From a5422d4f8c43962147696e3b6b22d586133b9a4f Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 13 Jun 2022 16:50:35 -0700 Subject: Follow up on Language Server Improvement (#2275) * Fix typo and improve parser recovery. * Add search path configuration. Co-authored-by: Yong He --- source/slang/slang-parser.cpp | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'source/slang/slang-parser.cpp') diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 38317009d..aaf175812 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -100,6 +100,8 @@ namespace Slang TokenReader tokenReader; DiagnosticSink* sink; + SourceLoc lastErrorLoc; + int genericDepth = 0; // Have we seen any `import` declarations? If so, we need @@ -192,6 +194,18 @@ namespace Slang TypeExp ParseTypeExp(); Parser & operator = (const Parser &) = delete; + + // Helper to issue diagnose message that filters out errors for the same token. + template + void diagnose(P const& pos, DiagnosticInfo const& info, Args const&... args) + { + auto loc = getDiagnosticPos(pos); + if (loc != lastErrorLoc) + { + sink->diagnose(pos, info, args...); + lastErrorLoc = loc; + } + } }; // Forward Declarations @@ -248,7 +262,7 @@ namespace Slang // Don't emit "unexpected token" errors if we are in recovering mode if (!parser->isRecovering) { - parser->sink->diagnose(parser->tokenReader.peekLoc(), Diagnostics::unexpectedToken, + parser->diagnose(parser->tokenReader.peekLoc(), Diagnostics::unexpectedToken, parser->tokenReader.peekTokenType()); // Switch into recovery mode, to suppress additional errors @@ -279,10 +293,15 @@ namespace Slang // Don't emit "unexpected token" errors if we are in recovering mode if (!parser->isRecovering) { - parser->sink->diagnose(parser->tokenReader.peekLoc(), Diagnostics::unexpectedTokenExpectedTokenType, - parser->tokenReader.peekTokenType(), - expected); - + if (parser->lastErrorLoc != parser->tokenReader.peekLoc()) + { + parser->sink->diagnose( + parser->tokenReader.peekLoc(), + Diagnostics::unexpectedTokenExpectedTokenType, + parser->tokenReader.peekTokenType(), + expected); + parser->lastErrorLoc = parser->tokenReader.peekLoc(); + } // Switch into recovery mode, to suppress additional errors parser->isRecovering = true; } @@ -2515,6 +2534,9 @@ namespace Slang if (!AdvanceIf(parser, TokenType::Comma)) { parser->ReadToken(TokenType::Semicolon); + // We don't need to enter recovering mode if next token isn't semicolon. + // In this case we just continue parsing the token as the next decl. + parser->isRecovering = false; return declGroupBuilder.getResult(); } @@ -5231,7 +5253,7 @@ namespace Slang { default: // TODO: should this return an error expression instead of NULL? - parser->sink->diagnose(parser->tokenReader.peekLoc(), Diagnostics::syntaxError); + parser->diagnose(parser->tokenReader.peekLoc(), Diagnostics::syntaxError); return parser->astBuilder->create(); // Either: -- cgit v1.2.3