From c1fffa892d528d232fb5f7323217991700e20a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 24 Feb 2023 19:49:42 +0100 Subject: [PATCH] Parser: Extract literal parsing into a separate function --- libsolidity/parsing/Parser.cpp | 94 +++++++++++-------- libsolidity/parsing/Parser.h | 1 + .../denominations/finney_invalid.sol | 8 +- .../denominations/szabo_invalid.sol | 8 +- 4 files changed, 63 insertions(+), 48 deletions(-) diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index f1850fe1c..257b8bea9 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -36,10 +36,12 @@ #include #include #include + #include -#include +#include #include #include +#include using namespace std; using namespace solidity::langutil; @@ -1989,6 +1991,56 @@ ASTPointer Parser::parseLeftHandSideExpression( } } +ASTPointer Parser::parseLiteral() +{ + RecursionGuard recursionGuard(*this); + ASTNodeFactory nodeFactory(*this); + Token initialToken = m_scanner->currentToken(); + ASTPointer value = make_shared(m_scanner->currentLiteral()); + + switch (initialToken) + { + case Token::TrueLiteral: + case Token::FalseLiteral: + case Token::Number: + { + nodeFactory.markEndPosition(); + advance(); + break; + } + case Token::StringLiteral: + case Token::UnicodeStringLiteral: + case Token::HexStringLiteral: + { + while (m_scanner->peekNextToken() == initialToken) + { + advance(); + *value += m_scanner->currentLiteral(); + } + nodeFactory.markEndPosition(); + advance(); + if (m_scanner->currentToken() == Token::Illegal) + fatalParserError(5428_error, to_string(m_scanner->currentError())); + break; + } + default: + solAssert(false); + } + + if (initialToken == Token::Number && ( + TokenTraits::isEtherSubdenomination(m_scanner->currentToken()) || + TokenTraits::isTimeSubdenomination(m_scanner->currentToken()) + )) + { + nodeFactory.markEndPosition(); + Literal::SubDenomination subDenomination = static_cast(m_scanner->currentToken()); + advance(); + return nodeFactory.createNode(initialToken, std::move(value), subDenomination); + } + + return nodeFactory.createNode(initialToken, std::move(value), Literal::SubDenomination::None); +} + ASTPointer Parser::parsePrimaryExpression() { RecursionGuard recursionGuard(*this); @@ -2000,50 +2052,12 @@ ASTPointer Parser::parsePrimaryExpression() { case Token::TrueLiteral: case Token::FalseLiteral: - nodeFactory.markEndPosition(); - expression = nodeFactory.createNode(token, getLiteralAndAdvance()); - break; case Token::Number: - if (TokenTraits::isEtherSubdenomination(m_scanner->peekNextToken())) - { - ASTPointer literal = getLiteralAndAdvance(); - nodeFactory.markEndPosition(); - Literal::SubDenomination subdenomination = static_cast(m_scanner->currentToken()); - advance(); - expression = nodeFactory.createNode(token, literal, subdenomination); - } - else if (TokenTraits::isTimeSubdenomination(m_scanner->peekNextToken())) - { - ASTPointer literal = getLiteralAndAdvance(); - nodeFactory.markEndPosition(); - Literal::SubDenomination subdenomination = static_cast(m_scanner->currentToken()); - advance(); - expression = nodeFactory.createNode(token, literal, subdenomination); - } - else - { - nodeFactory.markEndPosition(); - expression = nodeFactory.createNode(token, getLiteralAndAdvance()); - } - break; case Token::StringLiteral: case Token::UnicodeStringLiteral: case Token::HexStringLiteral: - { - string literal = m_scanner->currentLiteral(); - Token firstToken = m_scanner->currentToken(); - while (m_scanner->peekNextToken() == firstToken) - { - advance(); - literal += m_scanner->currentLiteral(); - } - nodeFactory.markEndPosition(); - advance(); - if (m_scanner->currentToken() == Token::Illegal) - fatalParserError(5428_error, to_string(m_scanner->currentError())); - expression = nodeFactory.createNode(token, make_shared(literal)); + expression = parseLiteral(); break; - } case Token::Identifier: nodeFactory.markEndPosition(); expression = nodeFactory.createNode(getLiteralAndAdvance()); diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 7a9b41318..c7d6146be 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -159,6 +159,7 @@ private: ASTPointer parseLeftHandSideExpression( ASTPointer const& _partiallyParsedExpression = ASTPointer() ); + ASTPointer parseLiteral(); ASTPointer parsePrimaryExpression(); std::vector> parseFunctionCallListArguments(); diff --git a/test/libsolidity/syntaxTests/denominations/finney_invalid.sol b/test/libsolidity/syntaxTests/denominations/finney_invalid.sol index b7bae7fa7..0974cde13 100644 --- a/test/libsolidity/syntaxTests/denominations/finney_invalid.sol +++ b/test/libsolidity/syntaxTests/denominations/finney_invalid.sol @@ -1,7 +1,7 @@ contract C { - function f() { - uint x = 1 finney; - } + function f() public { + uint x = 1 finney; + } } // ---- -// ParserError 2314: (45-51): Expected ';' but got identifier +// ParserError 2314: (58-64): Expected ';' but got identifier diff --git a/test/libsolidity/syntaxTests/denominations/szabo_invalid.sol b/test/libsolidity/syntaxTests/denominations/szabo_invalid.sol index d206830d5..d0e3eb3ff 100644 --- a/test/libsolidity/syntaxTests/denominations/szabo_invalid.sol +++ b/test/libsolidity/syntaxTests/denominations/szabo_invalid.sol @@ -1,7 +1,7 @@ contract C { - function f() { - uint x = 1 szabo; - } + function f() public { + uint x = 1 szabo; + } } // ---- -// ParserError 2314: (45-50): Expected ';' but got identifier +// ParserError 2314: (58-63): Expected ';' but got identifier