Skip to content

Commit

Permalink
Improve error detection by parsing the last statement missing a semic…
Browse files Browse the repository at this point in the history
…olon rather than just emitting an error.
  • Loading branch information
Ivorforce committed Apr 26, 2024
1 parent f77f06c commit caf659e
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
13 changes: 8 additions & 5 deletions src/monoteny_grammar.lalrpop
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use lalrpop_util::ErrorRecovery;
use std::str::FromStr;
use itertools::Itertools;
use crate::error::RuntimeError;
use crate::util::position::*;
use crate::parser::ast::*;
use crate::parser::lexer::*;
Expand Down Expand Up @@ -84,11 +85,13 @@ InnerBlock: Block = {
// ... statements, maybe erroring in between
<statements: Box<Decorated<Positioned<<Statement>>>>*> => Block { <> },
// ... statements, then an erroring statement without a ; to end it
<statements: Box<Decorated<Positioned<<Statement>>>>*> <e: Positioned<!>> => {
errors.push(e.value.clone());
let expression: Expression = Expression::from(vec![Box::new(e.with_value(Term::Error(derive_error(&e))))]);
let statement = Box::new(Decorated::undecorated(e.with_value(Statement::Expression(Box::new(expression)))));
Block { statements: statements.into_iter().chain([statement]).collect_vec() }
<statements: Box<Decorated<Positioned<<Statement>>>>*> <last_statement: Box<Decorated<Positioned<<StatementNoSemicolon>>>>> => {
let err_position = last_statement.value.position.end;
let term = Term::Error(RuntimeError::error("Expected ;"));
let expression: Expression = Expression::from(vec![Box::new(positioned(term, err_position, err_position))]);
let error_statement = Box::new(Decorated::undecorated(positioned(Statement::Expression(Box::new(expression)), err_position, err_position)));

Block { statements: statements.into_iter().chain([last_statement, error_statement]).collect_vec() }
},
};

Expand Down
7 changes: 7 additions & 0 deletions src/parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,13 @@ impl<V: Display> Display for Decorated<V> {
}

impl<V> Decorated<V> {
pub fn with_value<N>(&self, n: N) -> Decorated<N> {
Decorated {
decorations: self.decorations.clone(),
value: n,
}
}

pub fn undecorated(t: V) -> Decorated<V> {
Decorated {
decorations: Array { arguments: vec![] },
Expand Down

0 comments on commit caf659e

Please sign in to comment.