From cb3956f5bb8c3da8fb1b6401f2a2f055ea921794 Mon Sep 17 00:00:00 2001 From: Bhavya Kukkar <bhavyakukkar@gmail.com> Date: Thu, 3 Oct 2024 17:06:16 +0530 Subject: [PATCH] Recursive vs. One-shot Parser - new switch `parse_defs` on `struct Parser` that is read in `Parser.read_one` and disables parsing new syntax definitions if `false` - made `Parser` public so that it can be used directly without relying on `fn parse` - made field `Parser.reader` public so that it can be used as it was being used for reporting location of failure in `fn parse` - new Parser constructors `Parser::recursive` and `Parser::one_shot` to construct Parsers that do and do not have the ability to parse new syntax definitions, respectively - made fn `Parser.read_all` public so that it can be used directly without relying on `fn parse` --- crates/ast/src/lib.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/crates/ast/src/lib.rs b/crates/ast/src/lib.rs index 9f6415c..41f02fb 100644 --- a/crates/ast/src/lib.rs +++ b/crates/ast/src/lib.rs @@ -134,6 +134,7 @@ impl std::fmt::Display for Ast { pub fn parse(syntax: &Syntax, source: SourceFile) -> Result<Option<Ast>, Error> { let mut parser = Parser { reader: lex(source)?, + parse_defs: true, }; let result = parser.read_all(syntax); result.map_err(|msg| msg.at(parser.reader.peek().unwrap().span.clone())) @@ -164,8 +165,9 @@ pub fn read_syntax(source: SourceFile) -> Result<Syntax, Error> { result.map_err(|msg: ErrorMessage| msg.at(reader.peek().unwrap().span.clone())) } -struct Parser { - reader: peek2::Reader<SpannedToken>, +pub struct Parser { + pub reader: peek2::Reader<SpannedToken>, + parse_defs: bool, } fn read_syntax_def(reader: &mut peek2::Reader<SpannedToken>) -> Result<(SyntaxDefinition, Span)> { @@ -298,6 +300,24 @@ enum ReadOneResult { } impl Parser { + /// Construct a new parser that has the ability to parse new syntax-definitions when + /// [`Parser::read_all`] is called + pub fn recursive(reader: peek2::Reader<SpannedToken>) -> Self { + Parser { + reader, + parse_defs: true, + } + } + + /// Construct a new parser that does not have the ability to parse new syntax-definitions + /// when [`Parser::read_all`] is called + pub fn one_shot(reader: peek2::Reader<SpannedToken>) -> Self { + Parser { + reader, + parse_defs: false, + } + } + fn skip_comments(&mut self) { while self.reader.peek().unwrap().is_comment() { self.reader.next().unwrap(); @@ -325,7 +345,7 @@ impl Parser { self.skip_comments(); let peek = self.reader.peek().unwrap(); let raw = peek.raw(); - if raw == "syntax" { + if self.parse_defs && raw == "syntax" { tracing::trace!("see syntax keyword, parsing syntax definition..."); let (def, span) = read_syntax_def(&mut self.reader)?; return Ok(ReadOneResult::Progress(Ast::SyntaxDefinition { @@ -478,7 +498,7 @@ impl Parser { } } - fn read_all(&mut self, syntax: &Syntax) -> Result<Option<Ast>> { + pub fn read_all(&mut self, syntax: &Syntax) -> Result<Option<Ast>> { let result = self.read_expr(syntax, &HashSet::new(), None)?; let peek = self.reader.peek().unwrap(); if !peek.is_eof() {