#pragma once
#include <libsolidity/ast/AST.h>
#include <liblangutil/ParserBase.h>
#include <liblangutil/EVMVersion.h>
namespace solidity::langutil
{
class CharStream;
}
namespace solidity::frontend
{
class Parser: public langutil::ParserBase
{
public:
explicit Parser(
langutil::ErrorReporter& _errorReporter,
langutil::EVMVersion _evmVersion,
bool _errorRecovery = false
):
ParserBase(_errorReporter, _errorRecovery),
m_evmVersion(_evmVersion)
{}
ASTPointer<SourceUnit> parse(langutil::CharStream& _charStream);
private:
class ASTNodeFactory;
enum class VarDeclKind { FileLevel, State, Other };
struct VarDeclParserOptions
{
VarDeclParserOptions() {}
VarDeclKind kind = VarDeclKind::Other;
bool allowIndexed = false;
bool allowEmptyName = false;
bool allowInitialValue = false;
bool allowLocationSpecifier = false;
};
struct FunctionHeaderParserResult
{
bool isVirtual = false;
ASTPointer<OverrideSpecifier> overrides;
ASTPointer<ParameterList> parameters;
ASTPointer<ParameterList> returnParameters;
Visibility visibility = Visibility::Default;
StateMutability stateMutability = StateMutability::NonPayable;
std::vector<ASTPointer<ModifierInvocation>> modifiers;
};
void parsePragmaVersion(langutil::SourceLocation const& _location, std::vector<Token> const& _tokens, std::vector<std::string> const& _literals);
ASTPointer<StructuredDocumentation> parseStructuredDocumentation();
ASTPointer<PragmaDirective> parsePragmaDirective();
ASTPointer<ImportDirective> parseImportDirective();
std::pair<ContractKind, bool> parseContractKind();
ASTPointer<ContractDefinition> parseContractDefinition();
ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier();
Visibility parseVisibilitySpecifier();
ASTPointer<OverrideSpecifier> parseOverrideSpecifier();
StateMutability parseStateMutability();
FunctionHeaderParserResult parseFunctionHeader(bool _isStateVariable);
ASTPointer<ASTNode> parseFunctionDefinition(bool _freeFunction = false);
ASTPointer<StructDefinition> parseStructDefinition();
ASTPointer<EnumDefinition> parseEnumDefinition();
ASTPointer<UserDefinedValueTypeDefinition> parseUserDefinedValueTypeDefinition();
ASTPointer<EnumValue> parseEnumValue();
ASTPointer<VariableDeclaration> parseVariableDeclaration(
VarDeclParserOptions const& _options = {},
ASTPointer<TypeName> const& _lookAheadArrayType = ASTPointer<TypeName>()
);
ASTPointer<ModifierDefinition> parseModifierDefinition();
ASTPointer<EventDefinition> parseEventDefinition();
ASTPointer<ErrorDefinition> parseErrorDefinition();
ASTPointer<UsingForDirective> parseUsingDirective();
ASTPointer<ModifierInvocation> parseModifierInvocation();
ASTPointer<Identifier> parseIdentifier();
ASTPointer<Identifier> parseIdentifierOrAddress();
ASTPointer<UserDefinedTypeName> parseUserDefinedTypeName();
ASTPointer<IdentifierPath> parseIdentifierPath();
ASTPointer<TypeName> parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory);
ASTPointer<TypeName> parseTypeName();
ASTPointer<FunctionTypeName> parseFunctionType();
ASTPointer<Mapping> parseMapping();
ASTPointer<ParameterList> parseParameterList(
VarDeclParserOptions const& _options = {},
bool _allowEmpty = true
);
ASTPointer<Block> parseBlock(bool _allowUncheckedBlock = false, ASTPointer<ASTString> const& _docString = {});
ASTPointer<Statement> parseStatement(bool _allowUncheckedBlock = false);
ASTPointer<InlineAssembly> parseInlineAssembly(ASTPointer<ASTString> const& _docString = {});
ASTPointer<IfStatement> parseIfStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<TryStatement> parseTryStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<TryCatchClause> parseCatchClause();
ASTPointer<WhileStatement> parseWhileStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<WhileStatement> parseDoWhileStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<ForStatement> parseForStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<EmitStatement> parseEmitStatement(ASTPointer<ASTString> const& docString);
ASTPointer<RevertStatement> parseRevertStatement(ASTPointer<ASTString> const& docString);
ASTPointer<Statement> parseSimpleStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<VariableDeclarationStatement> parseVariableDeclarationStatement(
ASTPointer<ASTString> const& _docString,
ASTPointer<TypeName> const& _lookAheadArrayType = ASTPointer<TypeName>()
);
ASTPointer<ExpressionStatement> parseExpressionStatement(
ASTPointer<ASTString> const& _docString,
ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
);
ASTPointer<Expression> parseExpression(
ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
);
ASTPointer<Expression> parseBinaryExpression(int _minPrecedence = 4,
ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
);
ASTPointer<Expression> parseUnaryExpression(
ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
);
ASTPointer<Expression> parseLeftHandSideExpression(
ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
);
ASTPointer<Expression> parsePrimaryExpression();
std::vector<ASTPointer<Expression>> parseFunctionCallListArguments();
std::pair<std::vector<ASTPointer<Expression>>, std::vector<ASTPointer<ASTString>>> parseFunctionCallArguments();
std::pair<std::vector<ASTPointer<Expression>>, std::vector<ASTPointer<ASTString>>> parseNamedArguments();
std::pair<ASTPointer<ASTString>, langutil::SourceLocation> expectIdentifierWithLocation();
bool variableDeclarationStart();
enum class LookAheadInfo
{
IndexAccessStructure, VariableDeclaration, Expression
};
struct IndexAccessedPath
{
struct Index
{
ASTPointer<Expression> start;
std::optional<ASTPointer<Expression>> end;
langutil::SourceLocation location;
};
std::vector<ASTPointer<PrimaryExpression>> path;
std::vector<Index> indices;
bool empty() const;
};
std::optional<std::string> findLicenseString(std::vector<ASTPointer<ASTNode>> const& _nodes);
int64_t nextID() { return ++m_currentNodeID; }
std::pair<LookAheadInfo, IndexAccessedPath> tryParseIndexAccessedPath();
LookAheadInfo peekStatementType() const;
IndexAccessedPath parseIndexAccessedPath();
ASTPointer<TypeName> typeNameFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
ASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
ASTPointer<ASTString> expectIdentifierToken();
ASTPointer<ASTString> expectIdentifierTokenOrAddress();
ASTPointer<ASTString> getLiteralAndAdvance();
ASTPointer<ParameterList> createEmptyParameterList();
bool m_insideModifier = false;
langutil::EVMVersion m_evmVersion;
int64_t m_currentNodeID = 0;
};
}