[fine] Fix a problem with a stuck parser

Whoops
This commit is contained in:
John Doty 2024-01-21 09:01:12 -08:00
parent 5f0a0b3268
commit 11cb7199e9
2 changed files with 44 additions and 3 deletions

View file

@ -361,7 +361,7 @@ impl<'a> CParser<'a> {
fn advance(&mut self) {
assert!(!self.eof()); // Don't try to advance past EOF
self.fuel.set(256); // Consuming a token, rest stuck detector
self.fuel.set(256); // Consuming a token, reset stuck detector
self.events.push(ParseEvent::Advance {
token: self.current.clone(),
});
@ -381,11 +381,20 @@ impl<'a> CParser<'a> {
}
fn peek(&self) -> TokenKind {
assert!(self.fuel.get() > 0, "parser is stuck!");
if self.fuel.get() == 0 {
panic!(
"parser is stuck at '{}' ({})!",
self.current, self.current.start
);
}
self.fuel.set(self.fuel.get() - 1);
self.current.kind
}
// fn trace(&self, msg: &str) {
// eprintln!("{}: {}: {}", self.current.start, self.current, msg);
// }
fn at(&self, kind: TokenKind) -> bool {
self.peek() == kind
}
@ -511,6 +520,14 @@ fn file(p: &mut CParser) {
while !p.eof() {
match p.peek() {
TokenKind::Class => class(p),
TokenKind::RightBrace => {
// An error parsing mismatched braces can leave me at an
// un-balanced right brace, which unfortunately will not be
// consumed by the statement below. (Statement currently
// falls through to expression_statement, which checks for
// the right-brace that a block would end with.)
p.advance_with_error("unbalanced '}'");
}
_ => statement(p),
}
}
@ -542,7 +559,11 @@ fn class(p: &mut CParser) {
p.expect(TokenKind::Identifier, "expected a class name");
if p.eat(TokenKind::LeftBrace) {
while !p.at(TokenKind::RightBrace) && !p.eof() {
field_decl(p);
if p.at(TokenKind::Identifier) {
field_decl(p);
} else {
p.advance_with_error("expected a field declaration");
}
}
}
p.expect(TokenKind::RightBrace, "expected a class to end with a '}'");

View file

@ -0,0 +1,20 @@
fun foo() { }
} // <- Whoopsie!
// @concrete:
// | File
// | FunctionDecl
// | Fun:'"fun"'
// | Identifier:'"foo"'
// | ParamList
// | LeftParen:'"("'
// | RightParen:'")"'
// | Block
// | LeftBrace:'"{"'
// | RightBrace:'"}"'
// | Error
// | Error:'"Error at '}': unbalanced '}'"'
// | RightBrace:'"}"'
// |
//