12131
|
1 |
pub type Spanned<Tok, Loc, Error> = Result<(Loc, Tok, Loc), Error>;
|
|
2 |
|
|
3 |
#[derive(Debug)]
|
|
4 |
pub enum Tok {
|
|
5 |
Linefeed,
|
|
6 |
}
|
|
7 |
|
|
8 |
#[derive(Debug)]
|
|
9 |
pub enum LexicalError {
|
|
10 |
// Not possible
|
|
11 |
}
|
|
12 |
|
|
13 |
use std::str::CharIndices;
|
|
14 |
|
|
15 |
pub struct Lexer<'input> {
|
|
16 |
chars: CharIndices<'input>,
|
|
17 |
}
|
|
18 |
|
|
19 |
impl<'input> Lexer<'input> {
|
|
20 |
pub fn new(input: &'input str) -> Self {
|
|
21 |
Lexer { chars: input.char_indices() }
|
|
22 |
}
|
|
23 |
}
|
|
24 |
|
|
25 |
impl<'input> Iterator for Lexer<'input> {
|
|
26 |
type Item = Spanned<Tok, usize, LexicalError>;
|
|
27 |
|
|
28 |
fn next(&mut self) -> Option<Self::Item> {
|
|
29 |
loop {
|
|
30 |
match self.chars.next() {
|
|
31 |
Some((i, '\n')) => return Some(Ok((i, Tok::Linefeed, i+1))),
|
|
32 |
|
|
33 |
None => return None, // End of file
|
|
34 |
_ => continue, // Comment; skip this character
|
|
35 |
}
|
|
36 |
}
|
|
37 |
}
|
|
38 |
}
|