diff options
| author | Yong He <yonghe@outlook.com> | 2022-06-13 16:50:35 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-13 16:50:35 -0700 |
| commit | a5422d4f8c43962147696e3b6b22d586133b9a4f (patch) | |
| tree | ac7541219ec1ea789c8a470471c8b37fbc4ac29e /source/slang/slang-parser.cpp | |
| parent | b0c7eb885dac6b609a46a961feb71d2f983a0d76 (diff) | |
Follow up on Language Server Improvement (#2275)
* Fix typo and improve parser recovery.
* Add search path configuration.
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-parser.cpp')
| -rw-r--r-- | source/slang/slang-parser.cpp | 34 |
1 files changed, 28 insertions, 6 deletions
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 <typename P, typename... Args> + 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<IncompleteExpr>(); // Either: |
