lex: fix buggy peek
This commit is contained in:
		
					parent
					
						
							
								6af5c5c884
							
						
					
				
			
			
				commit
				
					
						4a7967812e
					
				
			
		
					 2 changed files with 34 additions and 13 deletions
				
			
		| 
						 | 
					@ -67,7 +67,7 @@ pub struct Event {
 | 
				
			||||||
    pub span: Span,
 | 
					    pub span: Span,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Parser<I> {
 | 
					pub struct Parser<I: Iterator + Clone> {
 | 
				
			||||||
    /// Lexer, hosting upcoming source.
 | 
					    /// Lexer, hosting upcoming source.
 | 
				
			||||||
    lexer: lex::Lexer<I>,
 | 
					    lexer: lex::Lexer<I>,
 | 
				
			||||||
    /// Span of current event.
 | 
					    /// Span of current event.
 | 
				
			||||||
| 
						 | 
					@ -177,9 +177,10 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
 | 
				
			||||||
                            Some(lex::Kind::Open(Delimiter::BraceEqual))
 | 
					                            Some(lex::Kind::Open(Delimiter::BraceEqual))
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        let mut ahead = self.lexer.inner().clone();
 | 
					                        let mut ahead = self.lexer.chars();
 | 
				
			||||||
                        let mut end = false;
 | 
					                        let mut end = false;
 | 
				
			||||||
                        let len = (&mut ahead)
 | 
					                        let len = (&mut ahead)
 | 
				
			||||||
 | 
					                            .skip(2) // {=
 | 
				
			||||||
                            .take_while(|c| {
 | 
					                            .take_while(|c| {
 | 
				
			||||||
                                if *c == '{' {
 | 
					                                if *c == '{' {
 | 
				
			||||||
                                    return false;
 | 
					                                    return false;
 | 
				
			||||||
| 
						 | 
					@ -191,8 +192,16 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
 | 
				
			||||||
                            })
 | 
					                            })
 | 
				
			||||||
                            .count();
 | 
					                            .count();
 | 
				
			||||||
                        if len > 0 && end {
 | 
					                        if len > 0 && end {
 | 
				
			||||||
 | 
					                            let tok = self.eat();
 | 
				
			||||||
 | 
					                            debug_assert_eq!(
 | 
				
			||||||
 | 
					                                tok,
 | 
				
			||||||
 | 
					                                Some(lex::Token {
 | 
				
			||||||
 | 
					                                    kind: lex::Kind::Open(Delimiter::BraceEqual),
 | 
				
			||||||
 | 
					                                    len: 2,
 | 
				
			||||||
 | 
					                                })
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
                            self.lexer = lex::Lexer::new(ahead);
 | 
					                            self.lexer = lex::Lexer::new(ahead);
 | 
				
			||||||
                            let span_format = Span::by_len(self.span.end() + "{=".len(), len);
 | 
					                            let span_format = Span::by_len(self.span.end(), len);
 | 
				
			||||||
                            kind = RawFormat;
 | 
					                            kind = RawFormat;
 | 
				
			||||||
                            self.events[opener_event].kind = EventKind::Enter(kind);
 | 
					                            self.events[opener_event].kind = EventKind::Enter(kind);
 | 
				
			||||||
                            self.events[opener_event].span = span_format;
 | 
					                            self.events[opener_event].span = span_format;
 | 
				
			||||||
| 
						 | 
					@ -238,7 +247,7 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
 | 
				
			||||||
                .back()
 | 
					                .back()
 | 
				
			||||||
                .map_or(false, |e| e.kind == EventKind::Str)
 | 
					                .map_or(false, |e| e.kind == EventKind::Str)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            let mut ahead = self.lexer.inner().clone();
 | 
					            let mut ahead = self.lexer.chars();
 | 
				
			||||||
            let (mut attr_len, mut has_attr) = attr::valid(std::iter::once('{').chain(&mut ahead));
 | 
					            let (mut attr_len, mut has_attr) = attr::valid(std::iter::once('{').chain(&mut ahead));
 | 
				
			||||||
            attr_len -= 1; // rm {
 | 
					            attr_len -= 1; // rm {
 | 
				
			||||||
            if attr_len > 0 {
 | 
					            if attr_len > 0 {
 | 
				
			||||||
| 
						 | 
					@ -296,7 +305,7 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_autolink(&mut self, first: &lex::Token) -> Option<Event> {
 | 
					    fn parse_autolink(&mut self, first: &lex::Token) -> Option<Event> {
 | 
				
			||||||
        if first.kind == lex::Kind::Sym(Symbol::Lt) {
 | 
					        if first.kind == lex::Kind::Sym(Symbol::Lt) {
 | 
				
			||||||
            let mut ahead = self.lexer.inner().clone();
 | 
					            let mut ahead = self.lexer.chars();
 | 
				
			||||||
            let mut end = false;
 | 
					            let mut end = false;
 | 
				
			||||||
            let mut is_url = false;
 | 
					            let mut is_url = false;
 | 
				
			||||||
            let len = (&mut ahead)
 | 
					            let len = (&mut ahead)
 | 
				
			||||||
| 
						 | 
					@ -372,7 +381,7 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        let mut ahead = self.lexer.inner().clone();
 | 
					                        let mut ahead = self.lexer.chars();
 | 
				
			||||||
                        let (mut attr_len, mut has_attr) = attr::valid(&mut ahead);
 | 
					                        let (mut attr_len, mut has_attr) = attr::valid(&mut ahead);
 | 
				
			||||||
                        if attr_len > 0 {
 | 
					                        if attr_len > 0 {
 | 
				
			||||||
                            let span_closer = self.span;
 | 
					                            let span_closer = self.span;
 | 
				
			||||||
| 
						 | 
					@ -429,7 +438,7 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn post_span(&mut self, ty: SpanType, opener_event: usize) -> Option<Event> {
 | 
					    fn post_span(&mut self, ty: SpanType, opener_event: usize) -> Option<Event> {
 | 
				
			||||||
        let mut ahead = self.lexer.inner().clone();
 | 
					        let mut ahead = self.lexer.chars();
 | 
				
			||||||
        match ahead.next() {
 | 
					        match ahead.next() {
 | 
				
			||||||
            Some(opener @ ('[' | '(')) => {
 | 
					            Some(opener @ ('[' | '(')) => {
 | 
				
			||||||
                let img = ty == SpanType::Image;
 | 
					                let img = ty == SpanType::Image;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										24
									
								
								src/lex.rs
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								src/lex.rs
									
										
									
									
									
								
							| 
						 | 
					@ -82,8 +82,9 @@ impl Sequence {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone)]
 | 
					#[derive(Clone)]
 | 
				
			||||||
pub(crate) struct Lexer<I> {
 | 
					pub(crate) struct Lexer<I: Iterator + Clone> {
 | 
				
			||||||
    chars: I,
 | 
					    chars: I,
 | 
				
			||||||
 | 
					    chars_non_peeked: I,
 | 
				
			||||||
    /// Next character should be escaped.
 | 
					    /// Next character should be escaped.
 | 
				
			||||||
    escape: bool,
 | 
					    escape: bool,
 | 
				
			||||||
    /// Token to be peeked or next'ed.
 | 
					    /// Token to be peeked or next'ed.
 | 
				
			||||||
| 
						 | 
					@ -95,26 +96,30 @@ pub(crate) struct Lexer<I> {
 | 
				
			||||||
impl<I: Iterator<Item = char> + Clone> Lexer<I> {
 | 
					impl<I: Iterator<Item = char> + Clone> Lexer<I> {
 | 
				
			||||||
    pub fn new(chars: I) -> Lexer<I> {
 | 
					    pub fn new(chars: I) -> Lexer<I> {
 | 
				
			||||||
        Lexer {
 | 
					        Lexer {
 | 
				
			||||||
            chars,
 | 
					            chars: chars.clone(),
 | 
				
			||||||
 | 
					            chars_non_peeked: chars,
 | 
				
			||||||
            escape: false,
 | 
					            escape: false,
 | 
				
			||||||
            next: None,
 | 
					            next: None,
 | 
				
			||||||
            len: 0,
 | 
					            len: 0,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// NOTE: Peeked [`Kind::Text`] tokens are only one char long, they may be longer when
 | 
				
			||||||
 | 
					    /// consumed.
 | 
				
			||||||
    pub fn peek(&mut self) -> Option<&Token> {
 | 
					    pub fn peek(&mut self) -> Option<&Token> {
 | 
				
			||||||
        if self.next.is_none() {
 | 
					        if self.next.is_none() {
 | 
				
			||||||
            self.next = self.next_token();
 | 
					            self.next = self.token();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        self.next.as_ref()
 | 
					        self.next.as_ref()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn inner(&self) -> &I {
 | 
					    pub fn chars(&self) -> I {
 | 
				
			||||||
        &self.chars
 | 
					        self.chars_non_peeked.clone()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn next_token(&mut self) -> Option<Token> {
 | 
					    fn next_token(&mut self) -> Option<Token> {
 | 
				
			||||||
        let mut current = self.token();
 | 
					        let mut current = self.token();
 | 
				
			||||||
 | 
					        self.chars_non_peeked = self.chars.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // concatenate text tokens
 | 
					        // concatenate text tokens
 | 
				
			||||||
        if let Some(Token { kind: Text, len }) = &mut current {
 | 
					        if let Some(Token { kind: Text, len }) = &mut current {
 | 
				
			||||||
| 
						 | 
					@ -145,6 +150,7 @@ impl<I: Iterator<Item = char> + Clone> Lexer<I> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn token(&mut self) -> Option<Token> {
 | 
					    fn token(&mut self) -> Option<Token> {
 | 
				
			||||||
 | 
					        self.chars_non_peeked = self.chars.clone();
 | 
				
			||||||
        self.len = 0;
 | 
					        self.len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let first = self.eat_char()?;
 | 
					        let first = self.eat_char()?;
 | 
				
			||||||
| 
						 | 
					@ -271,7 +277,13 @@ impl<I: Iterator<Item = char> + Clone> Iterator for Lexer<I> {
 | 
				
			||||||
    type Item = Token;
 | 
					    type Item = Token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					    fn next(&mut self) -> Option<Self::Item> {
 | 
				
			||||||
        self.next.take().or_else(|| self.next_token())
 | 
					        self.next
 | 
				
			||||||
 | 
					            .take()
 | 
				
			||||||
 | 
					            .map(|x| {
 | 
				
			||||||
 | 
					                self.chars_non_peeked = self.chars.clone();
 | 
				
			||||||
 | 
					                x
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .or_else(|| self.next_token())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue