summaryrefslogtreecommitdiffstats
path: root/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-05-18 15:24:05 -0400
committerGitHub <noreply@github.com>2020-05-18 15:24:05 -0400
commit1de14312917a0427a7a0858615b65261da60f748 (patch)
tree53a3bbe74b620c7a37ccc8f3776423ca1ed5b7e9 /tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
parent4397d90fe14940e421a4e87df51b22d78d5efe9e (diff)
Use 'balance' for extracting array suffix in C++ extractor (#1346)
* Add support for parsing array types to C++ extractor. * C++ extractor looks for 'balanced tokens'. Use for extracting array suffixes.
Diffstat (limited to 'tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp')
-rw-r--r--tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp112
1 files changed, 81 insertions, 31 deletions
diff --git a/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp b/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
index e18601076..814e7ac0e 100644
--- a/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
+++ b/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
@@ -332,7 +332,8 @@ protected:
SlangResult _maybeParseTemplateArgs(Index& ioTemplateDepth);
SlangResult _maybeParseTemplateArg(Index& ioTemplateDepth);
- SlangResult _maybeParseArrayTypeSuffix(UnownedStringSlice& outSuffix);
+ /// Parse balanced - if a sink is set will report to that sink
+ SlangResult _parseBalanced(DiagnosticSink* sink);
SlangResult _calcDerivedTypesRec(Node* node);
static String _calcMacroOrigin(const String& filePath, const Options& options);
@@ -950,7 +951,7 @@ SlangResult CPPExtractor::consumeToClosingBrace(const Token* inOpenBraceToken)
case TokenType::EndOfFile:
{
m_sink->diagnose(m_reader.peekLoc(), CPPDiagnostics::didntFindMatchingBrace);
- m_sink->diagnose(openToken, CPPDiagnostics::seeOpenBrace);
+ m_sink->diagnose(openToken, CPPDiagnostics::seeOpen);
return SLANG_FAIL;
}
case TokenType::LBrace:
@@ -1336,46 +1337,91 @@ SlangResult CPPExtractor::_maybeParseType(UnownedStringSlice& outType)
return SLANG_OK;
}
-SlangResult CPPExtractor::_maybeParseArrayTypeSuffix(UnownedStringSlice& outSuffix)
+static bool _isBalancedOpen(TokenType tokenType)
{
- auto startCursor = m_reader.getCursor();
+ return tokenType == TokenType::LBrace ||
+ tokenType == TokenType::LParent ||
+ tokenType == TokenType::LBracket;
+}
+
+static bool _isBalancedClose(TokenType tokenType)
+{
+ return tokenType == TokenType::RBrace ||
+ tokenType == TokenType::RParent ||
+ tokenType == TokenType::RBracket;
+}
+
+static TokenType _getBalancedClose(TokenType tokenType)
+{
+ SLANG_ASSERT(_isBalancedOpen(tokenType));
+ switch (tokenType)
+ {
+ case TokenType::LBrace: return TokenType::RBrace;
+ case TokenType::LParent: return TokenType::RParent;
+ case TokenType::LBracket: return TokenType::RBracket;
+ default: return TokenType::Unknown;
+ }
+}
+
+SlangResult CPPExtractor::_parseBalanced(DiagnosticSink* sink)
+{
+ const TokenType openTokenType = m_reader.peekTokenType();
+ if (!_isBalancedOpen(openTokenType))
+ {
+ return SLANG_FAIL;
+ }
+
+ // Save the start token
+ const Token startToken = m_reader.advanceToken();
+ // Get the token type that would close the open
+ const TokenType closeTokenType = _getBalancedClose(openTokenType);
while (true)
{
- SLANG_RETURN_ON_FAIL(expect(TokenType::LBracket));
+ const TokenType tokenType = m_reader.peekTokenType();
- while (true)
+ // If we hit the closing token, we are done
+ if (tokenType == closeTokenType)
{
- TokenType tokenType = m_reader.peekTokenType();
- if (tokenType == TokenType::RBracket)
- {
- break;
- }
+ m_reader.advanceToken();
+ return SLANG_OK;
+ }
- if (tokenType == TokenType::EndOfFile ||
- tokenType == TokenType::LBrace ||
- tokenType == TokenType::RBrace ||
- tokenType == TokenType::LBracket)
+ // If we hit a balanced open, recurse
+ if (_isBalancedOpen(tokenType))
+ {
+ SLANG_RETURN_ON_FAIL(_parseBalanced(sink));
+ continue;
+ }
+
+ // If we hit a close token that doesn't match, then the balancing has gone wrong
+ if (_isBalancedClose(tokenType))
+ {
+ // Only diagnose if required
+ if (sink)
{
- return SLANG_FAIL;
+ sink->diagnose(m_reader.peekLoc(), CPPDiagnostics::unexpectedUnbalancedToken);
+ sink->diagnose(startToken, CPPDiagnostics::seeOpen);
}
-
- // Okay onto next
- m_reader.advanceToken();
+ return SLANG_FAIL;
}
- SLANG_RETURN_ON_FAIL(expect(TokenType::RBracket));
-
- if (m_reader.peekTokenType() == TokenType::RBracket)
+ // If we hit the end of the file and have not hit the closing token, then
+ // somethings gone wrong
+ if (tokenType == TokenType::EndOfFile)
{
- continue;
+ if (sink)
+ {
+ sink->diagnose(m_reader.peekLoc(), CPPDiagnostics::unexpectedEndOfFile);
+ sink->diagnose(startToken, CPPDiagnostics::seeOpen);
+ }
+
+ return SLANG_FAIL;
}
- break;
+ // Skip the token
+ m_reader.advanceToken();
}
-
- outSuffix = _concatTokens(startCursor);
- return SLANG_OK;
}
SlangResult CPPExtractor::_maybeParseField()
@@ -1404,14 +1450,18 @@ SlangResult CPPExtractor::_maybeParseField()
if (m_reader.peekTokenType() == TokenType::LBracket)
{
- UnownedStringSlice arraySuffix;
+ auto startCursor = m_reader.getCursor();
- if (SLANG_FAILED(_maybeParseArrayTypeSuffix(arraySuffix)))
+ // If it's not balanced we just assume it's not correct - and ignore
+ if (SLANG_FAILED(_parseBalanced(nullptr)))
{
_consumeToSync();
- return m_sink->errorCount ? SLANG_FAIL : SLANG_OK;
+ return SLANG_OK;
}
- // The overall type is the typename concatted with the arraySuffix
+
+ UnownedStringSlice arraySuffix = _concatTokens(startCursor);
+
+ // The overall type is the typename concated with the arraySuffix
StringBuilder buf;
buf << typeName << arraySuffix;