Scanner hack.

This commit is contained in:
Daniel Kirchner 2023-06-13 20:42:59 +02:00
parent d2cde10388
commit fb959b3066
7 changed files with 35 additions and 2 deletions

View File

@ -1020,15 +1020,28 @@ tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
while (isIdentifierPart(m_char) || (m_char == '.' && m_kind == ScannerKind::Yul)) while (isIdentifierPart(m_char) || (m_char == '.' && m_kind == ScannerKind::Yul))
addLiteralCharAndAdvance(); addLiteralCharAndAdvance();
literal.complete(); literal.complete();
auto const token = TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal); auto const token = TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal);
if (m_kind == ScannerKind::Yul) switch (m_kind)
{ {
case ScannerKind::Solidity:
// Turn experimental Solidity keywords that are not keywords in legacy Solidity into identifiers.
if (TokenTraits::isExperimentalSolidityOnlyKeyword(std::get<0>(token)))
return std::make_tuple(Token::Identifier, 0, 0);
break;
case ScannerKind::Yul:
// Turn Solidity identifier into a Yul keyword // Turn Solidity identifier into a Yul keyword
if (m_tokens[NextNext].literal == "leave") if (m_tokens[NextNext].literal == "leave")
return std::make_tuple(Token::Leave, 0, 0); return std::make_tuple(Token::Leave, 0, 0);
// Turn non-Yul keywords into identifiers. // Turn non-Yul keywords into identifiers.
if (!TokenTraits::isYulKeyword(std::get<0>(token))) if (!TokenTraits::isYulKeyword(std::get<0>(token)))
return std::make_tuple(Token::Identifier, 0, 0); return std::make_tuple(Token::Identifier, 0, 0);
break;
case ScannerKind::ExperimentalSolidity:
// Turn Solidity keywords that are not keywords in experimental solidity into identifiers.
if (!TokenTraits::isExperimentalSolidityKeyword(std::get<0>(token)))
return std::make_tuple(Token::Identifier, 0, 0);
break;
} }
return token; return token;
} }

View File

@ -69,7 +69,8 @@ class ParserRecorder;
enum class ScannerKind enum class ScannerKind
{ {
Solidity, Solidity,
Yul Yul,
ExperimentalSolidity
}; };
enum class ScannerError enum class ScannerError

View File

@ -322,6 +322,14 @@ namespace TokenTraits
tok == Token::Default || tok == Token::For || tok == Token::Break || tok == Token::Continue || tok == Token::Leave || tok == Token::Default || tok == Token::For || tok == Token::Break || tok == Token::Continue || tok == Token::Leave ||
tok == Token::TrueLiteral || tok == Token::FalseLiteral || tok == Token::HexStringLiteral || tok == Token::Hex; tok == Token::TrueLiteral || tok == Token::FalseLiteral || tok == Token::HexStringLiteral || tok == Token::Hex;
} }
constexpr bool isExperimentalSolidityKeyword(Token tok)
{
return tok == Token::Assembly || tok == Token::Contract || tok == Token::External || tok == Token::Fallback;
}
constexpr bool isExperimentalSolidityOnlyKeyword(Token)
{
return false;
}
bool isYulKeyword(std::string const& _literal); bool isYulKeyword(std::string const& _literal);

View File

@ -313,6 +313,7 @@ void CompilerStack::reset(bool _keepSettings)
m_stackState = Empty; m_stackState = Empty;
m_hasError = false; m_hasError = false;
m_sources.clear(); m_sources.clear();
m_maxAstId.reset();
m_smtlib2Responses.clear(); m_smtlib2Responses.clear();
m_unhandledSMTLib2Queries.clear(); m_unhandledSMTLib2Queries.clear();
if (!_keepSettings) if (!_keepSettings)
@ -417,6 +418,9 @@ bool CompilerStack::parse()
storeContractDefinitions(); storeContractDefinitions();
solAssert(!m_maxAstId.has_value());
m_maxAstId = parser.maxID();
return !m_hasError; return !m_hasError;
} }
@ -664,6 +668,7 @@ bool CompilerStack::analyzeLegacy(bool _noErrorsSoFar)
bool CompilerStack::analyzeExperimental() bool CompilerStack::analyzeExperimental()
{ {
bool noErrors = true; bool noErrors = true;
solAssert(m_maxAstId);
m_experimentalAnalysis = make_unique<experimental::Analysis>(m_errorReporter); m_experimentalAnalysis = make_unique<experimental::Analysis>(m_errorReporter);
for (Source const* source: m_sourceOrder) for (Source const* source: m_sourceOrder)
if (source->ast) if (source->ast)

View File

@ -517,6 +517,7 @@ private:
std::map<std::string, util::h160> m_libraries; std::map<std::string, util::h160> m_libraries;
ImportRemapper m_importRemapper; ImportRemapper m_importRemapper;
std::map<std::string const, Source> m_sources; std::map<std::string const, Source> m_sources;
std::optional<int64_t> m_maxAstId;
std::vector<std::string> m_unhandledSMTLib2Queries; std::vector<std::string> m_unhandledSMTLib2Queries;
std::map<util::h256, std::string> m_smtlib2Responses; std::map<util::h256, std::string> m_smtlib2Responses;
std::shared_ptr<GlobalContext> m_globalContext; std::shared_ptr<GlobalContext> m_globalContext;

View File

@ -100,6 +100,9 @@ ASTPointer<SourceUnit> Parser::parse(CharStream& _charStream)
while (m_scanner->currentToken() == Token::Pragma) while (m_scanner->currentToken() == Token::Pragma)
nodes.push_back(parsePragmaDirective(false)); nodes.push_back(parsePragmaDirective(false));
if (m_experimentalSolidityEnabledInCurrentSourceUnit)
m_scanner->setScannerMode(ScannerKind::ExperimentalSolidity);
while (m_scanner->currentToken() != Token::EOS) while (m_scanner->currentToken() != Token::EOS)
{ {
switch (m_scanner->currentToken()) switch (m_scanner->currentToken())

View File

@ -198,6 +198,8 @@ private:
/// Returns the next AST node ID /// Returns the next AST node ID
int64_t nextID() { return ++m_currentNodeID; } int64_t nextID() { return ++m_currentNodeID; }
/// Returns the maximal AST node ID assigned so far
int64_t maxID() const { return m_currentNodeID; }
std::pair<LookAheadInfo, IndexAccessedPath> tryParseIndexAccessedPath(); std::pair<LookAheadInfo, IndexAccessedPath> tryParseIndexAccessedPath();
/// Performs limited look-ahead to distinguish between variable declaration and expression statement. /// Performs limited look-ahead to distinguish between variable declaration and expression statement.