diff options
| -rw-r--r-- | include/cps/Parser.h | 4 | ||||
| -rw-r--r-- | lib/Parser/Parser.cc | 1 | ||||
| -rw-r--r-- | lib/Parser/ParserControlFlow.cc | 13 | ||||
| -rw-r--r-- | lib/Parser/ParserExpression.cc | 2 | ||||
| -rw-r--r-- | tests/iii/missing-parenthesis/case.json | 2 |
5 files changed, 15 insertions, 7 deletions
diff --git a/include/cps/Parser.h b/include/cps/Parser.h index eff25a5..e710150 100644 --- a/include/cps/Parser.h +++ b/include/cps/Parser.h @@ -19,6 +19,7 @@ class Parser { Lexer &Lex; int CurTok = tok_eof; bool StartsLine = true; + int PrevTokLine = 0; // line of the token before CurTok bool ParsingCaseLabel = false; std::vector<unsigned> CaseBodyDepths; unsigned NumErrors = 0; @@ -33,6 +34,9 @@ class Parser { }; void getNextToken(); + // Line for a diagnostic about a token missing before CurTok: the previous + // line when CurTok starts a new one. + int missingLine() const { return StartsLine ? PrevTokLine : Lex.getLine(); } int GetTokPrecedence(); std::unique_ptr<ExprAST> ParseExpression(); diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc index d17856b..ad2e408 100644 --- a/lib/Parser/Parser.cc +++ b/lib/Parser/Parser.cc @@ -30,6 +30,7 @@ Parser::Parser(Lexer &L) : Lex(L) { void Parser::getNextToken() { int PreviousLine = CurTok == tok_eof ? 0 : Lex.getLine(); + PrevTokLine = PreviousLine; CurTok = Lex.gettok(); StartsLine = Lex.getLine() != PreviousLine; } diff --git a/lib/Parser/ParserControlFlow.cc b/lib/Parser/ParserControlFlow.cc index 7caf555..542ef0e 100644 --- a/lib/Parser/ParserControlFlow.cc +++ b/lib/Parser/ParserControlFlow.cc @@ -26,10 +26,13 @@ std::unique_ptr<StmtAST> Parser::ParseIfStmt() { if (!Cond) return nullptr; if (CurTok != tok_then) { - cps::sourceError(Lex.getLine(), "expected THEN"); - return nullptr; + cps::sourceError(missingLine(), "expected THEN"); + // A THEN missing at the end of a line is reported and then treated as + // present so the rest of the statement still parses. + if (!StartsLine) return nullptr; + } else { + getNextToken(); } - getNextToken(); std::vector<std::unique_ptr<StmtAST>> ThenStmts = ParseBlock({tok_else, tok_endif}); @@ -93,7 +96,7 @@ std::unique_ptr<StmtAST> Parser::ParseForStmt() { getNextToken(); if (CurTok != tok_assign) { - cps::sourceError(Lex.getLine(), "expected '<-' in FOR loop"); + cps::sourceError(missingLine(), "expected '<-' in FOR loop"); return nullptr; } getNextToken(); @@ -102,7 +105,7 @@ std::unique_ptr<StmtAST> Parser::ParseForStmt() { if (!Start) return nullptr; if (CurTok != tok_to) { - cps::sourceError(Lex.getLine(), "expected TO in FOR loop"); + cps::sourceError(missingLine(), "expected TO in FOR loop"); return nullptr; } getNextToken(); diff --git a/lib/Parser/ParserExpression.cc b/lib/Parser/ParserExpression.cc index 8c5e8ce..b75f704 100644 --- a/lib/Parser/ParserExpression.cc +++ b/lib/Parser/ParserExpression.cc @@ -211,7 +211,7 @@ std::unique_ptr<ExprAST> Parser::ParseParenExpr() { auto V = ParseExpression(); if (!V) return nullptr; if (CurTok != ')') { - cps::sourceError(Lex.getLine(), "expected ')'"); + cps::sourceError(missingLine(), "expected ')'"); return nullptr; } getNextToken(); diff --git a/tests/iii/missing-parenthesis/case.json b/tests/iii/missing-parenthesis/case.json index 3ccd080..5421130 100644 --- a/tests/iii/missing-parenthesis/case.json +++ b/tests/iii/missing-parenthesis/case.json @@ -2,7 +2,7 @@ "errors": [ { "reason": "expected\\ '\\)'", - "line": 3 + "line": 2 } ] } |
