Get the next token or a lexical error. Return None when the end of the source is encountered.
(&mut self)
| 475 | /// |
| 476 | /// Return None when the end of the source is encountered. |
| 477 | pub fn next(&mut self) -> Option<Result<LocatedToken<'a>, LocatedError>> { |
| 478 | loop { |
| 479 | let loc = self.loc(); |
| 480 | return match self.lookahead { |
| 481 | None => None, |
| 482 | Some(';') => Some(self.scan_comment()), |
| 483 | Some('(') => Some(self.scan_char(Token::LPar)), |
| 484 | Some(')') => Some(self.scan_char(Token::RPar)), |
| 485 | Some('{') => Some(self.scan_char(Token::LBrace)), |
| 486 | Some('}') => Some(self.scan_char(Token::RBrace)), |
| 487 | Some('[') => Some(self.scan_char(Token::LBracket)), |
| 488 | Some(']') => Some(self.scan_char(Token::RBracket)), |
| 489 | Some('<') => Some(self.scan_char(Token::LAngle)), |
| 490 | Some('>') => Some(self.scan_char(Token::RAngle)), |
| 491 | Some(',') => Some(self.scan_char(Token::Comma)), |
| 492 | Some('.') => Some(self.scan_char(Token::Dot)), |
| 493 | Some(':') => Some(self.scan_char(Token::Colon)), |
| 494 | Some('=') => Some(self.scan_char(Token::Equal)), |
| 495 | Some('!') => Some(self.scan_char(Token::Bang)), |
| 496 | Some('+') => Some(self.scan_number()), |
| 497 | Some('*') => Some(self.scan_char(Token::Multiply)), |
| 498 | Some('-') => { |
| 499 | if self.looking_at("->") { |
| 500 | Some(self.scan_chars(2, Token::Arrow)) |
| 501 | } else { |
| 502 | Some(self.scan_number()) |
| 503 | } |
| 504 | } |
| 505 | Some('0'..='9') => Some(self.scan_number()), |
| 506 | Some('a'..='z') | Some('A'..='Z') => { |
| 507 | if self.looking_at("NaN") || self.looking_at("Inf") { |
| 508 | Some(self.scan_number()) |
| 509 | } else { |
| 510 | Some(self.scan_word()) |
| 511 | } |
| 512 | } |
| 513 | Some('%') => Some(self.scan_name()), |
| 514 | Some('"') => Some(self.scan_string()), |
| 515 | Some('#') => Some(self.scan_hex_sequence()), |
| 516 | Some('@') => { |
| 517 | let pos = self.pos; |
| 518 | let loc = self.loc(); |
| 519 | self.next_ch(); |
| 520 | if self.looking_at_srcloc() { |
| 521 | Some(self.scan_srcloc(pos, loc)) |
| 522 | } else { |
| 523 | Some(token(Token::At, loc)) |
| 524 | } |
| 525 | } |
| 526 | // all ascii whitespace |
| 527 | Some(' ') | Some('\x09'..='\x0d') => { |
| 528 | self.next_ch(); |
| 529 | continue; |
| 530 | } |
| 531 | _ => { |
| 532 | // Skip invalid char, return error. |
| 533 | self.next_ch(); |
| 534 | Some(error(LexError::InvalidChar, loc)) |