mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Parse multi variable declaration statement.
This commit is contained in:
parent
2ba0002998
commit
67d208d144
@ -7,6 +7,7 @@ Features:
|
||||
* Control Flow Graph: Add Control Flow Graph as analysis structure.
|
||||
* Control Flow Graph: Warn about returning uninitialized storage pointers.
|
||||
* Gas Estimator: Only explore paths with higher gas costs. This reduces accuracy but greatly improves the speed of gas estimation.
|
||||
* General: Allow multiple variables to be declared as part of a tuple assignment, e.g. ``(uint a, uint b) = ...``.
|
||||
* Optimizer: Remove unnecessary masking of the result of known short instructions (``ADDRESS``, ``CALLER``, ``ORIGIN`` and ``COINBASE``).
|
||||
* Parser: Display nicer error messages by showing the actual tokens and not internal names.
|
||||
* Parser: Use the entire location of the token instead of only its starting position as source location for parser errors.
|
||||
|
@ -1086,15 +1086,79 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const&
|
||||
LookAheadInfo statementType;
|
||||
IndexAccessedPath iap;
|
||||
|
||||
tie(statementType, iap) = tryParseIndexAccessedPath();
|
||||
switch (statementType)
|
||||
if (m_scanner->currentToken() == Token::LParen)
|
||||
{
|
||||
case LookAheadInfo::VariableDeclaration:
|
||||
return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap));
|
||||
case LookAheadInfo::Expression:
|
||||
return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap));
|
||||
default:
|
||||
solAssert(false, "");
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
size_t emptyComponents = 0;
|
||||
// First consume all empty components.
|
||||
expectToken(Token::LParen);
|
||||
while (m_scanner->currentToken() == Token::Comma)
|
||||
{
|
||||
m_scanner->next();
|
||||
emptyComponents++;
|
||||
}
|
||||
|
||||
// Now see whether we have a variable declaration or an expression.
|
||||
tie(statementType, iap) = tryParseIndexAccessedPath();
|
||||
switch (statementType)
|
||||
{
|
||||
case LookAheadInfo::VariableDeclaration:
|
||||
{
|
||||
vector<ASTPointer<VariableDeclaration>> variables;
|
||||
ASTPointer<Expression> value;
|
||||
// We have already parsed something like `(,,,,a.b.c[2][3]`
|
||||
VarDeclParserOptions options;
|
||||
options.allowLocationSpecifier = true;
|
||||
variables = vector<ASTPointer<VariableDeclaration>>(emptyComponents, nullptr);
|
||||
variables.push_back(parseVariableDeclaration(options, typeNameFromIndexAccessStructure(iap)));
|
||||
|
||||
while (m_scanner->currentToken() != Token::RParen)
|
||||
{
|
||||
expectToken(Token::Comma);
|
||||
if (m_scanner->currentToken() == Token::Comma || m_scanner->currentToken() == Token::RParen)
|
||||
variables.push_back(nullptr);
|
||||
else
|
||||
variables.push_back(parseVariableDeclaration(options));
|
||||
}
|
||||
expectToken(Token::RParen);
|
||||
expectToken(Token::Assign);
|
||||
value = parseExpression();
|
||||
nodeFactory.setEndPositionFromNode(value);
|
||||
return nodeFactory.createNode<VariableDeclarationStatement>(_docString, variables, value);
|
||||
}
|
||||
case LookAheadInfo::Expression:
|
||||
{
|
||||
// Complete parsing the expression in the current component.
|
||||
vector<ASTPointer<Expression>> components(emptyComponents, nullptr);
|
||||
components.push_back(parseExpression(expressionFromIndexAccessStructure(iap)));
|
||||
while (m_scanner->currentToken() != Token::RParen)
|
||||
{
|
||||
expectToken(Token::Comma);
|
||||
if (m_scanner->currentToken() == Token::Comma || m_scanner->currentToken() == Token::RParen)
|
||||
components.push_back(ASTPointer<Expression>());
|
||||
else
|
||||
components.push_back(parseExpression());
|
||||
}
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RParen);
|
||||
return parseExpressionStatement(_docString, nodeFactory.createNode<TupleExpression>(components, false));
|
||||
}
|
||||
default:
|
||||
solAssert(false, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tie(statementType, iap) = tryParseIndexAccessedPath();
|
||||
switch (statementType)
|
||||
{
|
||||
case LookAheadInfo::VariableDeclaration:
|
||||
return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap));
|
||||
case LookAheadInfo::Expression:
|
||||
return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap));
|
||||
default:
|
||||
solAssert(false, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1144,6 +1208,9 @@ ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStateme
|
||||
ASTPointer<TypeName> const& _lookAheadArrayType
|
||||
)
|
||||
{
|
||||
// This does not parse multi variable declaration statements starting directly with
|
||||
// `(`, they are parsed in parseSimpleStatement, because they are hard to distinguish
|
||||
// from tuple expressions.
|
||||
RecursionGuard recursionGuard(*this);
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
if (_lookAheadArrayType)
|
||||
|
Loading…
Reference in New Issue
Block a user