mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Further refactor.
This commit is contained in:
parent
86b7adc18f
commit
be54f48197
@ -1083,18 +1083,36 @@ ASTPointer<EmitStatement> Parser::parseEmitStatement(ASTPointer<ASTString> const
|
|||||||
ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& _docString)
|
ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& _docString)
|
||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
|
LookAheadInfo statementType;
|
||||||
|
IndexAccessedPath iap;
|
||||||
|
|
||||||
|
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, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pair<Parser::LookAheadInfo, Parser::IndexAccessedPath> Parser::tryParseIndexAccessedPath()
|
||||||
|
{
|
||||||
// These two cases are very hard to distinguish:
|
// These two cases are very hard to distinguish:
|
||||||
// x[7 * 20 + 3] a; - x[7 * 20 + 3] = 9;
|
// x[7 * 20 + 3] a; and x[7 * 20 + 3] = 9;
|
||||||
// In the first case, x is a type name, in the second it is the name of a variable.
|
// In the first case, x is a type name, in the second it is the name of a variable.
|
||||||
// As an extension, we can even have:
|
// As an extension, we can even have:
|
||||||
// `x.y.z[1][2] a;` and `x.y.z[1][2] = 10;`
|
// `x.y.z[1][2] a;` and `x.y.z[1][2] = 10;`
|
||||||
// Where in the first, x.y.z leads to a type name where in the second, it accesses structs.
|
// Where in the first, x.y.z leads to a type name where in the second, it accesses structs.
|
||||||
switch (peekStatementType())
|
|
||||||
|
auto statementType = peekStatementType();
|
||||||
|
switch (statementType)
|
||||||
{
|
{
|
||||||
case LookAheadInfo::VariableDeclarationStatement:
|
case LookAheadInfo::VariableDeclaration:
|
||||||
return parseVariableDeclarationStatement(_docString);
|
case LookAheadInfo::Expression:
|
||||||
case LookAheadInfo::ExpressionStatement:
|
return make_pair(statementType, IndexAccessedPath());
|
||||||
return parseExpressionStatement(_docString);
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1106,9 +1124,9 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const&
|
|||||||
IndexAccessedPath iap = parseIndexAccessedPath();
|
IndexAccessedPath iap = parseIndexAccessedPath();
|
||||||
|
|
||||||
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, typeNameFromIndexAccessStructure(iap));
|
return make_pair(LookAheadInfo::VariableDeclaration, move(iap));
|
||||||
else
|
else
|
||||||
return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap));
|
return make_pair(LookAheadInfo::Expression, move(iap));
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement(
|
ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement(
|
||||||
@ -1489,16 +1507,16 @@ Parser::LookAheadInfo Parser::peekStatementType() const
|
|||||||
bool mightBeTypeName = (Token::isElementaryTypeName(token) || token == Token::Identifier);
|
bool mightBeTypeName = (Token::isElementaryTypeName(token) || token == Token::Identifier);
|
||||||
|
|
||||||
if (token == Token::Mapping || token == Token::Function || token == Token::Var)
|
if (token == Token::Mapping || token == Token::Function || token == Token::Var)
|
||||||
return LookAheadInfo::VariableDeclarationStatement;
|
return LookAheadInfo::VariableDeclaration;
|
||||||
if (mightBeTypeName)
|
if (mightBeTypeName)
|
||||||
{
|
{
|
||||||
Token::Value next = m_scanner->peekNextToken();
|
Token::Value next = m_scanner->peekNextToken();
|
||||||
if (next == Token::Identifier || Token::isLocationSpecifier(next))
|
if (next == Token::Identifier || Token::isLocationSpecifier(next))
|
||||||
return LookAheadInfo::VariableDeclarationStatement;
|
return LookAheadInfo::VariableDeclaration;
|
||||||
if (next == Token::LBrack || next == Token::Period)
|
if (next == Token::LBrack || next == Token::Period)
|
||||||
return LookAheadInfo::IndexAccessStructure;
|
return LookAheadInfo::IndexAccessStructure;
|
||||||
}
|
}
|
||||||
return LookAheadInfo::ExpressionStatement;
|
return LookAheadInfo::Expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::IndexAccessedPath Parser::parseIndexAccessedPath()
|
Parser::IndexAccessedPath Parser::parseIndexAccessedPath()
|
||||||
@ -1539,7 +1557,9 @@ Parser::IndexAccessedPath Parser::parseIndexAccessedPath()
|
|||||||
|
|
||||||
ASTPointer<TypeName> Parser::typeNameFromIndexAccessStructure(Parser::IndexAccessedPath const& _iap)
|
ASTPointer<TypeName> Parser::typeNameFromIndexAccessStructure(Parser::IndexAccessedPath const& _iap)
|
||||||
{
|
{
|
||||||
solAssert(!_iap.path.empty(), "");
|
if (_iap.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
SourceLocation location = _iap.path.front()->location();
|
SourceLocation location = _iap.path.front()->location();
|
||||||
@ -1571,7 +1591,9 @@ ASTPointer<Expression> Parser::expressionFromIndexAccessStructure(
|
|||||||
Parser::IndexAccessedPath const& _iap
|
Parser::IndexAccessedPath const& _iap
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
solAssert(!_iap.path.empty(), "");
|
if (_iap.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTNodeFactory nodeFactory(*this, _iap.path.front());
|
ASTNodeFactory nodeFactory(*this, _iap.path.front());
|
||||||
ASTPointer<Expression> expression(_iap.path.front());
|
ASTPointer<Expression> expression(_iap.path.front());
|
||||||
|
@ -143,16 +143,18 @@ private:
|
|||||||
/// Used as return value of @see peekStatementType.
|
/// Used as return value of @see peekStatementType.
|
||||||
enum class LookAheadInfo
|
enum class LookAheadInfo
|
||||||
{
|
{
|
||||||
IndexAccessStructure, VariableDeclarationStatement, ExpressionStatement
|
IndexAccessStructure, VariableDeclaration, Expression
|
||||||
};
|
};
|
||||||
/// Structure that represents a.b.c[x][y][z]. Can be converted either to an expression
|
/// 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.
|
/// or to a type name. For this to be valid, path cannot be empty, but indices can be empty.
|
||||||
struct IndexAccessedPath
|
struct IndexAccessedPath
|
||||||
{
|
{
|
||||||
std::vector<ASTPointer<PrimaryExpression>> path;
|
std::vector<ASTPointer<PrimaryExpression>> path;
|
||||||
std::vector<std::pair<ASTPointer<Expression>, SourceLocation>> indices;
|
std::vector<std::pair<ASTPointer<Expression>, SourceLocation>> indices;
|
||||||
|
bool empty() const { return path.empty() && indices.empty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::pair<LookAheadInfo, IndexAccessedPath> tryParseIndexAccessedPath();
|
||||||
/// 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.
|
||||||
@ -160,9 +162,11 @@ private:
|
|||||||
/// @returns an IndexAccessedPath as a prestage to parsing a variable declaration (type name)
|
/// @returns an IndexAccessedPath as a prestage to parsing a variable declaration (type name)
|
||||||
/// or an expression;
|
/// or an expression;
|
||||||
IndexAccessedPath parseIndexAccessedPath();
|
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]",
|
||||||
|
/// or an empty pointer if an empty @a _pathAndIncides has been supplied.
|
||||||
ASTPointer<TypeName> typeNameFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
|
ASTPointer<TypeName> typeNameFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
|
||||||
/// @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]",
|
||||||
|
/// or an empty pointer if an empty @a _pathAndIncides has been supplied.
|
||||||
ASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
|
ASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
|
||||||
|
|
||||||
ASTPointer<ASTString> expectIdentifierToken();
|
ASTPointer<ASTString> expectIdentifierToken();
|
||||||
|
Loading…
Reference in New Issue
Block a user