summaryrefslogtreecommitdiff
path: root/src/lexer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lexer.rs')
-rw-r--r--src/lexer.rs105
1 files changed, 78 insertions, 27 deletions
diff --git a/src/lexer.rs b/src/lexer.rs
index 94825b2..04be350 100644
--- a/src/lexer.rs
+++ b/src/lexer.rs
@@ -2,13 +2,15 @@ use std::iter::Iterator;
2//use core::error::Error; 2//use core::error::Error;
3use std::str::CharIndices; 3use std::str::CharIndices;
4 4
5use crate::Position;
6
5#[derive(Debug,Copy,Clone)] 7#[derive(Debug,Copy,Clone)]
6pub enum ErrorType { 8pub enum ErrorType {
7 UnexpectedChar(char), 9 UnexpectedChar(char),
8} 10}
9 11
10#[derive(Debug,Copy,Clone)] 12#[derive(Debug,Copy,Clone)]
11pub enum Symbol<'a> { 13pub enum SymbolType<'a> {
12 StartFlat, 14 StartFlat,
13 StartPoint, 15 StartPoint,
14 EndFlat, 16 EndFlat,
@@ -20,10 +22,41 @@ pub enum Symbol<'a> {
20 Token(&'a str), 22 Token(&'a str),
21 Literal(&'a str), 23 Literal(&'a str),
22 Text(&'a str), 24 Text(&'a str),
23 Error{ line: u32, row: u32, what: ErrorType }, 25 Error{ what: ErrorType },
24 EOS, 26 EOS,
25} 27}
26 28
29#[derive(Debug,Copy,Clone)]
30pub struct Symbol<'a> {
31 symbol: SymbolType<'a>,
32 start: Position,
33 end: Position,
34}
35
36impl<'a> Symbol<'a> {
37 pub fn new( symbol: SymbolType<'a>, start: Position, end: Position ) -> Self {
38 Self {
39 symbol, start, end,
40 }
41 }
42
43 pub fn check_type<T: Fn( &SymbolType ) -> bool>(&self, f: T ) -> bool {
44 f( &self.symbol )
45 }
46
47 pub fn symbol(&self) -> &SymbolType<'a> {
48 &self.symbol
49 }
50
51 pub fn start(&self) -> &Position {
52 &self.start
53 }
54
55 pub fn end(&self) -> &Position {
56 &self.end
57 }
58}
59
27enum Mode { 60enum Mode {
28 Text, 61 Text,
29 InTag, 62 InTag,
@@ -35,8 +68,7 @@ pub struct Lexer<'a> {
35 cur: [Option<(usize, char)>;2], 68 cur: [Option<(usize, char)>;2],
36 icur: usize, 69 icur: usize,
37 mode: Mode, 70 mode: Mode,
38 line: u32, 71 pos: Position,
39 row: u32,
40} 72}
41 73
42fn is_valid_token_char( c: char ) -> bool { 74fn is_valid_token_char( c: char ) -> bool {
@@ -61,8 +93,7 @@ impl<'a> Lexer<'a> {
61 cur: [cur, cur2], 93 cur: [cur, cur2],
62 icur: 0, 94 icur: 0,
63 mode: Mode::Text, 95 mode: Mode::Text,
64 line: 0, 96 pos: Position::new(1,1),
65 row: 0,
66 } 97 }
67 } 98 }
68 99
@@ -71,6 +102,12 @@ impl<'a> Lexer<'a> {
71 self.icur = (self.icur+1)%2; 102 self.icur = (self.icur+1)%2;
72 //println!(" - cur: {:?}, peek: {:?}", self.cur(), self.peek() ); 103 //println!(" - cur: {:?}, peek: {:?}", self.cur(), self.peek() );
73 if let Some((_,chr)) = self.cur[self.icur] { 104 if let Some((_,chr)) = self.cur[self.icur] {
105 if chr == '\n' {
106 self.pos.column = 1;
107 self.pos.line += 1;
108 } else {
109 self.pos.column += 1;
110 }
74 Some(chr) 111 Some(chr)
75 } else { 112 } else {
76 None 113 None
@@ -110,11 +147,9 @@ impl<'a> Lexer<'a> {
110 } 147 }
111 148
112 fn error( &self, what: ErrorType ) -> Option<Symbol<'a>> { 149 fn error( &self, what: ErrorType ) -> Option<Symbol<'a>> {
113 Some(Symbol::Error { 150 Some(Symbol::new( SymbolType::Error {
114 line: self.line,
115 row: self.row,
116 what: what 151 what: what
117 }) 152 }, self.pos, self.pos ))
118 } 153 }
119 154
120 fn skip_ws( &mut self ) { 155 fn skip_ws( &mut self ) {
@@ -149,14 +184,16 @@ impl<'a> Lexer<'a> {
149 184
150 fn parse_text(&mut self) -> Option<Symbol<'a>> { 185 fn parse_text(&mut self) -> Option<Symbol<'a>> {
151 let start = self.cur_index(); 186 let start = self.cur_index();
187 let start_pos = self.pos.clone();
152 while self.next().is_some() && !self.is_start_tag() { } 188 while self.next().is_some() && !self.is_start_tag() { }
153 let end = self.cur_index(); 189 let end = self.cur_index();
190 let end_pos = self.pos.clone();
154 let s = &self.data[start..end]; 191 let s = &self.data[start..end];
155 //println!(" text: >>>{}<<<", s); 192 //println!(" text: >>>{}<<<", s);
156 if start == end { 193 if start == end {
157 None 194 None
158 } else { 195 } else {
159 Some(Symbol::Text(s)) 196 Some(Symbol::new( SymbolType::Text(s), start_pos, end_pos ))
160 } 197 }
161 } 198 }
162 199
@@ -168,25 +205,27 @@ impl<'a> Lexer<'a> {
168 } 205 }
169 Some('=') => { 206 Some('=') => {
170 self.next(); 207 self.next();
171 return Some(Symbol::Equals); 208 return Some(Symbol::new(SymbolType::Equals, self.pos, self.pos));
172 } 209 }
173 _ => {} 210 _ => {}
174 } 211 }
175 let start = self.cur_index(); 212 let start = self.cur_index();
213 let start_pos = self.pos.clone();
176 214
177 while self.next().is_some_and(|ch| is_valid_token_char(ch) ) && 215 while self.next().is_some_and(|ch| is_valid_token_char(ch) ) &&
178 !self.is_end_tag() {} 216 !self.is_end_tag() {}
179 let end = self.cur_index(); 217 let end = self.cur_index();
218 let end_pos = self.pos.clone();
180 let s = &self.data[start..end]; 219 let s = &self.data[start..end];
181 if start == end { 220 if start == end {
182 None 221 None
183 } else { 222 } else {
184 Some(match s { 223 Some(Symbol::new( match s {
185 "fragment" => Symbol::Fragment, 224 "fragment" => SymbolType::Fragment,
186 "section" => Symbol::Section, 225 "section" => SymbolType::Section,
187 "output" => Symbol::Output, 226 "output" => SymbolType::Output,
188 _ => Symbol::Token(s) 227 _ => SymbolType::Token(s)
189 }) 228 }, start_pos, end_pos ))
190 } 229 }
191 } 230 }
192 231
@@ -195,11 +234,13 @@ impl<'a> Lexer<'a> {
195 return self.error( ErrorType::UnexpectedChar(chr) ); 234 return self.error( ErrorType::UnexpectedChar(chr) );
196 } 235 }
197 let start = self.peek_index(); 236 let start = self.peek_index();
237 let start_pos = self.pos.clone();
198 while self.next().is_some_and(|chr| chr != '"') { } 238 while self.next().is_some_and(|chr| chr != '"') { }
199 let end = self.cur_index(); 239 let end = self.cur_index();
240 let end_pos = self.pos.clone();
200 self.next(); 241 self.next();
201 let s = &self.data[start..end]; 242 let s = &self.data[start..end];
202 Some(Symbol::Literal(s)) 243 Some(Symbol::new(SymbolType::Literal(s), start_pos, end_pos ))
203 } 244 }
204 245
205 fn is_start_tag(&mut self) -> bool { 246 fn is_start_tag(&mut self) -> bool {
@@ -212,21 +253,26 @@ impl<'a> Lexer<'a> {
212 } 253 }
213 254
214 fn parse_start_tag(&mut self) -> Option<Symbol<'a>> { 255 fn parse_start_tag(&mut self) -> Option<Symbol<'a>> {
256 let start_pos = self.pos.clone();
215 match self.cur() { 257 match self.cur() {
216 Some('[') => { 258 Some('[') => {
217 if let Some(p) = self.peek() && p == '|' { 259 if let Some(p) = self.peek() && p == '|' {
218 self.next(); self.next(); 260 self.next();
261 let end_pos = self.pos.clone();
262 self.next();
219 self.mode = Mode::InTag; 263 self.mode = Mode::InTag;
220 Some(Symbol::StartFlat) 264 Some(Symbol::new( SymbolType::StartFlat, start_pos, end_pos ) )
221 } else { 265 } else {
222 None 266 None
223 } 267 }
224 } 268 }
225 Some('<') => { 269 Some('<') => {
226 if let Some(p) = self.peek() && p == '|' { 270 if let Some(p) = self.peek() && p == '|' {
227 self.next(); self.next(); 271 self.next();
272 let end_pos = self.pos.clone();
273 self.next();
228 self.mode = Mode::InTag; 274 self.mode = Mode::InTag;
229 Some(Symbol::StartPoint) 275 Some(Symbol::new(SymbolType::StartPoint, start_pos, end_pos ) )
230 } else { 276 } else {
231 None 277 None
232 } 278 }
@@ -247,17 +293,22 @@ impl<'a> Lexer<'a> {
247 } 293 }
248 294
249 fn parse_end_tag(&mut self) -> Option<Symbol<'a>> { 295 fn parse_end_tag(&mut self) -> Option<Symbol<'a>> {
296 let start_pos = self.pos.clone();
250 if let Some(chr) = self.cur() && chr == '|' { 297 if let Some(chr) = self.cur() && chr == '|' {
251 match self.peek() { 298 match self.peek() {
252 Some(']') => { 299 Some(']') => {
253 self.next(); self.next(); 300 self.next();
301 let end_pos = self.pos.clone();
302 self.next();
254 self.mode = Mode::Text; 303 self.mode = Mode::Text;
255 Some(Symbol::EndFlat) 304 Some(Symbol::new( SymbolType::EndFlat, start_pos, end_pos))
256 } 305 }
257 Some('>') => { 306 Some('>') => {
258 self.next(); self.next(); 307 self.next();
308 let end_pos = self.pos.clone();
309 self.next();
259 self.mode = Mode::Text; 310 self.mode = Mode::Text;
260 Some(Symbol::EndPoint) 311 Some(Symbol::new( SymbolType::EndPoint, start_pos, end_pos))
261 } 312 }
262 _ => { 313 _ => {
263 None 314 None