lexer peekable
This commit is contained in:
parent
13850978c1
commit
3c5093f4db
2 changed files with 23 additions and 16 deletions
|
@ -66,7 +66,7 @@ pub struct Parser<'s> {
|
||||||
events: std::collections::VecDeque<Event>,
|
events: std::collections::VecDeque<Event>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
||||||
lexer: std::iter::Peekable<lex::Lexer<'s>>,
|
lexer: lex::Lexer<'s>,
|
||||||
|
|
||||||
verbatim: Option<(Container, usize)>,
|
verbatim: Option<(Container, usize)>,
|
||||||
last: bool,
|
last: bool,
|
||||||
|
@ -79,7 +79,7 @@ impl<'s> Parser<'s> {
|
||||||
events: std::collections::VecDeque::new(),
|
events: std::collections::VecDeque::new(),
|
||||||
span: Span::new(0, 0),
|
span: Span::new(0, 0),
|
||||||
|
|
||||||
lexer: lex::Lexer::new("").peekable(),
|
lexer: lex::Lexer::new(""),
|
||||||
|
|
||||||
verbatim: None,
|
verbatim: None,
|
||||||
last: false,
|
last: false,
|
||||||
|
@ -87,7 +87,7 @@ impl<'s> Parser<'s> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(&mut self, src: &'s str, last: bool) {
|
pub fn parse(&mut self, src: &'s str, last: bool) {
|
||||||
self.lexer = lex::Lexer::new(src).peekable();
|
self.lexer = lex::Lexer::new(src);
|
||||||
if last {
|
if last {
|
||||||
assert!(!self.last);
|
assert!(!self.last);
|
||||||
}
|
}
|
||||||
|
|
33
src/lex.rs
33
src/lex.rs
|
@ -99,26 +99,33 @@ impl<'s> Lexer<'s> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peek(&mut self) -> char {
|
pub fn peek(&mut self) -> Option<&Token> {
|
||||||
|
if self.next.is_none() {
|
||||||
|
self.next = self.token();
|
||||||
|
}
|
||||||
|
self.next.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn peek_char(&mut self) -> char {
|
||||||
self.chars.clone().next().unwrap_or(EOF)
|
self.chars.clone().next().unwrap_or(EOF)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eat(&mut self) -> Option<char> {
|
fn eat_char(&mut self) -> Option<char> {
|
||||||
let c = self.chars.next();
|
let c = self.chars.next();
|
||||||
self.len += c.map_or(0, char::len_utf8);
|
self.len += c.map_or(0, char::len_utf8);
|
||||||
c
|
c
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) {
|
fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) {
|
||||||
while predicate(self.peek()) {
|
while predicate(self.peek_char()) {
|
||||||
self.eat();
|
self.eat_char();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn token(&mut self) -> Option<Token> {
|
fn token(&mut self) -> Option<Token> {
|
||||||
self.len = 0;
|
self.len = 0;
|
||||||
|
|
||||||
let first = self.eat()?;
|
let first = self.eat_char()?;
|
||||||
|
|
||||||
let escape = self.escape;
|
let escape = self.escape;
|
||||||
|
|
||||||
|
@ -128,14 +135,14 @@ impl<'s> Lexer<'s> {
|
||||||
&& matches!(first, '\t' | ' ')
|
&& matches!(first, '\t' | ' ')
|
||||||
&& self.chars.clone().find(|c| !matches!(c, ' ' | '\t')) == Some('\n') =>
|
&& self.chars.clone().find(|c| !matches!(c, ' ' | '\t')) == Some('\n') =>
|
||||||
{
|
{
|
||||||
while self.eat() != Some('\n') {}
|
while self.eat_char() != Some('\n') {}
|
||||||
Hardbreak
|
Hardbreak
|
||||||
}
|
}
|
||||||
_ if escape && first == ' ' => Nbsp,
|
_ if escape && first == ' ' => Nbsp,
|
||||||
_ if escape => Text,
|
_ if escape => Text,
|
||||||
|
|
||||||
'\\' => {
|
'\\' => {
|
||||||
let next = self.peek();
|
let next = self.peek_char();
|
||||||
if next.is_whitespace() || next.is_ascii_punctuation() {
|
if next.is_whitespace() || next.is_ascii_punctuation() {
|
||||||
self.escape = true;
|
self.escape = true;
|
||||||
Escape
|
Escape
|
||||||
|
@ -155,7 +162,7 @@ impl<'s> Lexer<'s> {
|
||||||
'[' => Open(Bracket),
|
'[' => Open(Bracket),
|
||||||
']' => Close(Bracket),
|
']' => Close(Bracket),
|
||||||
'{' => {
|
'{' => {
|
||||||
let explicit = match self.peek() {
|
let explicit = match self.peek_char() {
|
||||||
'*' => Some(Open(BraceAsterisk)),
|
'*' => Some(Open(BraceAsterisk)),
|
||||||
'^' => Some(Open(BraceCaret)),
|
'^' => Some(Open(BraceCaret)),
|
||||||
'=' => Some(Open(BraceEqual)),
|
'=' => Some(Open(BraceEqual)),
|
||||||
|
@ -166,7 +173,7 @@ impl<'s> Lexer<'s> {
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
if let Some(exp) = explicit {
|
if let Some(exp) = explicit {
|
||||||
self.eat();
|
self.eat_char();
|
||||||
exp
|
exp
|
||||||
} else {
|
} else {
|
||||||
Open(Brace)
|
Open(Brace)
|
||||||
|
@ -180,8 +187,8 @@ impl<'s> Lexer<'s> {
|
||||||
'~' => self.maybe_eat_close_brace(Tilde, BraceTilde),
|
'~' => self.maybe_eat_close_brace(Tilde, BraceTilde),
|
||||||
'_' => self.maybe_eat_close_brace(Underscore, BraceUnderscore),
|
'_' => self.maybe_eat_close_brace(Underscore, BraceUnderscore),
|
||||||
'-' => {
|
'-' => {
|
||||||
if self.peek() == '}' {
|
if self.peek_char() == '}' {
|
||||||
self.eat();
|
self.eat_char();
|
||||||
Close(BraceHyphen)
|
Close(BraceHyphen)
|
||||||
} else {
|
} else {
|
||||||
self.eat_seq(Hyphen)
|
self.eat_seq(Hyphen)
|
||||||
|
@ -226,8 +233,8 @@ impl<'s> Lexer<'s> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_eat_close_brace(&mut self, s: Symbol, d: Delimiter) -> Kind {
|
fn maybe_eat_close_brace(&mut self, s: Symbol, d: Delimiter) -> Kind {
|
||||||
if self.peek() == '}' {
|
if self.peek_char() == '}' {
|
||||||
self.eat();
|
self.eat_char();
|
||||||
Close(d)
|
Close(d)
|
||||||
} else {
|
} else {
|
||||||
Sym(s)
|
Sym(s)
|
||||||
|
|
Loading…
Reference in a new issue