Skip to content

Commit

Permalink
Recursive vs. One-shot Parser
Browse files Browse the repository at this point in the history
- 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`
  • Loading branch information
bhavyakukkar committed Oct 3, 2024
1 parent d94e816 commit cb3956f
Showing 1 changed file with 24 additions and 4 deletions.
28 changes: 24 additions & 4 deletions crates/ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
Expand Down Expand Up @@ -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)> {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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() {
Expand Down

0 comments on commit cb3956f

Please sign in to comment.