From 5efc90e89b5c27e79ab1d878a28aceb57faae675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Sat, 31 Dec 2022 16:40:59 +0100 Subject: [PATCH] Parser - Error recovery --- src/parser.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index efd4e6b..d387fdf 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -23,17 +23,11 @@ impl Parser { /// Parse the tokens into an AST and return it, or return nothing if a /// parser error occurs. pub fn parse(mut self, err_hdl: &mut ErrorHandler) -> Option { - match self.parse_program() { - Ok(expr) => Some(expr), - Err(e) => { - e.report(err_hdl); - None - } - } + self.parse_program(err_hdl) } /// Synchronize the parser after an error. - fn _synchronize(&mut self) { + fn synchronize(&mut self) { self.advance(); while !self.is_at_end() { if self.previous().token_type == TokenType::Semicolon @@ -61,13 +55,22 @@ impl Parser { /// ``` /// program := statement* /// ``` - fn parse_program(&mut self) -> ParserResult { + fn parse_program(&mut self, err_hdl: &mut ErrorHandler) -> Option { let mut stmts: Vec = Vec::new(); while !self.is_at_end() { - let stmt = self.parse_statement()?; - stmts.push(stmt); + match self.parse_statement() { + Ok(node) => stmts.push(node), + Err(err) => { + err.report(err_hdl); + self.synchronize() + } + } + } + if err_hdl.had_error().is_none() { + Some(ast::ProgramNode(stmts)) + } else { + None } - Ok(ast::ProgramNode(stmts)) } /// Parse the following rule: