diff options
author | chriseth <chris@ethereum.org> | 2018-04-28 06:26:56 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2018-05-09 17:48:21 +0800 |
commit | be54f4819713ce5737a271bbdc43ac0a73a8e456 (patch) | |
tree | bbb504047efb23d50f16ef001059b124831a5a33 | |
parent | 86b7adc18f14049c7ea4aed9eaaa9b0368d8ec9e (diff) | |
download | dexon-solidity-be54f4819713ce5737a271bbdc43ac0a73a8e456.tar dexon-solidity-be54f4819713ce5737a271bbdc43ac0a73a8e456.tar.gz dexon-solidity-be54f4819713ce5737a271bbdc43ac0a73a8e456.tar.bz2 dexon-solidity-be54f4819713ce5737a271bbdc43ac0a73a8e456.tar.lz dexon-solidity-be54f4819713ce5737a271bbdc43ac0a73a8e456.tar.xz dexon-solidity-be54f4819713ce5737a271bbdc43ac0a73a8e456.tar.zst dexon-solidity-be54f4819713ce5737a271bbdc43ac0a73a8e456.zip |
Further refactor.
-rw-r--r-- | libsolidity/parsing/Parser.cpp | 48 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.h | 12 |
2 files changed, 43 insertions, 17 deletions
diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 70567998..38ef32d5 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1083,18 +1083,36 @@ ASTPointer<EmitStatement> Parser::parseEmitStatement(ASTPointer<ASTString> const ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& _docString) { 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: - // 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. // As an extension, we can even have: // `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. - switch (peekStatementType()) + + auto statementType = peekStatementType(); + switch (statementType) { - case LookAheadInfo::VariableDeclarationStatement: - return parseVariableDeclarationStatement(_docString); - case LookAheadInfo::ExpressionStatement: - return parseExpressionStatement(_docString); + case LookAheadInfo::VariableDeclaration: + case LookAheadInfo::Expression: + return make_pair(statementType, IndexAccessedPath()); default: break; } @@ -1106,9 +1124,9 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& IndexAccessedPath iap = parseIndexAccessedPath(); if (m_scanner->currentToken() == Token::Identifier || Token::isLocationSpecifier(m_scanner->currentToken())) - return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap)); + return make_pair(LookAheadInfo::VariableDeclaration, move(iap)); else - return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap)); + return make_pair(LookAheadInfo::Expression, move(iap)); } ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement( @@ -1489,16 +1507,16 @@ Parser::LookAheadInfo Parser::peekStatementType() const bool mightBeTypeName = (Token::isElementaryTypeName(token) || token == Token::Identifier); if (token == Token::Mapping || token == Token::Function || token == Token::Var) - return LookAheadInfo::VariableDeclarationStatement; + return LookAheadInfo::VariableDeclaration; if (mightBeTypeName) { Token::Value next = m_scanner->peekNextToken(); if (next == Token::Identifier || Token::isLocationSpecifier(next)) - return LookAheadInfo::VariableDeclarationStatement; + return LookAheadInfo::VariableDeclaration; if (next == Token::LBrack || next == Token::Period) return LookAheadInfo::IndexAccessStructure; } - return LookAheadInfo::ExpressionStatement; + return LookAheadInfo::Expression; } Parser::IndexAccessedPath Parser::parseIndexAccessedPath() @@ -1539,7 +1557,9 @@ Parser::IndexAccessedPath Parser::parseIndexAccessedPath() ASTPointer<TypeName> Parser::typeNameFromIndexAccessStructure(Parser::IndexAccessedPath const& _iap) { - solAssert(!_iap.path.empty(), ""); + if (_iap.empty()) + return {}; + RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this); SourceLocation location = _iap.path.front()->location(); @@ -1571,7 +1591,9 @@ ASTPointer<Expression> Parser::expressionFromIndexAccessStructure( Parser::IndexAccessedPath const& _iap ) { - solAssert(!_iap.path.empty(), ""); + if (_iap.empty()) + return {}; + RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this, _iap.path.front()); ASTPointer<Expression> expression(_iap.path.front()); diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 7a1a390e..902312e8 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -143,16 +143,18 @@ private: /// Used as return value of @see peekStatementType. 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 - /// 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 { std::vector<ASTPointer<PrimaryExpression>> path; 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. /// For source code of the form "a[][8]" ("IndexAccessStructure"), this is not possible to /// decide with constant look-ahead. @@ -160,9 +162,11 @@ private: /// @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]", + /// or an empty pointer if an empty @a _pathAndIncides has been supplied. 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<ASTString> expectIdentifierToken(); |