diff options
Diffstat (limited to 'src/lexer.rs')
| -rw-r--r-- | src/lexer.rs | 105 |
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; |
| 3 | use std::str::CharIndices; | 3 | use std::str::CharIndices; |
| 4 | 4 | ||
| 5 | use crate::Position; | ||
| 6 | |||
| 5 | #[derive(Debug,Copy,Clone)] | 7 | #[derive(Debug,Copy,Clone)] |
| 6 | pub enum ErrorType { | 8 | pub enum ErrorType { |
| 7 | UnexpectedChar(char), | 9 | UnexpectedChar(char), |
| 8 | } | 10 | } |
| 9 | 11 | ||
| 10 | #[derive(Debug,Copy,Clone)] | 12 | #[derive(Debug,Copy,Clone)] |
| 11 | pub enum Symbol<'a> { | 13 | pub 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)] | ||
| 30 | pub struct Symbol<'a> { | ||
| 31 | symbol: SymbolType<'a>, | ||
| 32 | start: Position, | ||
| 33 | end: Position, | ||
| 34 | } | ||
| 35 | |||
| 36 | impl<'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 | |||
| 27 | enum Mode { | 60 | enum 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 | ||
| 42 | fn is_valid_token_char( c: char ) -> bool { | 74 | fn 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 |
