mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Refactor parser.
This commit is contained in:
parent
ef2111a2fe
commit
d44fb03322
@ -1057,16 +1057,16 @@ ASTPointer<EmitStatement> Parser::parseEmitStatement(ASTPointer<ASTString> const
|
|||||||
if (m_scanner->currentToken() != Token::Identifier)
|
if (m_scanner->currentToken() != Token::Identifier)
|
||||||
fatalParserError("Expected event name or path.");
|
fatalParserError("Expected event name or path.");
|
||||||
|
|
||||||
vector<ASTPointer<PrimaryExpression>> path;
|
IndexAccessedPath iap;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
path.push_back(parseIdentifier());
|
iap.path.push_back(parseIdentifier());
|
||||||
if (m_scanner->currentToken() != Token::Period)
|
if (m_scanner->currentToken() != Token::Period)
|
||||||
break;
|
break;
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto eventName = expressionFromIndexAccessStructure(path, {});
|
auto eventName = expressionFromIndexAccessStructure(iap);
|
||||||
expectToken(Token::LParen);
|
expectToken(Token::LParen);
|
||||||
|
|
||||||
vector<ASTPointer<Expression>> arguments;
|
vector<ASTPointer<Expression>> arguments;
|
||||||
@ -1098,46 +1098,17 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const&
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, we have 'Identifier "["' or 'Identifier "." Identifier' or 'ElementoryTypeName "["'.
|
// At this point, we have 'Identifier "["' or 'Identifier "." Identifier' or 'ElementoryTypeName "["'.
|
||||||
// We parse '(Identifier ("." Identifier)* |ElementaryTypeName) ( "[" Expression "]" )+'
|
// We parse '(Identifier ("." Identifier)* |ElementaryTypeName) ( "[" Expression "]" )*'
|
||||||
// until we can decide whether to hand this over to ExpressionStatement or create a
|
// until we can decide whether to hand this over to ExpressionStatement or create a
|
||||||
// VariableDeclarationStatement out of it.
|
// VariableDeclarationStatement out of it.
|
||||||
vector<ASTPointer<PrimaryExpression>> path;
|
IndexAccessedPath iap = parseIndexAccessedPath();
|
||||||
bool startedWithElementary = false;
|
|
||||||
if (m_scanner->currentToken() == Token::Identifier)
|
|
||||||
path.push_back(parseIdentifier());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
startedWithElementary = true;
|
|
||||||
unsigned firstNum;
|
|
||||||
unsigned secondNum;
|
|
||||||
tie(firstNum, secondNum) = m_scanner->currentTokenInfo();
|
|
||||||
ElementaryTypeNameToken elemToken(m_scanner->currentToken(), firstNum, secondNum);
|
|
||||||
path.push_back(ASTNodeFactory(*this).createNode<ElementaryTypeNameExpression>(elemToken));
|
|
||||||
m_scanner->next();
|
|
||||||
}
|
|
||||||
while (!startedWithElementary && m_scanner->currentToken() == Token::Period)
|
|
||||||
{
|
|
||||||
m_scanner->next();
|
|
||||||
path.push_back(parseIdentifier());
|
|
||||||
}
|
|
||||||
vector<pair<ASTPointer<Expression>, SourceLocation>> indices;
|
|
||||||
while (m_scanner->currentToken() == Token::LBrack)
|
|
||||||
{
|
|
||||||
expectToken(Token::LBrack);
|
|
||||||
ASTPointer<Expression> index;
|
|
||||||
if (m_scanner->currentToken() != Token::RBrack)
|
|
||||||
index = parseExpression();
|
|
||||||
SourceLocation indexLocation = path.front()->location();
|
|
||||||
indexLocation.end = endPosition();
|
|
||||||
indices.push_back(make_pair(index, indexLocation));
|
|
||||||
expectToken(Token::RBrack);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_scanner->currentToken() == Token::Identifier || Token::isLocationSpecifier(m_scanner->currentToken()))
|
if (m_scanner->currentToken() == Token::Identifier || Token::isLocationSpecifier(m_scanner->currentToken()))
|
||||||
return parseVariableDeclarationStatement(_docString, typeNameIndexAccessStructure(path, indices));
|
return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap));
|
||||||
else
|
else
|
||||||
return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(path, indices));
|
return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap));
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement(
|
ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement(
|
||||||
@ -1529,32 +1500,65 @@ Parser::LookAheadInfo Parser::peekStatementType() const
|
|||||||
return LookAheadInfo::ExpressionStatement;
|
return LookAheadInfo::ExpressionStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<TypeName> Parser::typeNameIndexAccessStructure(
|
Parser::IndexAccessedPath Parser::parseIndexAccessedPath()
|
||||||
vector<ASTPointer<PrimaryExpression>> const& _path,
|
|
||||||
vector<pair<ASTPointer<Expression>, SourceLocation>> const& _indices
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
solAssert(!_path.empty(), "");
|
IndexAccessedPath iap;
|
||||||
|
if (m_scanner->currentToken() == Token::Identifier)
|
||||||
|
{
|
||||||
|
iap.path.push_back(parseIdentifier());
|
||||||
|
while (m_scanner->currentToken() == Token::Period)
|
||||||
|
{
|
||||||
|
m_scanner->next();
|
||||||
|
iap.path.push_back(parseIdentifier());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned firstNum;
|
||||||
|
unsigned secondNum;
|
||||||
|
tie(firstNum, secondNum) = m_scanner->currentTokenInfo();
|
||||||
|
ElementaryTypeNameToken elemToken(m_scanner->currentToken(), firstNum, secondNum);
|
||||||
|
iap.path.push_back(ASTNodeFactory(*this).createNode<ElementaryTypeNameExpression>(elemToken));
|
||||||
|
m_scanner->next();
|
||||||
|
}
|
||||||
|
while (m_scanner->currentToken() == Token::LBrack)
|
||||||
|
{
|
||||||
|
expectToken(Token::LBrack);
|
||||||
|
ASTPointer<Expression> index;
|
||||||
|
if (m_scanner->currentToken() != Token::RBrack)
|
||||||
|
index = parseExpression();
|
||||||
|
SourceLocation indexLocation = iap.path.front()->location();
|
||||||
|
indexLocation.end = endPosition();
|
||||||
|
iap.indices.push_back(make_pair(index, indexLocation));
|
||||||
|
expectToken(Token::RBrack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return iap;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTPointer<TypeName> Parser::typeNameFromIndexAccessStructure(Parser::IndexAccessedPath const& _iap)
|
||||||
|
{
|
||||||
|
solAssert(!_iap.path.empty(), "");
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
SourceLocation location = _path.front()->location();
|
SourceLocation location = _iap.path.front()->location();
|
||||||
location.end = _path.back()->location().end;
|
location.end = _iap.path.back()->location().end;
|
||||||
nodeFactory.setLocation(location);
|
nodeFactory.setLocation(location);
|
||||||
|
|
||||||
ASTPointer<TypeName> type;
|
ASTPointer<TypeName> type;
|
||||||
if (auto typeName = dynamic_cast<ElementaryTypeNameExpression const*>(_path.front().get()))
|
if (auto typeName = dynamic_cast<ElementaryTypeNameExpression const*>(_iap.path.front().get()))
|
||||||
{
|
{
|
||||||
solAssert(_path.size() == 1, "");
|
solAssert(_iap.path.size() == 1, "");
|
||||||
type = nodeFactory.createNode<ElementaryTypeName>(typeName->typeName());
|
type = nodeFactory.createNode<ElementaryTypeName>(typeName->typeName());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vector<ASTString> path;
|
vector<ASTString> path;
|
||||||
for (auto const& el: _path)
|
for (auto const& el: _iap.path)
|
||||||
path.push_back(dynamic_cast<Identifier const&>(*el).name());
|
path.push_back(dynamic_cast<Identifier const&>(*el).name());
|
||||||
type = nodeFactory.createNode<UserDefinedTypeName>(path);
|
type = nodeFactory.createNode<UserDefinedTypeName>(path);
|
||||||
}
|
}
|
||||||
for (auto const& lengthExpression: _indices)
|
for (auto const& lengthExpression: _iap.indices)
|
||||||
{
|
{
|
||||||
nodeFactory.setLocation(lengthExpression.second);
|
nodeFactory.setLocation(lengthExpression.second);
|
||||||
type = nodeFactory.createNode<ArrayTypeName>(type, lengthExpression.first);
|
type = nodeFactory.createNode<ArrayTypeName>(type, lengthExpression.first);
|
||||||
@ -1563,26 +1567,25 @@ ASTPointer<TypeName> Parser::typeNameIndexAccessStructure(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<Expression> Parser::expressionFromIndexAccessStructure(
|
ASTPointer<Expression> Parser::expressionFromIndexAccessStructure(
|
||||||
vector<ASTPointer<PrimaryExpression>> const& _path,
|
Parser::IndexAccessedPath const& _iap
|
||||||
vector<pair<ASTPointer<Expression>, SourceLocation>> const& _indices
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
solAssert(!_path.empty(), "");
|
solAssert(!_iap.path.empty(), "");
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTNodeFactory nodeFactory(*this, _path.front());
|
ASTNodeFactory nodeFactory(*this, _iap.path.front());
|
||||||
ASTPointer<Expression> expression(_path.front());
|
ASTPointer<Expression> expression(_iap.path.front());
|
||||||
for (size_t i = 1; i < _path.size(); ++i)
|
for (size_t i = 1; i < _iap.path.size(); ++i)
|
||||||
{
|
{
|
||||||
SourceLocation location(_path.front()->location());
|
SourceLocation location(_iap.path.front()->location());
|
||||||
location.end = _path[i]->location().end;
|
location.end = _iap.path[i]->location().end;
|
||||||
nodeFactory.setLocation(location);
|
nodeFactory.setLocation(location);
|
||||||
Identifier const& identifier = dynamic_cast<Identifier const&>(*_path[i]);
|
Identifier const& identifier = dynamic_cast<Identifier const&>(*_iap.path[i]);
|
||||||
expression = nodeFactory.createNode<MemberAccess>(
|
expression = nodeFactory.createNode<MemberAccess>(
|
||||||
expression,
|
expression,
|
||||||
make_shared<ASTString>(identifier.name())
|
make_shared<ASTString>(identifier.name())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for (auto const& index: _indices)
|
for (auto const& index: _iap.indices)
|
||||||
{
|
{
|
||||||
nodeFactory.setLocation(index.second);
|
nodeFactory.setLocation(index.second);
|
||||||
expression = nodeFactory.createNode<IndexAccess>(expression, index.first);
|
expression = nodeFactory.createNode<IndexAccess>(expression, index.first);
|
||||||
|
@ -145,21 +145,25 @@ private:
|
|||||||
{
|
{
|
||||||
IndexAccessStructure, VariableDeclarationStatement, ExpressionStatement
|
IndexAccessStructure, VariableDeclarationStatement, ExpressionStatement
|
||||||
};
|
};
|
||||||
|
/// Structure that represents a.b.c[x][y][z]. Can be converted either to an expression
|
||||||
|
/// or to a type name. Path cannot be empty, but indices can be empty.
|
||||||
|
struct IndexAccessedPath
|
||||||
|
{
|
||||||
|
std::vector<ASTPointer<PrimaryExpression>> path;
|
||||||
|
std::vector<std::pair<ASTPointer<Expression>, SourceLocation>> indices;
|
||||||
|
};
|
||||||
|
|
||||||
/// Performs limited look-ahead to distinguish between variable declaration and expression statement.
|
/// Performs limited look-ahead to distinguish between variable declaration and expression statement.
|
||||||
/// For source code of the form "a[][8]" ("IndexAccessStructure"), this is not possible to
|
/// For source code of the form "a[][8]" ("IndexAccessStructure"), this is not possible to
|
||||||
/// decide with constant look-ahead.
|
/// decide with constant look-ahead.
|
||||||
LookAheadInfo peekStatementType() const;
|
LookAheadInfo peekStatementType() const;
|
||||||
|
/// @returns an IndexAccessedPath as a prestage to parsing a variable declaration (type name)
|
||||||
|
/// or an expression;
|
||||||
|
IndexAccessedPath parseIndexAccessedPath();
|
||||||
/// @returns a typename parsed in look-ahead fashion from something like "a.b[8][2**70]".
|
/// @returns a typename parsed in look-ahead fashion from something like "a.b[8][2**70]".
|
||||||
ASTPointer<TypeName> typeNameIndexAccessStructure(
|
ASTPointer<TypeName> typeNameFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
|
||||||
std::vector<ASTPointer<PrimaryExpression>> const& _path,
|
|
||||||
std::vector<std::pair<ASTPointer<Expression>, SourceLocation>> const& _indices
|
|
||||||
);
|
|
||||||
/// @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(
|
ASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
|
||||||
std::vector<ASTPointer<PrimaryExpression>> const& _path,
|
|
||||||
std::vector<std::pair<ASTPointer<Expression>, SourceLocation>> const& _indices
|
|
||||||
);
|
|
||||||
|
|
||||||
std::string currentTokenName();
|
std::string currentTokenName();
|
||||||
Token::Value expectAssignmentOperator();
|
Token::Value expectAssignmentOperator();
|
||||||
|
Loading…
Reference in New Issue
Block a user