-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlexer.rs
110 lines (98 loc) · 3.01 KB
/
lexer.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
mod token;
use std::io::{self, Read};
pub use token::Token;
use super::parse_error::ParseError;
pub struct Lexer<'a, T: Read> {
pub token: Token,
pub position: u32,
pub last_id: String,
reader: &'a mut T,
cur: u8,
}
impl<'a, T: Read> Lexer<'a, T> {
pub fn new(reader: &'a mut T) -> Lexer<'a, T> {
Lexer {
token: Token::Eof,
position: 1,
last_id: String::new(),
reader,
cur: b' ',
}
}
pub fn next(&mut self) -> Result<Token, ParseError> {
while self.cur.is_ascii_whitespace() {
self.read().map_err(ParseError::failed_read)?;
}
let mut is_id = false;
let mut cur_id = String::new();
while self.cur.is_ascii_alphanumeric() {
is_id = true;
cur_id.push(self.cur as char);
self.read().map_err(ParseError::failed_read)?;
}
if is_id {
for t in [Token::Var, Token::Array, Token::Of].iter().cloned() {
if cur_id == t.to_string() {
self.token = t;
return Ok(self.token.clone());
}
}
self.token = match cur_id.parse::<u32>() {
Ok(_) => Token::Number,
Err(_) => Token::Id
};
self.last_id = cur_id;
return Ok(self.token.clone());
}
if self.cur == b'.' {
cur_id.push('.');
self.read().map_err(ParseError::failed_read)?;
if self.cur == b'.' {
cur_id.push('.');
self.read().map_err(ParseError::failed_read)?;
self.token = Token::DoubleDot;
return Ok(Token::DoubleDot);
}
}
if self.cur == 0 {
self.token = Token::Eof;
Ok(Token::Eof)
} else {
let result = match self.cur as char {
',' => Ok(Token::Comma),
';' => Ok(Token::Semicolon),
':' => Ok(Token::Colon),
'[' => Ok(Token::OpenSBracket),
']' => Ok(Token::CloseSBracket),
other => Err(ParseError::unknown_terminal(other, self.position))
};
match result {
Ok(token) => match self.read() {
Ok(_) => {
self.token = token;
Ok(self.token.clone())
},
Err(e) => Err(ParseError::failed_read(e))
},
Err(e) => Err(e)
}
}
}
fn read(&mut self) -> Result<u8, io::Error> {
let mut buffer: [u8; 1] = [0; 1];
match self.reader.read(&mut buffer) {
Ok(0) => {
self.cur = 0;
Ok(self.cur)
}
Ok(_) => {
self.position += 1;
self.cur = buffer[0];
Ok(self.cur)
},
Err(e) => Err(e)
}
}
}
#[cfg(test)]
mod tests;