mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
WIP
This commit is contained in:
parent
325a78fe47
commit
0e13a3ae3c
@ -8,7 +8,17 @@
|
||||
grammar Solidity;
|
||||
|
||||
sourceUnit
|
||||
: (pragmaDirective | importDirective | structDefinition | enumDefinition | contractDefinition)* EOF ;
|
||||
: globalDefinition* EOF ;
|
||||
|
||||
globalDefinition
|
||||
: pragmaDirective
|
||||
| contractDefinition
|
||||
| enumDefinition
|
||||
| importDirective
|
||||
| interfaceDefinition
|
||||
| libraryDefinition
|
||||
| structDefinition
|
||||
;
|
||||
|
||||
pragmaDirective
|
||||
: 'pragma' pragmaName pragmaValue ';' ;
|
||||
@ -36,10 +46,25 @@ importDirective
|
||||
importDeclaration
|
||||
: identifier ('as' identifier)? ;
|
||||
|
||||
interfaceDefinition
|
||||
: 'interface' identifier 'from' StringLiteralFragment
|
||||
| 'interface' identifier 'as' AbiString
|
||||
| 'interface' identifier contractInheritanceDefinition? contractBody ;
|
||||
|
||||
AbiString
|
||||
: StringLiteral ;
|
||||
|
||||
libraryDefinition
|
||||
: 'abstract'? 'library' identifier contractInheritanceDefinition? contractBody ;
|
||||
|
||||
contractDefinition
|
||||
: 'abstract'? ( 'contract' | 'interface' | 'library' ) identifier
|
||||
( 'is' inheritanceSpecifier (',' inheritanceSpecifier )* )?
|
||||
'{' contractPart* '}' ;
|
||||
: 'abstract'? 'contract' identifier contractInheritanceDefinition? contractBody ;
|
||||
|
||||
contractInheritanceDefinition
|
||||
: ( 'is' inheritanceSpecifier (',' inheritanceSpecifier )* ) ;
|
||||
|
||||
contractBody
|
||||
: '{' contractPart* '}' ;
|
||||
|
||||
inheritanceSpecifier
|
||||
: userDefinedTypeName ( '(' expressionList? ')' )? ;
|
||||
|
@ -94,8 +94,10 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
|
||||
case Token::Import:
|
||||
nodes.push_back(parseImportDirective());
|
||||
break;
|
||||
case Token::Abstract:
|
||||
case Token::Interface:
|
||||
// nodes.push_back(parseInterfaceDefinition());
|
||||
// break;
|
||||
case Token::Abstract:
|
||||
case Token::Contract:
|
||||
case Token::Library:
|
||||
nodes.push_back(parseContractDefinition());
|
||||
@ -290,6 +292,35 @@ std::pair<ContractKind, bool> Parser::parseContractKind()
|
||||
return std::make_pair(kind, abstract);
|
||||
}
|
||||
|
||||
ASTPointer<ContractDefinition> Parser::parseInterfaceDefinition()
|
||||
{
|
||||
// interfaceDefinition
|
||||
// : 'interface' identifier 'from' StringLiteralFragment
|
||||
// | 'interface' identifier 'as' AbiString
|
||||
// | 'interface' identifier contractInheritanceDefinition? contractBody ;
|
||||
|
||||
m_scanner->next();
|
||||
|
||||
RecursionGuard recursionGuard(*this);
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
|
||||
ASTPointer<ASTString> name = expectIdentifierToken();
|
||||
|
||||
ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();
|
||||
|
||||
vector<ASTPointer<InheritanceSpecifier>> baseContracts;
|
||||
vector<ASTPointer<ASTNode>> subNodes;//TODO = parseContractBody();
|
||||
|
||||
return nodeFactory.createNode<ContractDefinition>(
|
||||
name,
|
||||
documentation,
|
||||
baseContracts,
|
||||
subNodes,
|
||||
ContractKind::Interface,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
@ -311,6 +342,84 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
||||
baseContracts.push_back(parseInheritanceSpecifier());
|
||||
}
|
||||
while (m_scanner->currentToken() == Token::Comma);
|
||||
#if 0
|
||||
parseContractBody(subNodes);
|
||||
//subNodes = parseContractBody();
|
||||
#else
|
||||
expectToken(Token::LBrace);
|
||||
while (true)
|
||||
{
|
||||
Token currentTokenValue = m_scanner->currentToken();
|
||||
if (currentTokenValue == Token::RBrace)
|
||||
break;
|
||||
else if (
|
||||
(currentTokenValue == Token::Function && m_scanner->peekNextToken() != Token::LParen) ||
|
||||
currentTokenValue == Token::Constructor ||
|
||||
currentTokenValue == Token::Receive ||
|
||||
currentTokenValue == Token::Fallback
|
||||
)
|
||||
subNodes.push_back(parseFunctionDefinition());
|
||||
else if (currentTokenValue == Token::Struct)
|
||||
subNodes.push_back(parseStructDefinition());
|
||||
else if (currentTokenValue == Token::Enum)
|
||||
subNodes.push_back(parseEnumDefinition());
|
||||
else if (
|
||||
currentTokenValue == Token::Identifier ||
|
||||
currentTokenValue == Token::Mapping ||
|
||||
TokenTraits::isElementaryTypeName(currentTokenValue) ||
|
||||
(currentTokenValue == Token::Function && m_scanner->peekNextToken() == Token::LParen)
|
||||
)
|
||||
{
|
||||
VarDeclParserOptions options;
|
||||
options.isStateVariable = true;
|
||||
options.allowInitialValue = true;
|
||||
subNodes.push_back(parseVariableDeclaration(options));
|
||||
expectToken(Token::Semicolon);
|
||||
}
|
||||
else if (currentTokenValue == Token::Modifier)
|
||||
subNodes.push_back(parseModifierDefinition());
|
||||
else if (currentTokenValue == Token::Event)
|
||||
subNodes.push_back(parseEventDefinition());
|
||||
else if (currentTokenValue == Token::Using)
|
||||
subNodes.push_back(parseUsingDirective());
|
||||
else
|
||||
fatalParserError(9182_error, "Function, variable, struct or modifier declaration expected.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (FatalError const&)
|
||||
{
|
||||
if (
|
||||
!m_errorReporter.hasErrors() ||
|
||||
!m_parserErrorRecovery ||
|
||||
m_errorReporter.hasExcessiveErrors()
|
||||
)
|
||||
BOOST_THROW_EXCEPTION(FatalError()); /* Don't try to recover here. */
|
||||
nodeFactory.markEndPosition();
|
||||
expectTokenOrConsumeUntil(Token::RBrace, "ContractDefinition");
|
||||
m_inParserRecovery = true;
|
||||
}
|
||||
nodeFactory.markEndPosition();
|
||||
if (m_inParserRecovery)
|
||||
expectTokenOrConsumeUntil(Token::RBrace, "ContractDefinition");
|
||||
else
|
||||
expectToken(Token::RBrace);
|
||||
return nodeFactory.createNode<ContractDefinition>(
|
||||
name,
|
||||
documentation,
|
||||
baseContracts,
|
||||
subNodes,
|
||||
contractKind.first,
|
||||
contractKind.second
|
||||
);
|
||||
}
|
||||
|
||||
void Parser::parseContractBody(vector<ASTPointer<ASTNode>>& subNodes)
|
||||
{
|
||||
//vector<ASTPointer<ASTNode>> subNodes;
|
||||
|
||||
try
|
||||
{
|
||||
expectToken(Token::LBrace);
|
||||
while (true)
|
||||
{
|
||||
@ -353,6 +462,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
||||
}
|
||||
catch (FatalError const&)
|
||||
{
|
||||
printf("FatalError: in parser recovery\n");
|
||||
if (
|
||||
!m_errorReporter.hasErrors() ||
|
||||
!m_parserErrorRecovery ||
|
||||
@ -361,19 +471,13 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
||||
BOOST_THROW_EXCEPTION(FatalError()); /* Don't try to recover here. */
|
||||
m_inParserRecovery = true;
|
||||
}
|
||||
nodeFactory.markEndPosition();
|
||||
|
||||
if (m_inParserRecovery)
|
||||
expectTokenOrConsumeUntil(Token::RBrace, "ContractDefinition");
|
||||
else
|
||||
expectToken(Token::RBrace);
|
||||
return nodeFactory.createNode<ContractDefinition>(
|
||||
name,
|
||||
documentation,
|
||||
baseContracts,
|
||||
subNodes,
|
||||
contractKind.first,
|
||||
contractKind.second
|
||||
);
|
||||
|
||||
//return subNodes;
|
||||
}
|
||||
|
||||
ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()
|
||||
|
@ -87,6 +87,9 @@ private:
|
||||
/// result.second is set to true, if an abstract contract was parsed, false otherwise.
|
||||
std::pair<ContractKind, bool> parseContractKind();
|
||||
ASTPointer<ContractDefinition> parseContractDefinition();
|
||||
ASTPointer<ContractDefinition> parseInterfaceDefinition();
|
||||
//std::vector<ASTPointer<ASTNode>> parseContractBody();
|
||||
void parseContractBody(std::vector<ASTPointer<ASTNode>>& _result);
|
||||
ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier();
|
||||
Visibility parseVisibilitySpecifier();
|
||||
ASTPointer<OverrideSpecifier> parseOverrideSpecifier();
|
||||
|
Loading…
Reference in New Issue
Block a user