Skip to content

Commit

Permalink
Make the trailing errors skip all characters until the end of the lin…
Browse files Browse the repository at this point in the history
…es to avoid throwing duplicated errors for the same character
  • Loading branch information
irevoire authored and sharkdp committed Nov 23, 2023
1 parent ba9e97b commit 24e6346
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions numbat/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,7 @@ impl<'a> Parser<'a> {
Ok(statement) => statements.push(statement),
Err(e) => {
errors.push(e);
// skip all the tokens until we encounter a newline.
while !matches!(self.peek().kind, TokenKind::Newline | TokenKind::Eof) {
self.advance()
}
self.recover_from_error();
}
}

Expand All @@ -273,12 +270,14 @@ impl<'a> Parser<'a> {
),
span: self.peek().span,
});
self.recover_from_error();
}
_ => {
errors.push(ParseError {
kind: ParseErrorKind::TrailingCharacters(self.peek().lexeme.clone()),
span: self.peek().span,
});
self.recover_from_error();
}
}
}
Expand All @@ -290,6 +289,14 @@ impl<'a> Parser<'a> {
}
}

/// Must be called after encountering an error.
fn recover_from_error(&mut self) {
// Skip all the tokens until we encounter a newline or EoF.
while !matches!(self.peek().kind, TokenKind::Newline | TokenKind::Eof) {
self.advance()
}
}

fn accepts_prefix(&mut self) -> Result<Option<AcceptsPrefix>> {
if self.match_exact(TokenKind::Colon).is_some() {
if self.match_exact(TokenKind::Long).is_some() {
Expand Down Expand Up @@ -2368,6 +2375,7 @@ mod tests {
ParseErrorKind::UnterminatedStringInterpolation,
);
}

#[test]
fn accumulate_errors() {
// error on the last character of a line
Expand Down Expand Up @@ -2416,5 +2424,14 @@ mod tests {
Expected one of: number, identifier, parenthesized expression - ParseError { kind: ExpectedPrimary, span: Span { start: SourceCodePositition { byte: 36, line: 3, position: 17 }, end: SourceCodePositition { byte: 40, line: 3, position: 21 }, code_source_id: 0 } }
Expected one of: number, identifier, parenthesized expression - ParseError { kind: ExpectedPrimary, span: Span { start: SourceCodePositition { byte: 63, line: 4, position: 17 }, end: SourceCodePositition { byte: 67, line: 4, position: 21 }, code_source_id: 0 } }
"###);

// #260
assert_snapshot!(snap_parse(
"x = 3"), @r###"
Successfully parsed:
Expression(Identifier(Span { start: SourceCodePositition { byte: 0, line: 1, position: 1 }, end: SourceCodePositition { byte: 1, line: 1, position: 2 }, code_source_id: 0 }, "x"))
Errors encountered:
Trailing '=' sign. Use `let x = …` if you intended to define a new constant. - ParseError { kind: TrailingEqualSign("x"), span: Span { start: SourceCodePositition { byte: 2, line: 1, position: 3 }, end: SourceCodePositition { byte: 3, line: 1, position: 4 }, code_source_id: 0 } }
"###);
}
}

0 comments on commit 24e6346

Please sign in to comment.