[fine] Working on parser resilience
This commit is contained in:
parent
11cb7199e9
commit
741a729f8d
5 changed files with 129 additions and 1 deletions
|
|
@ -395,6 +395,15 @@ impl<'a> CParser<'a> {
|
|||
// eprintln!("{}: {}: {}", self.current.start, self.current, msg);
|
||||
// }
|
||||
|
||||
fn at_any(&self, kinds: &[TokenKind]) -> bool {
|
||||
for kind in kinds {
|
||||
if self.at(*kind) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
fn at(&self, kind: TokenKind) -> bool {
|
||||
self.peek() == kind
|
||||
}
|
||||
|
|
@ -586,6 +595,8 @@ fn field_decl(p: &mut CParser) {
|
|||
p.end(m, TreeKind::FieldDecl);
|
||||
}
|
||||
|
||||
const PARAM_LIST_RECOVERY: &[TokenKind] = &[TokenKind::Arrow, TokenKind::LeftBrace, TokenKind::Fun];
|
||||
|
||||
fn param_list(p: &mut CParser) {
|
||||
let m = p.start();
|
||||
|
||||
|
|
@ -594,7 +605,10 @@ fn param_list(p: &mut CParser) {
|
|||
if p.at(TokenKind::Identifier) {
|
||||
parameter(p);
|
||||
} else {
|
||||
break;
|
||||
if p.at_any(PARAM_LIST_RECOVERY) {
|
||||
break;
|
||||
}
|
||||
p.advance_with_error("expected parameter");
|
||||
}
|
||||
}
|
||||
p.expect(TokenKind::RightParen, "expect ')' to end a parameter list");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue