summaryrefslogtreecommitdiffstats
path: root/source/slang/parser.cpp
diff options
context:
space:
mode:
authorTim Foley <tim.foley.is@gmail.com>2017-07-11 17:47:58 -0700
committerGitHub <noreply@github.com>2017-07-11 17:47:58 -0700
commit88f451cfafbf3a30033e750873c79f761b2bd1a5 (patch)
tree915b5124f0da1eed6b85f1616178e80a0dfbe3af /source/slang/parser.cpp
parentd8d8fefb9693e83bea215629f3a77f8a48d2f50f (diff)
parent24a44ffdd6e5648b3e0528ac3ccc871da853158c (diff)
Merge pull request #76 from tfoleyNV/gh-75
Make parser recovering more robust to avoid infinite loops
Diffstat (limited to 'source/slang/parser.cpp')
-rw-r--r--source/slang/parser.cpp51
1 files changed, 42 insertions, 9 deletions
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index 759fc0c20..de63793b1 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -303,17 +303,40 @@ namespace Slang
if (!parser->isRecovering)
return true;
- // Determine if we are looking for a closing token at all...
- bool lookingForClose = false;
+ // Determine if we are looking for common closing tokens,
+ // so that we can know whether or we are allowed to skip
+ // over them.
+
+ bool lookingForEOF = false;
+ bool lookingForRCurly = false;
+ bool lookingForRParen = false;
+ bool lookingForRSquare = false;
+
for (int ii = 0; ii < recoverBeforeCount; ++ii)
{
- if (IsClosingToken(recoverBefore[ii]))
- lookingForClose = true;
+ switch (recoverBefore[ii])
+ {
+ default:
+ break;
+
+ case TokenType::EndOfFile: lookingForEOF = true; break;
+ case TokenType::RBrace: lookingForRCurly = true; break;
+ case TokenType::RParent: lookingForRParen = true; break;
+ case TokenType::RBracket: lookingForRSquare = true; break;
+ }
}
for (int ii = 0; ii < recoverAfterCount; ++ii)
{
- if (IsClosingToken(recoverAfter[ii]))
- lookingForClose = true;
+ switch (recoverBefore[ii])
+ {
+ default:
+ break;
+
+ case TokenType::EndOfFile: lookingForEOF = true; break;
+ case TokenType::RBrace: lookingForRCurly = true; break;
+ case TokenType::RParent: lookingForRParen = true; break;
+ case TokenType::RBracket: lookingForRSquare = true; break;
+ }
}
TokenReader* tokenReader = &parser->tokenReader;
@@ -354,12 +377,23 @@ namespace Slang
// we are looking for a closing token
case TokenType::RParent:
case TokenType::RBracket:
- if (!lookingForClose)
+ if (lookingForRParen || lookingForRSquare || lookingForRCurly || lookingForEOF)
+ {
+ // We are looking for a closing token, so it is okay to skip these
+ }
+ else
return false;
break;
- // never skip a `}`, to avoid spurious errors
+ // Don't skip a `}`, to avoid spurious errors,
+ // with the exception of when we are looking for EOF
case TokenType::RBrace:
+ if (lookingForRCurly || lookingForEOF)
+ {
+ // We are looking for end-of-file, so it is okay to skip here
+ }
+ else
+
return false;
}
@@ -2342,7 +2376,6 @@ namespace Slang
while(!AdvanceIfMatch(parser, closingToken))
{
ParseDecl(parser, containerDecl);
- TryRecover(parser);
}
}