summaryrefslogtreecommitdiff
path: root/source/slang/slang-parser.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-06-13 16:50:35 -0700
committerGitHub <noreply@github.com>2022-06-13 16:50:35 -0700
commita5422d4f8c43962147696e3b6b22d586133b9a4f (patch)
treeac7541219ec1ea789c8a470471c8b37fbc4ac29e /source/slang/slang-parser.cpp
parentb0c7eb885dac6b609a46a961feb71d2f983a0d76 (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.cpp34
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: