diff options
author | Laurent Le Brun <laurentlb@google.com> | 2015-04-02 10:07:28 +0000 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@google.com> | 2015-04-02 12:49:49 +0000 |
commit | 9060e16088490c038e64188652922f7f5407f652 (patch) | |
tree | e9cf87e8697d5a6ed7be61ffe330cfbfddba36e9 /src/main/java/com/google/devtools | |
parent | f6579daf14986c2727b82b843324fc4679cb0d0f (diff) |
Parser: Make error recovery more conservative.
Reduce the number of error message after a parse error.
Recover only when we have confidence we are in good state.
--
MOS_MIGRATED_REVID=90147322
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/syntax/Parser.java | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java index 297aa13922..7694ab70d3 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java @@ -250,8 +250,10 @@ class Parser { } } - // Consumes the current token. If it is not of the specified (expected) - // kind, reports a syntax error. + /** + * Consumes the current token. If it is not of the specified (expected) + * kind, reports a syntax error. + */ private boolean expect(TokenKind kind) { boolean expected = token.kind == kind; if (!expected) { @@ -262,6 +264,15 @@ class Parser { } /** + * Same as expect, but stop the recovery mode if the token was expected. + */ + private void expectAndRecover(TokenKind kind) { + if (expect(kind)) { + recoveryMode = false; + } + } + + /** * Consume tokens past the first token that has a kind that is in the set of * teminatingTokens. * @param terminatingTokens @@ -979,7 +990,12 @@ class Parser { List<Statement> list = new ArrayList<>(); while (token.kind != TokenKind.EOF) { if (token.kind == TokenKind.NEWLINE) { - expect(TokenKind.NEWLINE); + expectAndRecover(TokenKind.NEWLINE); + } else if (recoveryMode) { + // If there was a parse error, we want to recover here + // before starting a new top-level statement. + syncTo(STATEMENT_TERMINATOR_SET); + recoveryMode = false; } else { parseTopLevelStatement(list); } @@ -1067,10 +1083,7 @@ class Parser { } parseSmallStatementOrPass(list); } - expect(TokenKind.NEWLINE); - // This is a safe place to recover: There is a new line at top-level - // and the parser is at the end of a statement. - recoveryMode = false; + expectAndRecover(TokenKind.NEWLINE); } // small_stmt ::= assign_stmt @@ -1259,7 +1272,7 @@ class Parser { while (token.kind != TokenKind.OUTDENT && token.kind != TokenKind.EOF) { parseStatement(list, false); } - expect(TokenKind.OUTDENT); + expectAndRecover(TokenKind.OUTDENT); } else { parseSimpleStatement(list); } |