Parser: Extract literal parsing into a separate function

This commit is contained in:
Kamil Śliwak 2023-02-24 19:49:42 +01:00
parent 46457cfc25
commit c1fffa892d
4 changed files with 63 additions and 48 deletions

View File

@ -36,10 +36,12 @@
#include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <cctype> #include <cctype>
#include <vector> #include <memory>
#include <regex> #include <regex>
#include <tuple> #include <tuple>
#include <vector>
using namespace std; using namespace std;
using namespace solidity::langutil; using namespace solidity::langutil;
@ -1989,6 +1991,56 @@ ASTPointer<Expression> Parser::parseLeftHandSideExpression(
} }
} }
ASTPointer<Expression> Parser::parseLiteral()
{
RecursionGuard recursionGuard(*this);
ASTNodeFactory nodeFactory(*this);
Token initialToken = m_scanner->currentToken();
ASTPointer<ASTString> value = make_shared<string>(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<Literal::SubDenomination>(m_scanner->currentToken());
advance();
return nodeFactory.createNode<Literal>(initialToken, std::move(value), subDenomination);
}
return nodeFactory.createNode<Literal>(initialToken, std::move(value), Literal::SubDenomination::None);
}
ASTPointer<Expression> Parser::parsePrimaryExpression() ASTPointer<Expression> Parser::parsePrimaryExpression()
{ {
RecursionGuard recursionGuard(*this); RecursionGuard recursionGuard(*this);
@ -2000,50 +2052,12 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
{ {
case Token::TrueLiteral: case Token::TrueLiteral:
case Token::FalseLiteral: case Token::FalseLiteral:
nodeFactory.markEndPosition();
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
break;
case Token::Number: case Token::Number:
if (TokenTraits::isEtherSubdenomination(m_scanner->peekNextToken()))
{
ASTPointer<ASTString> literal = getLiteralAndAdvance();
nodeFactory.markEndPosition();
Literal::SubDenomination subdenomination = static_cast<Literal::SubDenomination>(m_scanner->currentToken());
advance();
expression = nodeFactory.createNode<Literal>(token, literal, subdenomination);
}
else if (TokenTraits::isTimeSubdenomination(m_scanner->peekNextToken()))
{
ASTPointer<ASTString> literal = getLiteralAndAdvance();
nodeFactory.markEndPosition();
Literal::SubDenomination subdenomination = static_cast<Literal::SubDenomination>(m_scanner->currentToken());
advance();
expression = nodeFactory.createNode<Literal>(token, literal, subdenomination);
}
else
{
nodeFactory.markEndPosition();
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
}
break;
case Token::StringLiteral: case Token::StringLiteral:
case Token::UnicodeStringLiteral: case Token::UnicodeStringLiteral:
case Token::HexStringLiteral: case Token::HexStringLiteral:
{ expression = parseLiteral();
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<Literal>(token, make_shared<ASTString>(literal));
break; break;
}
case Token::Identifier: case Token::Identifier:
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance()); expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance());

View File

@ -159,6 +159,7 @@ private:
ASTPointer<Expression> parseLeftHandSideExpression( ASTPointer<Expression> parseLeftHandSideExpression(
ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>() ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
); );
ASTPointer<Expression> parseLiteral();
ASTPointer<Expression> parsePrimaryExpression(); ASTPointer<Expression> parsePrimaryExpression();
std::vector<ASTPointer<Expression>> parseFunctionCallListArguments(); std::vector<ASTPointer<Expression>> parseFunctionCallListArguments();

View File

@ -1,7 +1,7 @@
contract C { contract C {
function f() { function f() public {
uint x = 1 finney; uint x = 1 finney;
} }
} }
// ---- // ----
// ParserError 2314: (45-51): Expected ';' but got identifier // ParserError 2314: (58-64): Expected ';' but got identifier

View File

@ -1,7 +1,7 @@
contract C { contract C {
function f() { function f() public {
uint x = 1 szabo; uint x = 1 szabo;
} }
} }
// ---- // ----
// ParserError 2314: (45-50): Expected ';' but got identifier // ParserError 2314: (58-63): Expected ';' but got identifier