inline: add ControlFlow enum
needed to indicate that more input is needed this is needed only for multiline attributes that require backtracking
This commit is contained in:
		
					parent
					
						
							
								7133de94bb
							
						
					
				
			
			
				commit
				
					
						3d42820001
					
				
			
		
					 1 changed files with 44 additions and 30 deletions
				
			
		| 
						 | 
					@ -9,6 +9,7 @@ use lex::Symbol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Atom::*;
 | 
					use Atom::*;
 | 
				
			||||||
use Container::*;
 | 
					use Container::*;
 | 
				
			||||||
 | 
					use ControlFlow::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, PartialEq, Eq)]
 | 
					#[derive(Debug, Clone, PartialEq, Eq)]
 | 
				
			||||||
pub enum Atom {
 | 
					pub enum Atom {
 | 
				
			||||||
| 
						 | 
					@ -224,6 +225,15 @@ pub struct Parser<'s> {
 | 
				
			||||||
    pub(crate) store_cowstrs: Vec<CowStr<'s>>,
 | 
					    pub(crate) store_cowstrs: Vec<CowStr<'s>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ControlFlow {
 | 
				
			||||||
 | 
					    /// At least one event has been emitted, continue parsing the line.
 | 
				
			||||||
 | 
					    Continue,
 | 
				
			||||||
 | 
					    /// Next line is needed to emit an event.
 | 
				
			||||||
 | 
					    Next,
 | 
				
			||||||
 | 
					    /// Parsing of the line is completed.
 | 
				
			||||||
 | 
					    Done,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'s> Parser<'s> {
 | 
					impl<'s> Parser<'s> {
 | 
				
			||||||
    pub fn new(src: &'s str) -> Self {
 | 
					    pub fn new(src: &'s str) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
| 
						 | 
					@ -248,18 +258,18 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
        self.store_cowstrs.clear();
 | 
					        self.store_cowstrs.clear();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn push_sp(&mut self, kind: EventKind, span: Span) -> Option<()> {
 | 
					    fn push_sp(&mut self, kind: EventKind, span: Span) -> Option<ControlFlow> {
 | 
				
			||||||
        self.events.push_back(Event { kind, span });
 | 
					        self.events.push_back(Event { kind, span });
 | 
				
			||||||
        Some(())
 | 
					        Some(Continue)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn push(&mut self, kind: EventKind) -> Option<()> {
 | 
					    fn push(&mut self, kind: EventKind) -> Option<ControlFlow> {
 | 
				
			||||||
        self.push_sp(kind, self.input.span)
 | 
					        self.push_sp(kind, self.input.span)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_event(&mut self) -> Option<()> {
 | 
					    fn parse_event(&mut self) -> ControlFlow {
 | 
				
			||||||
        self.input.reset_span();
 | 
					        self.input.reset_span();
 | 
				
			||||||
        self.input.eat().map(|first| {
 | 
					        if let Some(first) = self.input.eat() {
 | 
				
			||||||
            self.parse_verbatim(&first)
 | 
					            self.parse_verbatim(&first)
 | 
				
			||||||
                .or_else(|| self.parse_attributes(&first))
 | 
					                .or_else(|| self.parse_attributes(&first))
 | 
				
			||||||
                .or_else(|| self.parse_autolink(&first))
 | 
					                .or_else(|| self.parse_autolink(&first))
 | 
				
			||||||
| 
						 | 
					@ -267,13 +277,15 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
                .or_else(|| self.parse_footnote_reference(&first))
 | 
					                .or_else(|| self.parse_footnote_reference(&first))
 | 
				
			||||||
                .or_else(|| self.parse_container(&first))
 | 
					                .or_else(|| self.parse_container(&first))
 | 
				
			||||||
                .or_else(|| self.parse_atom(&first))
 | 
					                .or_else(|| self.parse_atom(&first))
 | 
				
			||||||
                .unwrap_or_else(|| {
 | 
					                .unwrap_or_else(|| self.push(EventKind::Str).unwrap())
 | 
				
			||||||
                    self.push(EventKind::Str);
 | 
					        } else if self.input.last() {
 | 
				
			||||||
                })
 | 
					            Done
 | 
				
			||||||
        })
 | 
					        } else {
 | 
				
			||||||
 | 
					            Next
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_verbatim(&mut self, first: &lex::Token) -> Option<()> {
 | 
					    fn parse_verbatim(&mut self, first: &lex::Token) -> Option<ControlFlow> {
 | 
				
			||||||
        if let Some(VerbatimState {
 | 
					        if let Some(VerbatimState {
 | 
				
			||||||
            event_opener,
 | 
					            event_opener,
 | 
				
			||||||
            len_opener,
 | 
					            len_opener,
 | 
				
			||||||
| 
						 | 
					@ -335,7 +347,7 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
                        })
 | 
					                        })
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        return Some(()); // skip whitespace
 | 
					                        return Some(Continue); // skip whitespace
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    *non_whitespace_encountered = true;
 | 
					                    *non_whitespace_encountered = true;
 | 
				
			||||||
| 
						 | 
					@ -343,7 +355,7 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                self.push(EventKind::Str);
 | 
					                self.push(EventKind::Str);
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            Some(())
 | 
					            Some(Continue)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            let (ty, len_opener) = match first.kind {
 | 
					            let (ty, len_opener) = match first.kind {
 | 
				
			||||||
                lex::Kind::DollarBacktick(l) if first.len - l as usize == 1 => {
 | 
					                lex::Kind::DollarBacktick(l) if first.len - l as usize == 1 => {
 | 
				
			||||||
| 
						 | 
					@ -368,7 +380,7 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_attributes(&mut self, first: &lex::Token) -> Option<()> {
 | 
					    fn parse_attributes(&mut self, first: &lex::Token) -> Option<ControlFlow> {
 | 
				
			||||||
        if first.kind == lex::Kind::Open(Delimiter::Brace) {
 | 
					        if first.kind == lex::Kind::Open(Delimiter::Brace) {
 | 
				
			||||||
            let mut ahead = self.input.lexer.ahead().chars();
 | 
					            let mut ahead = self.input.lexer.ahead().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));
 | 
				
			||||||
| 
						 | 
					@ -394,14 +406,14 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    self.push_sp(EventKind::Placeholder, self.input.span.empty_before());
 | 
					                    self.push_sp(EventKind::Placeholder, self.input.span.empty_before());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return Some(());
 | 
					                return Some(Continue);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        None
 | 
					        None
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_autolink(&mut self, first: &lex::Token) -> Option<()> {
 | 
					    fn parse_autolink(&mut self, first: &lex::Token) -> Option<ControlFlow> {
 | 
				
			||||||
        if first.kind == lex::Kind::Sym(Symbol::Lt) {
 | 
					        if first.kind == lex::Kind::Sym(Symbol::Lt) {
 | 
				
			||||||
            let mut ahead = self.input.lexer.ahead().chars();
 | 
					            let mut ahead = self.input.lexer.ahead().chars();
 | 
				
			||||||
            let mut end = false;
 | 
					            let mut end = false;
 | 
				
			||||||
| 
						 | 
					@ -433,7 +445,7 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
        None
 | 
					        None
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_symbol(&mut self, first: &lex::Token) -> Option<()> {
 | 
					    fn parse_symbol(&mut self, first: &lex::Token) -> Option<ControlFlow> {
 | 
				
			||||||
        if first.kind == lex::Kind::Sym(Symbol::Colon) {
 | 
					        if first.kind == lex::Kind::Sym(Symbol::Colon) {
 | 
				
			||||||
            let mut ahead = self.input.lexer.ahead().chars();
 | 
					            let mut ahead = self.input.lexer.ahead().chars();
 | 
				
			||||||
            let mut end = false;
 | 
					            let mut end = false;
 | 
				
			||||||
| 
						 | 
					@ -454,13 +466,13 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
                self.input.span = self.input.span.after(len);
 | 
					                self.input.span = self.input.span.after(len);
 | 
				
			||||||
                self.push(EventKind::Atom(Symbol));
 | 
					                self.push(EventKind::Atom(Symbol));
 | 
				
			||||||
                self.input.span = self.input.span.after(1);
 | 
					                self.input.span = self.input.span.after(1);
 | 
				
			||||||
                return Some(());
 | 
					                return Some(Continue);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        None
 | 
					        None
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_footnote_reference(&mut self, first: &lex::Token) -> Option<()> {
 | 
					    fn parse_footnote_reference(&mut self, first: &lex::Token) -> Option<ControlFlow> {
 | 
				
			||||||
        if first.kind == lex::Kind::Open(Delimiter::Bracket)
 | 
					        if first.kind == lex::Kind::Open(Delimiter::Bracket)
 | 
				
			||||||
            && matches!(
 | 
					            && matches!(
 | 
				
			||||||
                self.input.peek(),
 | 
					                self.input.peek(),
 | 
				
			||||||
| 
						 | 
					@ -497,13 +509,13 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
                self.input.span = self.input.span.after(len);
 | 
					                self.input.span = self.input.span.after(len);
 | 
				
			||||||
                self.push(EventKind::Atom(FootnoteReference));
 | 
					                self.push(EventKind::Atom(FootnoteReference));
 | 
				
			||||||
                self.input.span = self.input.span.after(1);
 | 
					                self.input.span = self.input.span.after(1);
 | 
				
			||||||
                return Some(());
 | 
					                return Some(Continue);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        None
 | 
					        None
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_container(&mut self, first: &lex::Token) -> Option<()> {
 | 
					    fn parse_container(&mut self, first: &lex::Token) -> Option<ControlFlow> {
 | 
				
			||||||
        self.openers
 | 
					        self.openers
 | 
				
			||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .rposition(|(o, _)| o.closed_by(first.kind))
 | 
					            .rposition(|(o, _)| o.closed_by(first.kind))
 | 
				
			||||||
| 
						 | 
					@ -642,7 +654,7 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
                            ),
 | 
					                            ),
 | 
				
			||||||
                        };
 | 
					                        };
 | 
				
			||||||
                        self.events.drain(e_opener..);
 | 
					                        self.events.drain(e_opener..);
 | 
				
			||||||
                        Some(())
 | 
					                        Some(Continue)
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -713,7 +725,7 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_atom(&mut self, first: &lex::Token) -> Option<()> {
 | 
					    fn parse_atom(&mut self, first: &lex::Token) -> Option<ControlFlow> {
 | 
				
			||||||
        let atom = match first.kind {
 | 
					        let atom = match first.kind {
 | 
				
			||||||
            lex::Kind::Newline => Softbreak,
 | 
					            lex::Kind::Newline => Softbreak,
 | 
				
			||||||
            lex::Kind::Hardbreak => Hardbreak,
 | 
					            lex::Kind::Hardbreak => Hardbreak,
 | 
				
			||||||
| 
						 | 
					@ -747,7 +759,7 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
                        self.push_sp(EventKind::Atom(atom), self.input.span.with_len(l));
 | 
					                        self.push_sp(EventKind::Atom(atom), self.input.span.with_len(l));
 | 
				
			||||||
                        self.input.span = self.input.span.skip(l);
 | 
					                        self.input.span = self.input.span.skip(l);
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                return Some(());
 | 
					                return Some(Continue);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            lex::Kind::Open(Delimiter::BraceQuote1) => Quote {
 | 
					            lex::Kind::Open(Delimiter::BraceQuote1) => Quote {
 | 
				
			||||||
                ty: QuoteType::Single,
 | 
					                ty: QuoteType::Single,
 | 
				
			||||||
| 
						 | 
					@ -981,13 +993,15 @@ impl<'s> Iterator for Parser<'s> {
 | 
				
			||||||
                .back()
 | 
					                .back()
 | 
				
			||||||
                .map_or(false, |ev| matches!(ev.kind, EventKind::Str))
 | 
					                .map_or(false, |ev| matches!(ev.kind, EventKind::Str))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if self.parse_event().is_none() {
 | 
					            match self.parse_event() {
 | 
				
			||||||
                if self.input.last() {
 | 
					                Continue => {}
 | 
				
			||||||
                    break;
 | 
					                Done => break,
 | 
				
			||||||
                } else if let Some(l) = self.input.ahead.pop_front() {
 | 
					                Next => {
 | 
				
			||||||
                    self.input.set_current_line(l);
 | 
					                    if let Some(l) = self.input.ahead.pop_front() {
 | 
				
			||||||
                } else {
 | 
					                        self.input.set_current_line(l);
 | 
				
			||||||
                    return None;
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        return None;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue