Merge pull request #4059 from ethereum/parser-simplify

Simplify the parser expectations
This commit is contained in:
chriseth 2018-05-04 12:50:12 +02:00 committed by GitHub
commit 81d61ca086
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 18 additions and 48 deletions

View File

@ -1194,7 +1194,8 @@ ASTPointer<Expression> Parser::parseExpression(
ASTPointer<Expression> expression = parseBinaryExpression(4, _lookAheadIndexAccessStructure); ASTPointer<Expression> expression = parseBinaryExpression(4, _lookAheadIndexAccessStructure);
if (Token::isAssignmentOp(m_scanner->currentToken())) if (Token::isAssignmentOp(m_scanner->currentToken()))
{ {
Token::Value assignmentOperator = expectAssignmentOperator(); Token::Value assignmentOperator = m_scanner->currentToken();
m_scanner->next();
ASTPointer<Expression> rightHandSide = parseExpression(); ASTPointer<Expression> rightHandSide = parseExpression();
ASTNodeFactory nodeFactory(*this, expression); ASTNodeFactory nodeFactory(*this, expression);
nodeFactory.setEndPositionFromNode(rightHandSide); nodeFactory.setEndPositionFromNode(rightHandSide);
@ -1601,40 +1602,10 @@ ASTPointer<ParameterList> Parser::createEmptyParameterList()
return nodeFactory.createNode<ParameterList>(vector<ASTPointer<VariableDeclaration>>()); return nodeFactory.createNode<ParameterList>(vector<ASTPointer<VariableDeclaration>>());
} }
string Parser::currentTokenName()
{
Token::Value token = m_scanner->currentToken();
if (Token::isElementaryTypeName(token)) //for the sake of accuracy in reporting
{
ElementaryTypeNameToken elemTypeName = m_scanner->currentElementaryTypeNameToken();
return elemTypeName.toString();
}
else
return Token::name(token);
}
Token::Value Parser::expectAssignmentOperator()
{
Token::Value op = m_scanner->currentToken();
if (!Token::isAssignmentOp(op))
fatalParserError(
string("Expected assignment operator, got '") +
currentTokenName() +
string("'")
);
m_scanner->next();
return op;
}
ASTPointer<ASTString> Parser::expectIdentifierToken() ASTPointer<ASTString> Parser::expectIdentifierToken()
{ {
Token::Value id = m_scanner->currentToken(); // do not advance on success
if (id != Token::Identifier) expectToken(Token::Identifier, false);
fatalParserError(
string("Expected identifier, got '") +
currentTokenName() +
string("'")
);
return getLiteralAndAdvance(); return getLiteralAndAdvance();
} }

View File

@ -165,8 +165,6 @@ private:
/// @returns an expression parsed in look-ahead fashion from something like "a.b[8][2**70]". /// @returns an expression parsed in look-ahead fashion from something like "a.b[8][2**70]".
ASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices); ASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
std::string currentTokenName();
Token::Value expectAssignmentOperator();
ASTPointer<ASTString> expectIdentifierToken(); ASTPointer<ASTString> expectIdentifierToken();
ASTPointer<ASTString> getLiteralAndAdvance(); ASTPointer<ASTString> getLiteralAndAdvance();
///@} ///@}

View File

@ -63,7 +63,7 @@ Token::Value ParserBase::advance()
return m_scanner->next(); return m_scanner->next();
} }
void ParserBase::expectToken(Token::Value _value) void ParserBase::expectToken(Token::Value _value, bool _advance)
{ {
Token::Value tok = m_scanner->currentToken(); Token::Value tok = m_scanner->currentToken();
if (tok != _value) if (tok != _value)
@ -98,7 +98,8 @@ void ParserBase::expectToken(Token::Value _value)
string("'") string("'")
); );
} }
m_scanner->next(); if (_advance)
m_scanner->next();
} }
void ParserBase::increaseRecursionDepth() void ParserBase::increaseRecursionDepth()

View File

@ -63,7 +63,7 @@ protected:
///@{ ///@{
///@name Helper functions ///@name Helper functions
/// If current token value is not _value, throw exception otherwise advance token. /// If current token value is not _value, throw exception otherwise advance token.
void expectToken(Token::Value _value); void expectToken(Token::Value _value, bool _advance = true);
Token::Value currentToken() const; Token::Value currentToken() const;
Token::Value peekNextToken() const; Token::Value peekNextToken() const;
std::string currentLiteral() const; std::string currentLiteral() const;

View File

@ -992,7 +992,7 @@ BOOST_AUTO_TEST_CASE(keyword_is_reserved)
for (const auto& keyword: keywords) for (const auto& keyword: keywords)
{ {
auto text = std::string("contract ") + keyword + " {}"; auto text = std::string("contract ") + keyword + " {}";
CHECK_PARSE_ERROR(text.c_str(), "Expected identifier"); CHECK_PARSE_ERROR(text.c_str(), "Expected token Identifier got reserved keyword");
} }
} }

View File

@ -326,8 +326,8 @@ BOOST_AUTO_TEST_CASE(compilation_error)
{ {
BOOST_CHECK_EQUAL( BOOST_CHECK_EQUAL(
dev::jsonCompactPrint(error), dev::jsonCompactPrint(error),
"{\"component\":\"general\",\"formattedMessage\":\"fileA:1:23: ParserError: Expected identifier, got 'RBrace'\\n" "{\"component\":\"general\",\"formattedMessage\":\"fileA:1:23: ParserError: Expected token Identifier got 'RBrace'\\n"
"contract A { function }\\n ^\\n\",\"message\":\"Expected identifier, got 'RBrace'\"," "contract A { function }\\n ^\\n\",\"message\":\"Expected token Identifier got 'RBrace'\","
"\"severity\":\"error\",\"sourceLocation\":{\"end\":22,\"file\":\"fileA\",\"start\":22},\"type\":\"ParserError\"}" "\"severity\":\"error\",\"sourceLocation\":{\"end\":22,\"file\":\"fileA\",\"start\":22},\"type\":\"ParserError\"}"
); );
} }

View File

@ -2,4 +2,4 @@ contract Foo {
uint constant = 4; uint constant = 4;
} }
// ---- // ----
// ParserError: (30-30): Expected identifier, got 'Assign' // ParserError: (30-30): Expected token Identifier got 'Assign'

View File

@ -2,4 +2,4 @@ contract c {
uint external x; uint external x;
} }
// ---- // ----
// ParserError: (19-19): Expected identifier, got 'External' // ParserError: (19-19): Expected token Identifier got 'External'

View File

@ -2,4 +2,4 @@ contract Foo {
uint[] memory x; uint[] memory x;
} }
// ---- // ----
// ParserError: (23-23): Expected identifier, got 'Memory' // ParserError: (23-23): Expected token Identifier got 'Memory'

View File

@ -3,4 +3,4 @@ contract test {
function b() returns (uint r) { r = a({: 1, : 2, : 3}); } function b() returns (uint r) { r = a({: 1, : 2, : 3}); }
} }
// ---- // ----
// ParserError: (143-143): Expected identifier, got 'Colon' // ParserError: (143-143): Expected token Identifier got 'Colon'

View File

@ -2,4 +2,4 @@ contract test {
uint256 ; uint256 ;
} }
// ---- // ----
// ParserError: (28-28): Expected identifier, got 'Semicolon' // ParserError: (28-28): Expected token Identifier got 'Semicolon'

View File

@ -2,4 +2,4 @@ contract test {
uint payable x; uint payable x;
} }
// ---- // ----
// ParserError: (22-22): Expected identifier, got 'Payable' // ParserError: (22-22): Expected token Identifier got 'Payable'

View File

@ -2,4 +2,4 @@ contract Foo {
function f() { var[] a; } function f() { var[] a; }
} }
// ---- // ----
// ParserError: (34-34): Expected identifier, got 'LBrack' // ParserError: (34-34): Expected token Identifier got 'LBrack'