1 /*
2 	This file is part of solidity.
3 
4 	solidity is free software: you can redistribute it and/or modify
5 	it under the terms of the GNU General Public License as published by
6 	the Free Software Foundation, either version 3 of the License, or
7 	(at your option) any later version.
8 
9 	solidity is distributed in the hope that it will be useful,
10 	but WITHOUT ANY WARRANTY; without even the implied warranty of
11 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 	GNU General Public License for more details.
13 
14 	You should have received a copy of the GNU General Public License
15 	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 // SPDX-License-Identifier: GPL-3.0
18 /**
19  * @author Christian <c@ethdev.com>
20  * @date 2014
21  * Solidity parser.
22  */
23 
24 #pragma once
25 
26 #include <libsolidity/ast/AST.h>
27 #include <liblangutil/ParserBase.h>
28 #include <liblangutil/EVMVersion.h>
29 
30 namespace solidity::langutil
31 {
32 class CharStream;
33 }
34 
35 namespace solidity::frontend
36 {
37 
38 class Parser: public langutil::ParserBase
39 {
40 public:
41 	explicit Parser(
42 		langutil::ErrorReporter& _errorReporter,
43 		langutil::EVMVersion _evmVersion,
44 		bool _errorRecovery = false
45 	):
ParserBase(_errorReporter,_errorRecovery)46 		ParserBase(_errorReporter, _errorRecovery),
47 		m_evmVersion(_evmVersion)
48 	{}
49 
50 	ASTPointer<SourceUnit> parse(langutil::CharStream& _charStream);
51 
52 private:
53 	class ASTNodeFactory;
54 
55 	enum class VarDeclKind { FileLevel, State, Other };
56 	struct VarDeclParserOptions
57 	{
58 		// This is actually not needed, but due to a defect in the C++ standard, we have to.
59 		// https://stackoverflow.com/questions/17430377
VarDeclParserOptionsVarDeclParserOptions60 		VarDeclParserOptions() {}
61 		VarDeclKind kind = VarDeclKind::Other;
62 		bool allowIndexed = false;
63 		bool allowEmptyName = false;
64 		bool allowInitialValue = false;
65 		bool allowLocationSpecifier = false;
66 	};
67 
68 	/// This struct is shared for parsing a function header and a function type.
69 	struct FunctionHeaderParserResult
70 	{
71 		bool isVirtual = false;
72 		ASTPointer<OverrideSpecifier> overrides;
73 		ASTPointer<ParameterList> parameters;
74 		ASTPointer<ParameterList> returnParameters;
75 		Visibility visibility = Visibility::Default;
76 		StateMutability stateMutability = StateMutability::NonPayable;
77 		std::vector<ASTPointer<ModifierInvocation>> modifiers;
78 	};
79 
80 	///@{
81 	///@name Parsing functions for the AST nodes
82 	void parsePragmaVersion(langutil::SourceLocation const& _location, std::vector<Token> const& _tokens, std::vector<std::string> const& _literals);
83 	ASTPointer<StructuredDocumentation> parseStructuredDocumentation();
84 	ASTPointer<PragmaDirective> parsePragmaDirective();
85 	ASTPointer<ImportDirective> parseImportDirective();
86 	/// @returns an std::pair<ContractKind, bool>, where
87 	/// result.second is set to true, if an abstract contract was parsed, false otherwise.
88 	std::pair<ContractKind, bool> parseContractKind();
89 	ASTPointer<ContractDefinition> parseContractDefinition();
90 	ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier();
91 	Visibility parseVisibilitySpecifier();
92 	ASTPointer<OverrideSpecifier> parseOverrideSpecifier();
93 	StateMutability parseStateMutability();
94 	FunctionHeaderParserResult parseFunctionHeader(bool _isStateVariable);
95 	ASTPointer<ASTNode> parseFunctionDefinition(bool _freeFunction = false);
96 	ASTPointer<StructDefinition> parseStructDefinition();
97 	ASTPointer<EnumDefinition> parseEnumDefinition();
98 	ASTPointer<UserDefinedValueTypeDefinition> parseUserDefinedValueTypeDefinition();
99 	ASTPointer<EnumValue> parseEnumValue();
100 	ASTPointer<VariableDeclaration> parseVariableDeclaration(
101 		VarDeclParserOptions const& _options = {},
102 		ASTPointer<TypeName> const& _lookAheadArrayType = ASTPointer<TypeName>()
103 	);
104 	ASTPointer<ModifierDefinition> parseModifierDefinition();
105 	ASTPointer<EventDefinition> parseEventDefinition();
106 	ASTPointer<ErrorDefinition> parseErrorDefinition();
107 	ASTPointer<UsingForDirective> parseUsingDirective();
108 	ASTPointer<ModifierInvocation> parseModifierInvocation();
109 	ASTPointer<Identifier> parseIdentifier();
110 	ASTPointer<Identifier> parseIdentifierOrAddress();
111 	ASTPointer<UserDefinedTypeName> parseUserDefinedTypeName();
112 	ASTPointer<IdentifierPath> parseIdentifierPath();
113 	ASTPointer<TypeName> parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory);
114 	ASTPointer<TypeName> parseTypeName();
115 	ASTPointer<FunctionTypeName> parseFunctionType();
116 	ASTPointer<Mapping> parseMapping();
117 	ASTPointer<ParameterList> parseParameterList(
118 		VarDeclParserOptions const& _options = {},
119 		bool _allowEmpty = true
120 	);
121 	ASTPointer<Block> parseBlock(bool _allowUncheckedBlock = false, ASTPointer<ASTString> const& _docString = {});
122 	ASTPointer<Statement> parseStatement(bool _allowUncheckedBlock = false);
123 	ASTPointer<InlineAssembly> parseInlineAssembly(ASTPointer<ASTString> const& _docString = {});
124 	ASTPointer<IfStatement> parseIfStatement(ASTPointer<ASTString> const& _docString);
125 	ASTPointer<TryStatement> parseTryStatement(ASTPointer<ASTString> const& _docString);
126 	ASTPointer<TryCatchClause> parseCatchClause();
127 	ASTPointer<WhileStatement> parseWhileStatement(ASTPointer<ASTString> const& _docString);
128 	ASTPointer<WhileStatement> parseDoWhileStatement(ASTPointer<ASTString> const& _docString);
129 	ASTPointer<ForStatement> parseForStatement(ASTPointer<ASTString> const& _docString);
130 	ASTPointer<EmitStatement> parseEmitStatement(ASTPointer<ASTString> const& docString);
131 	ASTPointer<RevertStatement> parseRevertStatement(ASTPointer<ASTString> const& docString);
132 	/// A "simple statement" can be a variable declaration statement or an expression statement.
133 	ASTPointer<Statement> parseSimpleStatement(ASTPointer<ASTString> const& _docString);
134 	ASTPointer<VariableDeclarationStatement> parseVariableDeclarationStatement(
135 		ASTPointer<ASTString> const& _docString,
136 		ASTPointer<TypeName> const& _lookAheadArrayType = ASTPointer<TypeName>()
137 	);
138 	ASTPointer<ExpressionStatement> parseExpressionStatement(
139 		ASTPointer<ASTString> const& _docString,
140 		ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
141 	);
142 	ASTPointer<Expression> parseExpression(
143 		ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
144 	);
145 	ASTPointer<Expression> parseBinaryExpression(int _minPrecedence = 4,
146 		ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
147 	);
148 	ASTPointer<Expression> parseUnaryExpression(
149 		ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
150 	);
151 	ASTPointer<Expression> parseLeftHandSideExpression(
152 		ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()
153 	);
154 	ASTPointer<Expression> parsePrimaryExpression();
155 	std::vector<ASTPointer<Expression>> parseFunctionCallListArguments();
156 	std::pair<std::vector<ASTPointer<Expression>>, std::vector<ASTPointer<ASTString>>> parseFunctionCallArguments();
157 	std::pair<std::vector<ASTPointer<Expression>>, std::vector<ASTPointer<ASTString>>> parseNamedArguments();
158 	std::pair<ASTPointer<ASTString>, langutil::SourceLocation> expectIdentifierWithLocation();
159 	///@}
160 
161 	///@{
162 	///@name Helper functions
163 
164 	/// @return true if we are at the start of a variable declaration.
165 	bool variableDeclarationStart();
166 
167 	/// Used as return value of @see peekStatementType.
168 	enum class LookAheadInfo
169 	{
170 		IndexAccessStructure, VariableDeclaration, Expression
171 	};
172 	/// Structure that represents a.b.c[x][y][z]. Can be converted either to an expression
173 	/// or to a type name. For this to be valid, path cannot be empty, but indices can be empty.
174 	struct IndexAccessedPath
175 	{
176 		struct Index
177 		{
178 			ASTPointer<Expression> start;
179 			std::optional<ASTPointer<Expression>> end;
180 			langutil::SourceLocation location;
181 		};
182 		std::vector<ASTPointer<PrimaryExpression>> path;
183 		std::vector<Index> indices;
184 		bool empty() const;
185 	};
186 
187 	std::optional<std::string> findLicenseString(std::vector<ASTPointer<ASTNode>> const& _nodes);
188 
189 	/// Returns the next AST node ID
nextID()190 	int64_t nextID() { return ++m_currentNodeID; }
191 
192 	std::pair<LookAheadInfo, IndexAccessedPath> tryParseIndexAccessedPath();
193 	/// Performs limited look-ahead to distinguish between variable declaration and expression statement.
194 	/// For source code of the form "a[][8]" ("IndexAccessStructure"), this is not possible to
195 	/// decide with constant look-ahead.
196 	LookAheadInfo peekStatementType() const;
197 	/// @returns an IndexAccessedPath as a prestage to parsing a variable declaration (type name)
198 	/// or an expression;
199 	IndexAccessedPath parseIndexAccessedPath();
200 	/// @returns a typename parsed in look-ahead fashion from something like "a.b[8][2**70]",
201 	/// or an empty pointer if an empty @a _pathAndIncides has been supplied.
202 	ASTPointer<TypeName> typeNameFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
203 	/// @returns an expression parsed in look-ahead fashion from something like "a.b[8][2**70]",
204 	/// or an empty pointer if an empty @a _pathAndIncides has been supplied.
205 	ASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
206 
207 	ASTPointer<ASTString> expectIdentifierToken();
208 	ASTPointer<ASTString> expectIdentifierTokenOrAddress();
209 	ASTPointer<ASTString> getLiteralAndAdvance();
210 	///@}
211 
212 	/// Creates an empty ParameterList at the current location (used if parameters can be omitted).
213 	ASTPointer<ParameterList> createEmptyParameterList();
214 
215 	/// Flag that signifies whether '_' is parsed as a PlaceholderStatement or a regular identifier.
216 	bool m_insideModifier = false;
217 	langutil::EVMVersion m_evmVersion;
218 	/// Counter for the next AST node ID
219 	int64_t m_currentNodeID = 0;
220 };
221 
222 }
223