Merge pull request #4917 from ethereum/parserCleanup

Parser cleanup.
This commit is contained in:
Daniel Kirchner 2018-09-06 16:01:44 +02:00 committed by GitHub
commit f19cddd59e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 46 deletions

View File

@ -75,7 +75,7 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
vector<ASTPointer<ASTNode>> nodes; vector<ASTPointer<ASTNode>> nodes;
while (m_scanner->currentToken() != Token::EOS) while (m_scanner->currentToken() != Token::EOS)
{ {
switch (auto token = m_scanner->currentToken()) switch (m_scanner->currentToken())
{ {
case Token::Pragma: case Token::Pragma:
nodes.push_back(parsePragmaDirective()); nodes.push_back(parsePragmaDirective());
@ -86,7 +86,7 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
case Token::Interface: case Token::Interface:
case Token::Contract: case Token::Contract:
case Token::Library: case Token::Library:
nodes.push_back(parseContractDefinition(token)); nodes.push_back(parseContractDefinition());
break; break;
default: default:
fatalParserError(string("Expected pragma, import directive or contract/interface/library definition.")); fatalParserError(string("Expected pragma, import directive or contract/interface/library definition."));
@ -198,31 +198,35 @@ ASTPointer<ImportDirective> Parser::parseImportDirective()
return nodeFactory.createNode<ImportDirective>(path, unitAlias, move(symbolAliases)); return nodeFactory.createNode<ImportDirective>(path, unitAlias, move(symbolAliases));
} }
ContractDefinition::ContractKind Parser::tokenToContractKind(Token::Value _token) ContractDefinition::ContractKind Parser::parseContractKind()
{ {
switch(_token) ContractDefinition::ContractKind kind;
switch(m_scanner->currentToken())
{ {
case Token::Interface: case Token::Interface:
return ContractDefinition::ContractKind::Interface; kind = ContractDefinition::ContractKind::Interface;
break;
case Token::Contract: case Token::Contract:
return ContractDefinition::ContractKind::Contract; kind = ContractDefinition::ContractKind::Contract;
break;
case Token::Library: case Token::Library:
return ContractDefinition::ContractKind::Library; kind = ContractDefinition::ContractKind::Library;
break;
default: default:
fatalParserError("Unsupported contract type."); solAssert(false, "Invalid contract kind.");
} }
// FIXME: fatalParserError is not considered as throwing here m_scanner->next();
return ContractDefinition::ContractKind::Contract; return kind;
} }
ASTPointer<ContractDefinition> Parser::parseContractDefinition(Token::Value _expectedKind) ASTPointer<ContractDefinition> Parser::parseContractDefinition()
{ {
RecursionGuard recursionGuard(*this); RecursionGuard recursionGuard(*this);
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
ASTPointer<ASTString> docString; ASTPointer<ASTString> docString;
if (m_scanner->currentCommentLiteral() != "") if (m_scanner->currentCommentLiteral() != "")
docString = make_shared<ASTString>(m_scanner->currentCommentLiteral()); docString = make_shared<ASTString>(m_scanner->currentCommentLiteral());
expectToken(_expectedKind); ContractDefinition::ContractKind contractKind = parseContractKind();
ASTPointer<ASTString> name = expectIdentifierToken(); ASTPointer<ASTString> name = expectIdentifierToken();
vector<ASTPointer<InheritanceSpecifier>> baseContracts; vector<ASTPointer<InheritanceSpecifier>> baseContracts;
if (m_scanner->currentToken() == Token::Is) if (m_scanner->currentToken() == Token::Is)
@ -275,7 +279,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(Token::Value _exp
docString, docString,
baseContracts, baseContracts,
subNodes, subNodes,
tokenToContractKind(_expectedKind) contractKind
); );
} }
@ -297,42 +301,56 @@ ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()
return nodeFactory.createNode<InheritanceSpecifier>(name, std::move(arguments)); return nodeFactory.createNode<InheritanceSpecifier>(name, std::move(arguments));
} }
Declaration::Visibility Parser::parseVisibilitySpecifier(Token::Value _token) Declaration::Visibility Parser::parseVisibilitySpecifier()
{ {
Declaration::Visibility visibility(Declaration::Visibility::Default); Declaration::Visibility visibility(Declaration::Visibility::Default);
if (_token == Token::Public) Token::Value token = m_scanner->currentToken();
switch (token)
{
case Token::Public:
visibility = Declaration::Visibility::Public; visibility = Declaration::Visibility::Public;
else if (_token == Token::Internal) break;
case Token::Internal:
visibility = Declaration::Visibility::Internal; visibility = Declaration::Visibility::Internal;
else if (_token == Token::Private) break;
case Token::Private:
visibility = Declaration::Visibility::Private; visibility = Declaration::Visibility::Private;
else if (_token == Token::External) break;
case Token::External:
visibility = Declaration::Visibility::External; visibility = Declaration::Visibility::External;
else break;
default:
solAssert(false, "Invalid visibility specifier."); solAssert(false, "Invalid visibility specifier.");
}
m_scanner->next(); m_scanner->next();
return visibility; return visibility;
} }
StateMutability Parser::parseStateMutability(Token::Value _token) StateMutability Parser::parseStateMutability()
{ {
StateMutability stateMutability(StateMutability::NonPayable); StateMutability stateMutability(StateMutability::NonPayable);
if (_token == Token::Payable) Token::Value token = m_scanner->currentToken();
stateMutability = StateMutability::Payable; switch(token)
else if (_token == Token::View)
stateMutability = StateMutability::View;
else if (_token == Token::Pure)
stateMutability = StateMutability::Pure;
else if (_token == Token::Constant)
{ {
case Token::Payable:
stateMutability = StateMutability::Payable;
break;
case Token::View:
stateMutability = StateMutability::View;
break;
case Token::Pure:
stateMutability = StateMutability::Pure;
break;
case Token::Constant:
stateMutability = StateMutability::View; stateMutability = StateMutability::View;
parserError( parserError(
"The state mutability modifier \"constant\" was removed in version 0.5.0. " "The state mutability modifier \"constant\" was removed in version 0.5.0. "
"Use \"view\" or \"pure\" instead." "Use \"view\" or \"pure\" instead."
); );
} break;
else default:
solAssert(false, "Invalid state mutability specifier."); solAssert(false, "Invalid state mutability specifier.");
}
m_scanner->next(); m_scanner->next();
return stateMutability; return stateMutability;
} }
@ -403,7 +421,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN
m_scanner->next(); m_scanner->next();
} }
else else
result.visibility = parseVisibilitySpecifier(token); result.visibility = parseVisibilitySpecifier();
} }
else if (Token::isStateMutabilitySpecifier(token)) else if (Token::isStateMutabilitySpecifier(token))
{ {
@ -417,7 +435,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN
m_scanner->next(); m_scanner->next();
} }
else else
result.stateMutability = parseStateMutability(token); result.stateMutability = parseStateMutability();
} }
else else
break; break;
@ -583,7 +601,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
m_scanner->next(); m_scanner->next();
} }
else else
visibility = parseVisibilitySpecifier(token); visibility = parseVisibilitySpecifier();
} }
else else
{ {

View File

@ -69,11 +69,11 @@ private:
///@name Parsing functions for the AST nodes ///@name Parsing functions for the AST nodes
ASTPointer<PragmaDirective> parsePragmaDirective(); ASTPointer<PragmaDirective> parsePragmaDirective();
ASTPointer<ImportDirective> parseImportDirective(); ASTPointer<ImportDirective> parseImportDirective();
ContractDefinition::ContractKind tokenToContractKind(Token::Value _token); ContractDefinition::ContractKind parseContractKind();
ASTPointer<ContractDefinition> parseContractDefinition(Token::Value _expectedKind); ASTPointer<ContractDefinition> parseContractDefinition();
ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier(); ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier();
Declaration::Visibility parseVisibilitySpecifier(Token::Value _token); Declaration::Visibility parseVisibilitySpecifier();
StateMutability parseStateMutability(Token::Value _token); StateMutability parseStateMutability();
FunctionHeaderParserResult parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers); FunctionHeaderParserResult parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers);
ASTPointer<ASTNode> parseFunctionDefinitionOrFunctionTypeStateVariable(); ASTPointer<ASTNode> parseFunctionDefinitionOrFunctionTypeStateVariable();
ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName); ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName);