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 #include <libsolidity/parsing/Parser.h>
25
26 #include <libsolidity/interface/Version.h>
27 #include <libyul/AST.h>
28 #include <libyul/AsmParser.h>
29 #include <libyul/backends/evm/EVMDialect.h>
30 #include <liblangutil/ErrorReporter.h>
31 #include <liblangutil/Scanner.h>
32 #include <liblangutil/SemVerHandler.h>
33 #include <liblangutil/SourceLocation.h>
34 #include <libyul/backends/evm/EVMDialect.h>
35 #include <boost/algorithm/string/trim.hpp>
36 #include <boost/algorithm/string/replace.hpp>
37 #include <boost/algorithm/string/predicate.hpp>
38 #include <cctype>
39 #include <vector>
40 #include <regex>
41
42 using namespace std;
43 using namespace solidity::langutil;
44
45 namespace solidity::frontend
46 {
47
48 /// AST node factory that also tracks the begin and end position of an AST node
49 /// while it is being parsed
50 class Parser::ASTNodeFactory
51 {
52 public:
ASTNodeFactory(Parser & _parser)53 explicit ASTNodeFactory(Parser& _parser):
54 m_parser(_parser), m_location{
55 _parser.currentLocation().start,
56 -1,
57 _parser.currentLocation().sourceName
58 }
59 {}
ASTNodeFactory(Parser & _parser,ASTPointer<ASTNode> const & _childNode)60 ASTNodeFactory(Parser& _parser, ASTPointer<ASTNode> const& _childNode):
61 m_parser(_parser), m_location{_childNode->location()} {}
62
markEndPosition()63 void markEndPosition() { m_location.end = m_parser.currentLocation().end; }
setLocation(SourceLocation const & _location)64 void setLocation(SourceLocation const& _location) { m_location = _location; }
setLocationEmpty()65 void setLocationEmpty() { m_location.end = m_location.start; }
66 /// Set the end position to the one of the given node.
setEndPositionFromNode(ASTPointer<ASTNode> const & _node)67 void setEndPositionFromNode(ASTPointer<ASTNode> const& _node) { m_location.end = _node->location().end; }
68
69 template <class NodeType, typename... Args>
createNode(Args &&..._args)70 ASTPointer<NodeType> createNode(Args&& ... _args)
71 {
72 solAssert(m_location.sourceName, "");
73 if (m_location.end < 0)
74 markEndPosition();
75 return make_shared<NodeType>(m_parser.nextID(), m_location, std::forward<Args>(_args)...);
76 }
77
location() const78 SourceLocation const& location() const noexcept { return m_location; }
79
80 private:
81 Parser& m_parser;
82 SourceLocation m_location;
83 };
84
parse(CharStream & _charStream)85 ASTPointer<SourceUnit> Parser::parse(CharStream& _charStream)
86 {
87 solAssert(!m_insideModifier, "");
88 try
89 {
90 m_recursionDepth = 0;
91 m_scanner = make_shared<Scanner>(_charStream);
92 ASTNodeFactory nodeFactory(*this);
93
94 vector<ASTPointer<ASTNode>> nodes;
95 while (m_scanner->currentToken() != Token::EOS)
96 {
97 switch (m_scanner->currentToken())
98 {
99 case Token::Pragma:
100 nodes.push_back(parsePragmaDirective());
101 break;
102 case Token::Import:
103 nodes.push_back(parseImportDirective());
104 break;
105 case Token::Abstract:
106 case Token::Interface:
107 case Token::Contract:
108 case Token::Library:
109 nodes.push_back(parseContractDefinition());
110 break;
111 case Token::Struct:
112 nodes.push_back(parseStructDefinition());
113 break;
114 case Token::Enum:
115 nodes.push_back(parseEnumDefinition());
116 break;
117 case Token::Type:
118 nodes.push_back(parseUserDefinedValueTypeDefinition());
119 break;
120 case Token::Function:
121 nodes.push_back(parseFunctionDefinition(true));
122 break;
123 default:
124 if (
125 // Workaround because `error` is not a keyword.
126 m_scanner->currentToken() == Token::Identifier &&
127 currentLiteral() == "error" &&
128 m_scanner->peekNextToken() == Token::Identifier &&
129 m_scanner->peekNextNextToken() == Token::LParen
130 )
131 nodes.push_back(parseErrorDefinition());
132 // Constant variable.
133 else if (variableDeclarationStart() && m_scanner->peekNextToken() != Token::EOS)
134 {
135 VarDeclParserOptions options;
136 options.kind = VarDeclKind::FileLevel;
137 options.allowInitialValue = true;
138 nodes.push_back(parseVariableDeclaration(options));
139 expectToken(Token::Semicolon);
140 }
141 else
142 fatalParserError(7858_error, "Expected pragma, import directive or contract/interface/library/struct/enum/constant/function definition.");
143 }
144 }
145 solAssert(m_recursionDepth == 0, "");
146 return nodeFactory.createNode<SourceUnit>(findLicenseString(nodes), nodes);
147 }
148 catch (FatalError const&)
149 {
150 if (m_errorReporter.errors().empty())
151 throw; // Something is weird here, rather throw again.
152 return nullptr;
153 }
154 }
155
parsePragmaVersion(SourceLocation const & _location,vector<Token> const & _tokens,vector<string> const & _literals)156 void Parser::parsePragmaVersion(SourceLocation const& _location, vector<Token> const& _tokens, vector<string> const& _literals)
157 {
158 SemVerMatchExpressionParser parser(_tokens, _literals);
159 auto matchExpression = parser.parse();
160 if (!matchExpression.has_value())
161 m_errorReporter.fatalParserError(
162 1684_error,
163 _location,
164 "Found version pragma, but failed to parse it. "
165 "Please ensure there is a trailing semicolon."
166 );
167 static SemVerVersion const currentVersion{string(VersionString)};
168 // FIXME: only match for major version incompatibility
169 if (!matchExpression->matches(currentVersion))
170 // If m_parserErrorRecovery is true, the same message will appear from SyntaxChecker::visit(),
171 // so we don't need to report anything here.
172 if (!m_parserErrorRecovery)
173 m_errorReporter.fatalParserError(
174 5333_error,
175 _location,
176 "Source file requires different compiler version (current compiler is " +
177 string(VersionString) + ") - note that nightly builds are considered to be "
178 "strictly less than the released version"
179 );
180 }
181
parseStructuredDocumentation()182 ASTPointer<StructuredDocumentation> Parser::parseStructuredDocumentation()
183 {
184 if (m_scanner->currentCommentLiteral() != "")
185 {
186 ASTNodeFactory nodeFactory{*this};
187 nodeFactory.setLocation(m_scanner->currentCommentLocation());
188 return nodeFactory.createNode<StructuredDocumentation>(
189 make_shared<ASTString>(m_scanner->currentCommentLiteral())
190 );
191 }
192 return nullptr;
193 }
194
parsePragmaDirective()195 ASTPointer<PragmaDirective> Parser::parsePragmaDirective()
196 {
197 RecursionGuard recursionGuard(*this);
198 // pragma anything* ;
199 // Currently supported:
200 // pragma solidity ^0.4.0 || ^0.3.0;
201 ASTNodeFactory nodeFactory(*this);
202 expectToken(Token::Pragma);
203 vector<string> literals;
204 vector<Token> tokens;
205 do
206 {
207 Token token = m_scanner->currentToken();
208 if (token == Token::Illegal)
209 parserError(6281_error, "Token incompatible with Solidity parser as part of pragma directive.");
210 else
211 {
212 string literal = m_scanner->currentLiteral();
213 if (literal.empty() && TokenTraits::toString(token))
214 literal = TokenTraits::toString(token);
215 literals.push_back(literal);
216 tokens.push_back(token);
217 }
218 advance();
219 }
220 while (m_scanner->currentToken() != Token::Semicolon && m_scanner->currentToken() != Token::EOS);
221 nodeFactory.markEndPosition();
222 expectToken(Token::Semicolon);
223
224 if (literals.size() >= 1 && literals[0] == "solidity")
225 {
226 parsePragmaVersion(
227 nodeFactory.location(),
228 vector<Token>(tokens.begin() + 1, tokens.end()),
229 vector<string>(literals.begin() + 1, literals.end())
230 );
231 }
232
233 return nodeFactory.createNode<PragmaDirective>(tokens, literals);
234 }
235
parseImportDirective()236 ASTPointer<ImportDirective> Parser::parseImportDirective()
237 {
238 RecursionGuard recursionGuard(*this);
239 // import "abc" [as x];
240 // import * as x from "abc";
241 // import {a as b, c} from "abc";
242 ASTNodeFactory nodeFactory(*this);
243 expectToken(Token::Import);
244 ASTPointer<ASTString> path;
245 ASTPointer<ASTString> unitAlias = make_shared<string>();
246 SourceLocation unitAliasLocation{};
247 ImportDirective::SymbolAliasList symbolAliases;
248
249 if (m_scanner->currentToken() == Token::StringLiteral)
250 {
251 path = getLiteralAndAdvance();
252 if (m_scanner->currentToken() == Token::As)
253 {
254 advance();
255 tie(unitAlias, unitAliasLocation) = expectIdentifierWithLocation();
256 }
257 }
258 else
259 {
260 if (m_scanner->currentToken() == Token::LBrace)
261 {
262 advance();
263 while (true)
264 {
265 ASTPointer<ASTString> alias;
266 SourceLocation aliasLocation = currentLocation();
267 ASTPointer<Identifier> id = parseIdentifier();
268 if (m_scanner->currentToken() == Token::As)
269 {
270 expectToken(Token::As);
271 tie(alias, aliasLocation) = expectIdentifierWithLocation();
272 }
273 symbolAliases.emplace_back(ImportDirective::SymbolAlias{move(id), move(alias), aliasLocation});
274 if (m_scanner->currentToken() != Token::Comma)
275 break;
276 advance();
277 }
278 expectToken(Token::RBrace);
279 }
280 else if (m_scanner->currentToken() == Token::Mul)
281 {
282 advance();
283 expectToken(Token::As);
284 tie(unitAlias, unitAliasLocation) = expectIdentifierWithLocation();
285 }
286 else
287 fatalParserError(9478_error, "Expected string literal (path), \"*\" or alias list.");
288 // "from" is not a keyword but parsed as an identifier because of backwards
289 // compatibility and because it is a really common word.
290 if (m_scanner->currentToken() != Token::Identifier || m_scanner->currentLiteral() != "from")
291 fatalParserError(8208_error, "Expected \"from\".");
292 advance();
293 if (m_scanner->currentToken() != Token::StringLiteral)
294 fatalParserError(6845_error, "Expected import path.");
295 path = getLiteralAndAdvance();
296 }
297 if (path->empty())
298 fatalParserError(6326_error, "Import path cannot be empty.");
299 nodeFactory.markEndPosition();
300 expectToken(Token::Semicolon);
301 return nodeFactory.createNode<ImportDirective>(path, unitAlias, unitAliasLocation, move(symbolAliases));
302 }
303
parseContractKind()304 std::pair<ContractKind, bool> Parser::parseContractKind()
305 {
306 ContractKind kind;
307 bool abstract = false;
308 if (m_scanner->currentToken() == Token::Abstract)
309 {
310 abstract = true;
311 advance();
312 }
313 switch (m_scanner->currentToken())
314 {
315 case Token::Interface:
316 kind = ContractKind::Interface;
317 break;
318 case Token::Contract:
319 kind = ContractKind::Contract;
320 break;
321 case Token::Library:
322 kind = ContractKind::Library;
323 break;
324 default:
325 parserError(3515_error, "Expected keyword \"contract\", \"interface\" or \"library\".");
326 return std::make_pair(ContractKind::Contract, abstract);
327 }
328 advance();
329 return std::make_pair(kind, abstract);
330 }
331
parseContractDefinition()332 ASTPointer<ContractDefinition> Parser::parseContractDefinition()
333 {
334 RecursionGuard recursionGuard(*this);
335 ASTNodeFactory nodeFactory(*this);
336 ASTPointer<ASTString> name = nullptr;
337 SourceLocation nameLocation{};
338 ASTPointer<StructuredDocumentation> documentation;
339 vector<ASTPointer<InheritanceSpecifier>> baseContracts;
340 vector<ASTPointer<ASTNode>> subNodes;
341 std::pair<ContractKind, bool> contractKind{};
342 try
343 {
344 documentation = parseStructuredDocumentation();
345 contractKind = parseContractKind();
346 tie(name, nameLocation) = expectIdentifierWithLocation();
347 if (m_scanner->currentToken() == Token::Is)
348 do
349 {
350 advance();
351 baseContracts.push_back(parseInheritanceSpecifier());
352 }
353 while (m_scanner->currentToken() == Token::Comma);
354 expectToken(Token::LBrace);
355 while (true)
356 {
357 Token currentTokenValue = m_scanner->currentToken();
358 if (currentTokenValue == Token::RBrace)
359 break;
360 else if (
361 (currentTokenValue == Token::Function && m_scanner->peekNextToken() != Token::LParen) ||
362 currentTokenValue == Token::Constructor ||
363 currentTokenValue == Token::Receive ||
364 currentTokenValue == Token::Fallback
365 )
366 subNodes.push_back(parseFunctionDefinition());
367 else if (currentTokenValue == Token::Struct)
368 subNodes.push_back(parseStructDefinition());
369 else if (currentTokenValue == Token::Enum)
370 subNodes.push_back(parseEnumDefinition());
371 else if (currentTokenValue == Token::Type)
372 subNodes.push_back(parseUserDefinedValueTypeDefinition());
373 else if (
374 // Workaround because `error` is not a keyword.
375 currentTokenValue == Token::Identifier &&
376 currentLiteral() == "error" &&
377 m_scanner->peekNextToken() == Token::Identifier &&
378 m_scanner->peekNextNextToken() == Token::LParen
379 )
380 subNodes.push_back(parseErrorDefinition());
381 else if (variableDeclarationStart())
382 {
383 VarDeclParserOptions options;
384 options.kind = VarDeclKind::State;
385 options.allowInitialValue = true;
386 subNodes.push_back(parseVariableDeclaration(options));
387 expectToken(Token::Semicolon);
388 }
389 else if (currentTokenValue == Token::Modifier)
390 subNodes.push_back(parseModifierDefinition());
391 else if (currentTokenValue == Token::Event)
392 subNodes.push_back(parseEventDefinition());
393 else if (currentTokenValue == Token::Using)
394 subNodes.push_back(parseUsingDirective());
395 else
396 fatalParserError(9182_error, "Function, variable, struct or modifier declaration expected.");
397 }
398 }
399 catch (FatalError const&)
400 {
401 if (
402 !m_errorReporter.hasErrors() ||
403 !m_parserErrorRecovery ||
404 m_errorReporter.hasExcessiveErrors()
405 )
406 BOOST_THROW_EXCEPTION(FatalError()); /* Don't try to recover here. */
407 m_inParserRecovery = true;
408 }
409 nodeFactory.markEndPosition();
410 if (m_inParserRecovery)
411 expectTokenOrConsumeUntil(Token::RBrace, "ContractDefinition");
412 else
413 expectToken(Token::RBrace);
414 return nodeFactory.createNode<ContractDefinition>(
415 name,
416 nameLocation,
417 documentation,
418 baseContracts,
419 subNodes,
420 contractKind.first,
421 contractKind.second
422 );
423 }
424
parseInheritanceSpecifier()425 ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()
426 {
427 RecursionGuard recursionGuard(*this);
428 ASTNodeFactory nodeFactory(*this);
429 ASTPointer<IdentifierPath> name(parseIdentifierPath());
430 unique_ptr<vector<ASTPointer<Expression>>> arguments;
431 if (m_scanner->currentToken() == Token::LParen)
432 {
433 advance();
434 arguments = make_unique<vector<ASTPointer<Expression>>>(parseFunctionCallListArguments());
435 nodeFactory.markEndPosition();
436 expectToken(Token::RParen);
437 }
438 else
439 nodeFactory.setEndPositionFromNode(name);
440 return nodeFactory.createNode<InheritanceSpecifier>(name, std::move(arguments));
441 }
442
parseVisibilitySpecifier()443 Visibility Parser::parseVisibilitySpecifier()
444 {
445 Visibility visibility(Visibility::Default);
446 Token token = m_scanner->currentToken();
447 switch (token)
448 {
449 case Token::Public:
450 visibility = Visibility::Public;
451 break;
452 case Token::Internal:
453 visibility = Visibility::Internal;
454 break;
455 case Token::Private:
456 visibility = Visibility::Private;
457 break;
458 case Token::External:
459 visibility = Visibility::External;
460 break;
461 default:
462 solAssert(false, "Invalid visibility specifier.");
463 }
464 advance();
465 return visibility;
466 }
467
parseOverrideSpecifier()468 ASTPointer<OverrideSpecifier> Parser::parseOverrideSpecifier()
469 {
470 solAssert(m_scanner->currentToken() == Token::Override, "");
471
472 ASTNodeFactory nodeFactory(*this);
473 std::vector<ASTPointer<IdentifierPath>> overrides;
474
475 nodeFactory.markEndPosition();
476 advance();
477
478 if (m_scanner->currentToken() == Token::LParen)
479 {
480 advance();
481 while (true)
482 {
483 overrides.push_back(parseIdentifierPath());
484
485 if (m_scanner->currentToken() == Token::RParen)
486 break;
487
488 expectToken(Token::Comma);
489 }
490
491 nodeFactory.markEndPosition();
492 expectToken(Token::RParen);
493 }
494
495 return nodeFactory.createNode<OverrideSpecifier>(move(overrides));
496 }
497
parseStateMutability()498 StateMutability Parser::parseStateMutability()
499 {
500 StateMutability stateMutability(StateMutability::NonPayable);
501 Token token = m_scanner->currentToken();
502 switch (token)
503 {
504 case Token::Payable:
505 stateMutability = StateMutability::Payable;
506 break;
507 case Token::View:
508 stateMutability = StateMutability::View;
509 break;
510 case Token::Pure:
511 stateMutability = StateMutability::Pure;
512 break;
513 default:
514 solAssert(false, "Invalid state mutability specifier.");
515 }
516 advance();
517 return stateMutability;
518 }
519
parseFunctionHeader(bool _isStateVariable)520 Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _isStateVariable)
521 {
522 RecursionGuard recursionGuard(*this);
523 FunctionHeaderParserResult result;
524
525 VarDeclParserOptions options;
526 options.allowLocationSpecifier = true;
527 result.parameters = parseParameterList(options);
528 while (true)
529 {
530 Token token = m_scanner->currentToken();
531 if (!_isStateVariable && token == Token::Identifier)
532 result.modifiers.push_back(parseModifierInvocation());
533 else if (TokenTraits::isVisibilitySpecifier(token))
534 {
535 if (result.visibility != Visibility::Default)
536 {
537 // There is the special case of a public state variable of function type.
538 // Detect this and return early.
539 if (_isStateVariable && (result.visibility == Visibility::External || result.visibility == Visibility::Internal))
540 break;
541 parserError(
542 9439_error,
543 "Visibility already specified as \"" +
544 Declaration::visibilityToString(result.visibility) +
545 "\"."
546 );
547 advance();
548 }
549 else
550 result.visibility = parseVisibilitySpecifier();
551 }
552 else if (TokenTraits::isStateMutabilitySpecifier(token))
553 {
554 if (result.stateMutability != StateMutability::NonPayable)
555 {
556 parserError(
557 9680_error,
558 "State mutability already specified as \"" +
559 stateMutabilityToString(result.stateMutability) +
560 "\"."
561 );
562 advance();
563 }
564 else
565 result.stateMutability = parseStateMutability();
566 }
567 else if (!_isStateVariable && token == Token::Override)
568 {
569 if (result.overrides)
570 parserError(1827_error, "Override already specified.");
571
572 result.overrides = parseOverrideSpecifier();
573 }
574 else if (!_isStateVariable && token == Token::Virtual)
575 {
576 if (result.isVirtual)
577 parserError(6879_error, "Virtual already specified.");
578
579 result.isVirtual = true;
580 advance();
581 }
582 else
583 break;
584 }
585 if (m_scanner->currentToken() == Token::Returns)
586 {
587 bool const permitEmptyParameterList = false;
588 advance();
589 result.returnParameters = parseParameterList(options, permitEmptyParameterList);
590 }
591 else
592 result.returnParameters = createEmptyParameterList();
593 return result;
594 }
595
parseFunctionDefinition(bool _freeFunction)596 ASTPointer<ASTNode> Parser::parseFunctionDefinition(bool _freeFunction)
597 {
598 RecursionGuard recursionGuard(*this);
599 ASTNodeFactory nodeFactory(*this);
600 ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();
601
602 Token kind = m_scanner->currentToken();
603 ASTPointer<ASTString> name;
604 SourceLocation nameLocation;
605 if (kind == Token::Function)
606 {
607 advance();
608 if (
609 m_scanner->currentToken() == Token::Constructor ||
610 m_scanner->currentToken() == Token::Fallback ||
611 m_scanner->currentToken() == Token::Receive
612 )
613 {
614 std::string expected = std::map<Token, std::string>{
615 {Token::Constructor, "constructor"},
616 {Token::Fallback, "fallback function"},
617 {Token::Receive, "receive function"},
618 }.at(m_scanner->currentToken());
619 nameLocation = currentLocation();
620 name = make_shared<ASTString>(TokenTraits::toString(m_scanner->currentToken()));
621 string message{
622 "This function is named \"" + *name + "\" but is not the " + expected + " of the contract. "
623 "If you intend this to be a " + expected + ", use \"" + *name + "(...) { ... }\" without "
624 "the \"function\" keyword to define it."
625 };
626 if (m_scanner->currentToken() == Token::Constructor)
627 parserError(3323_error, message);
628 else
629 parserWarning(3445_error, message);
630 advance();
631 }
632 else
633 tie(name, nameLocation) = expectIdentifierWithLocation();
634 }
635 else
636 {
637 solAssert(kind == Token::Constructor || kind == Token::Fallback || kind == Token::Receive, "");
638 advance();
639 name = make_shared<ASTString>();
640 }
641
642 FunctionHeaderParserResult header = parseFunctionHeader(false);
643
644 ASTPointer<Block> block;
645 nodeFactory.markEndPosition();
646 if (m_scanner->currentToken() == Token::Semicolon)
647 advance();
648 else
649 {
650 block = parseBlock();
651 nodeFactory.setEndPositionFromNode(block);
652 }
653 return nodeFactory.createNode<FunctionDefinition>(
654 name,
655 nameLocation,
656 header.visibility,
657 header.stateMutability,
658 _freeFunction,
659 kind,
660 header.isVirtual,
661 header.overrides,
662 documentation,
663 header.parameters,
664 header.modifiers,
665 header.returnParameters,
666 block
667 );
668 }
669
parseStructDefinition()670 ASTPointer<StructDefinition> Parser::parseStructDefinition()
671 {
672 RecursionGuard recursionGuard(*this);
673 ASTNodeFactory nodeFactory(*this);
674 expectToken(Token::Struct);
675 auto [name, nameLocation] = expectIdentifierWithLocation();
676 vector<ASTPointer<VariableDeclaration>> members;
677 expectToken(Token::LBrace);
678 while (m_scanner->currentToken() != Token::RBrace)
679 {
680 members.push_back(parseVariableDeclaration());
681 expectToken(Token::Semicolon);
682 }
683 nodeFactory.markEndPosition();
684 expectToken(Token::RBrace);
685 return nodeFactory.createNode<StructDefinition>(move(name), move(nameLocation), move(members));
686 }
687
parseEnumValue()688 ASTPointer<EnumValue> Parser::parseEnumValue()
689 {
690 RecursionGuard recursionGuard(*this);
691 ASTNodeFactory nodeFactory(*this);
692 nodeFactory.markEndPosition();
693 return nodeFactory.createNode<EnumValue>(expectIdentifierToken());
694 }
695
parseEnumDefinition()696 ASTPointer<EnumDefinition> Parser::parseEnumDefinition()
697 {
698 RecursionGuard recursionGuard(*this);
699 ASTNodeFactory nodeFactory(*this);
700 expectToken(Token::Enum);
701 auto [name, nameLocation] = expectIdentifierWithLocation();
702 vector<ASTPointer<EnumValue>> members;
703 expectToken(Token::LBrace);
704
705 while (m_scanner->currentToken() != Token::RBrace)
706 {
707 members.push_back(parseEnumValue());
708 if (m_scanner->currentToken() == Token::RBrace)
709 break;
710 expectToken(Token::Comma);
711 if (m_scanner->currentToken() != Token::Identifier)
712 fatalParserError(1612_error, "Expected identifier after ','");
713 }
714 if (members.empty())
715 parserError(3147_error, "Enum with no members is not allowed.");
716
717 nodeFactory.markEndPosition();
718 expectToken(Token::RBrace);
719 return nodeFactory.createNode<EnumDefinition>(name, nameLocation, members);
720 }
721
parseVariableDeclaration(VarDeclParserOptions const & _options,ASTPointer<TypeName> const & _lookAheadArrayType)722 ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
723 VarDeclParserOptions const& _options,
724 ASTPointer<TypeName> const& _lookAheadArrayType
725 )
726 {
727 RecursionGuard recursionGuard(*this);
728 ASTNodeFactory nodeFactory = _lookAheadArrayType ?
729 ASTNodeFactory(*this, _lookAheadArrayType) : ASTNodeFactory(*this);
730
731 ASTPointer<StructuredDocumentation> const documentation = parseStructuredDocumentation();
732 ASTPointer<TypeName> type = _lookAheadArrayType ? _lookAheadArrayType : parseTypeName();
733 nodeFactory.setEndPositionFromNode(type);
734
735 if (dynamic_cast<FunctionTypeName*>(type.get()) && _options.kind == VarDeclKind::State && m_scanner->currentToken() == Token::LBrace)
736 fatalParserError(
737 2915_error,
738 "Expected a state variable declaration. If you intended this as a fallback function "
739 "or a function to handle plain ether transactions, use the \"fallback\" keyword "
740 "or the \"receive\" keyword instead."
741 );
742
743 bool isIndexed = false;
744 VariableDeclaration::Mutability mutability = VariableDeclaration::Mutability::Mutable;
745 ASTPointer<OverrideSpecifier> overrides = nullptr;
746 Visibility visibility(Visibility::Default);
747 VariableDeclaration::Location location = VariableDeclaration::Location::Unspecified;
748 ASTPointer<ASTString> identifier;
749 SourceLocation nameLocation{};
750
751 while (true)
752 {
753 Token token = m_scanner->currentToken();
754 if (_options.kind == VarDeclKind::State && TokenTraits::isVariableVisibilitySpecifier(token))
755 {
756 nodeFactory.markEndPosition();
757 if (visibility != Visibility::Default)
758 {
759 parserError(
760 4110_error,
761 "Visibility already specified as \"" +
762 Declaration::visibilityToString(visibility) +
763 "\"."
764 );
765 advance();
766 }
767 else
768 visibility = parseVisibilitySpecifier();
769 }
770 else if (_options.kind == VarDeclKind::State && token == Token::Override)
771 {
772 if (overrides)
773 parserError(9125_error, "Override already specified.");
774
775 overrides = parseOverrideSpecifier();
776 }
777 else
778 {
779 if (_options.allowIndexed && token == Token::Indexed)
780 isIndexed = true;
781 else if (token == Token::Constant || token == Token::Immutable)
782 {
783 if (mutability != VariableDeclaration::Mutability::Mutable)
784 parserError(
785 3109_error,
786 string("Mutability already set to ") +
787 (mutability == VariableDeclaration::Mutability::Constant ? "\"constant\"" : "\"immutable\"")
788 );
789 else if (token == Token::Constant)
790 mutability = VariableDeclaration::Mutability::Constant;
791 else if (token == Token::Immutable)
792 mutability = VariableDeclaration::Mutability::Immutable;
793 }
794 else if (_options.allowLocationSpecifier && TokenTraits::isLocationSpecifier(token))
795 {
796 if (location != VariableDeclaration::Location::Unspecified)
797 parserError(3548_error, "Location already specified.");
798 else
799 {
800 switch (token)
801 {
802 case Token::Storage:
803 location = VariableDeclaration::Location::Storage;
804 break;
805 case Token::Memory:
806 location = VariableDeclaration::Location::Memory;
807 break;
808 case Token::CallData:
809 location = VariableDeclaration::Location::CallData;
810 break;
811 default:
812 solAssert(false, "Unknown data location.");
813 }
814 }
815 }
816 else
817 break;
818 nodeFactory.markEndPosition();
819 advance();
820 }
821 }
822
823 if (_options.allowEmptyName && m_scanner->currentToken() != Token::Identifier)
824 identifier = make_shared<ASTString>("");
825 else
826 {
827 nodeFactory.markEndPosition();
828 tie(identifier, nameLocation) = expectIdentifierWithLocation();
829 }
830 ASTPointer<Expression> value;
831 if (_options.allowInitialValue)
832 {
833 if (m_scanner->currentToken() == Token::Assign)
834 {
835 advance();
836 value = parseExpression();
837 nodeFactory.setEndPositionFromNode(value);
838 }
839 }
840 return nodeFactory.createNode<VariableDeclaration>(
841 type,
842 identifier,
843 nameLocation,
844 value,
845 visibility,
846 documentation,
847 isIndexed,
848 mutability,
849 overrides,
850 location
851 );
852 }
853
parseModifierDefinition()854 ASTPointer<ModifierDefinition> Parser::parseModifierDefinition()
855 {
856 RecursionGuard recursionGuard(*this);
857 ScopeGuard resetModifierFlag([this]() { m_insideModifier = false; });
858 m_insideModifier = true;
859
860 ASTNodeFactory nodeFactory(*this);
861 ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();
862
863 expectToken(Token::Modifier);
864 auto [name, nameLocation] = expectIdentifierWithLocation();
865 ASTPointer<ParameterList> parameters;
866 if (m_scanner->currentToken() == Token::LParen)
867 {
868 VarDeclParserOptions options;
869 options.allowIndexed = true;
870 options.allowLocationSpecifier = true;
871 parameters = parseParameterList(options);
872 }
873 else
874 parameters = createEmptyParameterList();
875
876 ASTPointer<OverrideSpecifier> overrides;
877 bool isVirtual = false;
878
879 while (true)
880 {
881 if (m_scanner->currentToken() == Token::Override)
882 {
883 if (overrides)
884 parserError(9102_error, "Override already specified.");
885 overrides = parseOverrideSpecifier();
886 }
887 else if (m_scanner->currentToken() == Token::Virtual)
888 {
889 if (isVirtual)
890 parserError(2662_error, "Virtual already specified.");
891
892 isVirtual = true;
893 advance();
894 }
895 else
896 break;
897 }
898
899 ASTPointer<Block> block;
900 nodeFactory.markEndPosition();
901 if (m_scanner->currentToken() != Token::Semicolon)
902 {
903 block = parseBlock();
904 nodeFactory.setEndPositionFromNode(block);
905 }
906 else
907 advance(); // just consume the ';'
908
909 return nodeFactory.createNode<ModifierDefinition>(name, nameLocation, documentation, parameters, isVirtual, overrides, block);
910 }
911
expectIdentifierWithLocation()912 pair<ASTPointer<ASTString>, SourceLocation> Parser::expectIdentifierWithLocation()
913 {
914 SourceLocation nameLocation = currentLocation();
915 ASTPointer<ASTString> name = expectIdentifierToken();
916
917 return {move(name), move(nameLocation)};
918 }
919
parseEventDefinition()920 ASTPointer<EventDefinition> Parser::parseEventDefinition()
921 {
922 RecursionGuard recursionGuard(*this);
923 ASTNodeFactory nodeFactory(*this);
924 ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();
925
926 expectToken(Token::Event);
927 auto [name, nameLocation] = expectIdentifierWithLocation();
928
929 VarDeclParserOptions options;
930 options.allowIndexed = true;
931 ASTPointer<ParameterList> parameters = parseParameterList(options);
932
933 bool anonymous = false;
934 if (m_scanner->currentToken() == Token::Anonymous)
935 {
936 anonymous = true;
937 advance();
938 }
939 nodeFactory.markEndPosition();
940 expectToken(Token::Semicolon);
941 return nodeFactory.createNode<EventDefinition>(name, nameLocation, documentation, parameters, anonymous);
942 }
943
parseErrorDefinition()944 ASTPointer<ErrorDefinition> Parser::parseErrorDefinition()
945 {
946 RecursionGuard recursionGuard(*this);
947 ASTNodeFactory nodeFactory(*this);
948 ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();
949
950 solAssert(*expectIdentifierToken() == "error", "");
951 auto&& [name, nameLocation] = expectIdentifierWithLocation();
952
953 ASTPointer<ParameterList> parameters = parseParameterList({});
954 nodeFactory.markEndPosition();
955 expectToken(Token::Semicolon);
956 return nodeFactory.createNode<ErrorDefinition>(name, move(nameLocation), documentation, parameters);
957 }
958
parseUsingDirective()959 ASTPointer<UsingForDirective> Parser::parseUsingDirective()
960 {
961 RecursionGuard recursionGuard(*this);
962 ASTNodeFactory nodeFactory(*this);
963
964 expectToken(Token::Using);
965 ASTPointer<IdentifierPath> library(parseIdentifierPath());
966 ASTPointer<TypeName> typeName;
967 expectToken(Token::For);
968 if (m_scanner->currentToken() == Token::Mul)
969 advance();
970 else
971 typeName = parseTypeName();
972 nodeFactory.markEndPosition();
973 expectToken(Token::Semicolon);
974 return nodeFactory.createNode<UsingForDirective>(library, typeName);
975 }
976
parseModifierInvocation()977 ASTPointer<ModifierInvocation> Parser::parseModifierInvocation()
978 {
979 RecursionGuard recursionGuard(*this);
980 ASTNodeFactory nodeFactory(*this);
981 ASTPointer<IdentifierPath> name(parseIdentifierPath());
982 unique_ptr<vector<ASTPointer<Expression>>> arguments;
983 if (m_scanner->currentToken() == Token::LParen)
984 {
985 advance();
986 arguments = make_unique<vector<ASTPointer<Expression>>>(parseFunctionCallListArguments());
987 nodeFactory.markEndPosition();
988 expectToken(Token::RParen);
989 }
990 else
991 nodeFactory.setEndPositionFromNode(name);
992 return nodeFactory.createNode<ModifierInvocation>(name, move(arguments));
993 }
994
parseIdentifier()995 ASTPointer<Identifier> Parser::parseIdentifier()
996 {
997 RecursionGuard recursionGuard(*this);
998 ASTNodeFactory nodeFactory(*this);
999 nodeFactory.markEndPosition();
1000 return nodeFactory.createNode<Identifier>(expectIdentifierToken());
1001 }
1002
parseIdentifierOrAddress()1003 ASTPointer<Identifier> Parser::parseIdentifierOrAddress()
1004 {
1005 RecursionGuard recursionGuard(*this);
1006 ASTNodeFactory nodeFactory(*this);
1007 nodeFactory.markEndPosition();
1008 return nodeFactory.createNode<Identifier>(expectIdentifierTokenOrAddress());
1009 }
1010
parseUserDefinedTypeName()1011 ASTPointer<UserDefinedTypeName> Parser::parseUserDefinedTypeName()
1012 {
1013 ASTNodeFactory nodeFactory(*this);
1014 ASTPointer<IdentifierPath> identifierPath = parseIdentifierPath();
1015 nodeFactory.setEndPositionFromNode(identifierPath);
1016 return nodeFactory.createNode<UserDefinedTypeName>(identifierPath);
1017 }
1018
parseUserDefinedValueTypeDefinition()1019 ASTPointer<UserDefinedValueTypeDefinition> Parser::parseUserDefinedValueTypeDefinition()
1020 {
1021 ASTNodeFactory nodeFactory(*this);
1022 expectToken(Token::Type);
1023 auto&& [name, nameLocation] = expectIdentifierWithLocation();
1024 expectToken(Token::Is);
1025 ASTPointer<TypeName> typeName = parseTypeName();
1026 nodeFactory.markEndPosition();
1027 expectToken(Token::Semicolon);
1028 return nodeFactory.createNode<UserDefinedValueTypeDefinition>(
1029 name,
1030 move(nameLocation),
1031 typeName
1032 );
1033 }
1034
parseIdentifierPath()1035 ASTPointer<IdentifierPath> Parser::parseIdentifierPath()
1036 {
1037 RecursionGuard recursionGuard(*this);
1038 ASTNodeFactory nodeFactory(*this);
1039 nodeFactory.markEndPosition();
1040 vector<ASTString> identifierPath{*expectIdentifierToken()};
1041 while (m_scanner->currentToken() == Token::Period)
1042 {
1043 advance();
1044 nodeFactory.markEndPosition();
1045 identifierPath.push_back(*expectIdentifierTokenOrAddress());
1046 }
1047 return nodeFactory.createNode<IdentifierPath>(identifierPath);
1048 }
1049
parseTypeNameSuffix(ASTPointer<TypeName> type,ASTNodeFactory & nodeFactory)1050 ASTPointer<TypeName> Parser::parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory)
1051 {
1052 RecursionGuard recursionGuard(*this);
1053 while (m_scanner->currentToken() == Token::LBrack)
1054 {
1055 advance();
1056 ASTPointer<Expression> length;
1057 if (m_scanner->currentToken() != Token::RBrack)
1058 length = parseExpression();
1059 nodeFactory.markEndPosition();
1060 expectToken(Token::RBrack);
1061 type = nodeFactory.createNode<ArrayTypeName>(type, length);
1062 }
1063 return type;
1064 }
1065
parseTypeName()1066 ASTPointer<TypeName> Parser::parseTypeName()
1067 {
1068 RecursionGuard recursionGuard(*this);
1069 ASTNodeFactory nodeFactory(*this);
1070 ASTPointer<TypeName> type;
1071 Token token = m_scanner->currentToken();
1072 if (TokenTraits::isElementaryTypeName(token))
1073 {
1074 unsigned firstSize;
1075 unsigned secondSize;
1076 tie(firstSize, secondSize) = m_scanner->currentTokenInfo();
1077 ElementaryTypeNameToken elemTypeName(token, firstSize, secondSize);
1078 ASTNodeFactory nodeFactory(*this);
1079 nodeFactory.markEndPosition();
1080 advance();
1081 auto stateMutability = elemTypeName.token() == Token::Address
1082 ? optional<StateMutability>{StateMutability::NonPayable}
1083 : nullopt;
1084 if (TokenTraits::isStateMutabilitySpecifier(m_scanner->currentToken()))
1085 {
1086 if (elemTypeName.token() == Token::Address)
1087 {
1088 nodeFactory.markEndPosition();
1089 stateMutability = parseStateMutability();
1090 }
1091 else
1092 {
1093 parserError(9106_error, "State mutability can only be specified for address types.");
1094 advance();
1095 }
1096 }
1097 type = nodeFactory.createNode<ElementaryTypeName>(elemTypeName, stateMutability);
1098 }
1099 else if (token == Token::Function)
1100 type = parseFunctionType();
1101 else if (token == Token::Mapping)
1102 type = parseMapping();
1103 else if (token == Token::Identifier)
1104 type = parseUserDefinedTypeName();
1105 else
1106 fatalParserError(3546_error, "Expected type name");
1107
1108 solAssert(type, "");
1109 // Parse "[...]" postfixes for arrays.
1110 type = parseTypeNameSuffix(type, nodeFactory);
1111
1112 return type;
1113 }
1114
parseFunctionType()1115 ASTPointer<FunctionTypeName> Parser::parseFunctionType()
1116 {
1117 RecursionGuard recursionGuard(*this);
1118 ASTNodeFactory nodeFactory(*this);
1119 expectToken(Token::Function);
1120 FunctionHeaderParserResult header = parseFunctionHeader(true);
1121 return nodeFactory.createNode<FunctionTypeName>(
1122 header.parameters,
1123 header.returnParameters,
1124 header.visibility,
1125 header.stateMutability
1126 );
1127 }
1128
parseMapping()1129 ASTPointer<Mapping> Parser::parseMapping()
1130 {
1131 RecursionGuard recursionGuard(*this);
1132 ASTNodeFactory nodeFactory(*this);
1133 expectToken(Token::Mapping);
1134 expectToken(Token::LParen);
1135 ASTPointer<TypeName> keyType;
1136 Token token = m_scanner->currentToken();
1137 unsigned firstSize;
1138 unsigned secondSize;
1139 tie(firstSize, secondSize) = m_scanner->currentTokenInfo();
1140 if (token == Token::Identifier)
1141 keyType = parseUserDefinedTypeName();
1142 else if (TokenTraits::isElementaryTypeName(token))
1143 {
1144 keyType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(
1145 ElementaryTypeNameToken{token, firstSize, secondSize}
1146 );
1147 advance();
1148 }
1149 else
1150 fatalParserError(1005_error, "Expected elementary type name or identifier for mapping key type");
1151 expectToken(Token::DoubleArrow);
1152 ASTPointer<TypeName> valueType = parseTypeName();
1153 nodeFactory.markEndPosition();
1154 expectToken(Token::RParen);
1155 return nodeFactory.createNode<Mapping>(keyType, valueType);
1156 }
1157
parseParameterList(VarDeclParserOptions const & _options,bool _allowEmpty)1158 ASTPointer<ParameterList> Parser::parseParameterList(
1159 VarDeclParserOptions const& _options,
1160 bool _allowEmpty
1161 )
1162 {
1163 RecursionGuard recursionGuard(*this);
1164 ASTNodeFactory nodeFactory(*this);
1165 vector<ASTPointer<VariableDeclaration>> parameters;
1166 VarDeclParserOptions options(_options);
1167 options.allowEmptyName = true;
1168 expectToken(Token::LParen);
1169 if (!_allowEmpty || m_scanner->currentToken() != Token::RParen)
1170 {
1171 parameters.push_back(parseVariableDeclaration(options));
1172 while (m_scanner->currentToken() != Token::RParen)
1173 {
1174 if (m_scanner->currentToken() == Token::Comma && m_scanner->peekNextToken() == Token::RParen)
1175 fatalParserError(7591_error, "Unexpected trailing comma in parameter list.");
1176 expectToken(Token::Comma);
1177 parameters.push_back(parseVariableDeclaration(options));
1178 }
1179 }
1180 nodeFactory.markEndPosition();
1181 advance();
1182 return nodeFactory.createNode<ParameterList>(parameters);
1183 }
1184
parseBlock(bool _allowUnchecked,ASTPointer<ASTString> const & _docString)1185 ASTPointer<Block> Parser::parseBlock(bool _allowUnchecked, ASTPointer<ASTString> const& _docString)
1186 {
1187 RecursionGuard recursionGuard(*this);
1188 ASTNodeFactory nodeFactory(*this);
1189 bool const unchecked = m_scanner->currentToken() == Token::Unchecked;
1190 if (unchecked)
1191 {
1192 if (!_allowUnchecked)
1193 parserError(5296_error, "\"unchecked\" blocks can only be used inside regular blocks.");
1194 advance();
1195 }
1196 expectToken(Token::LBrace);
1197 vector<ASTPointer<Statement>> statements;
1198 try
1199 {
1200 while (m_scanner->currentToken() != Token::RBrace)
1201 statements.push_back(parseStatement(true));
1202 nodeFactory.markEndPosition();
1203 }
1204 catch (FatalError const&)
1205 {
1206 if (
1207 !m_errorReporter.hasErrors() ||
1208 !m_parserErrorRecovery ||
1209 m_errorReporter.hasExcessiveErrors()
1210 )
1211 BOOST_THROW_EXCEPTION(FatalError()); /* Don't try to recover here. */
1212 m_inParserRecovery = true;
1213 }
1214 if (m_inParserRecovery)
1215 expectTokenOrConsumeUntil(Token::RBrace, "Block");
1216 else
1217 expectToken(Token::RBrace);
1218 return nodeFactory.createNode<Block>(_docString, unchecked, statements);
1219 }
1220
parseStatement(bool _allowUnchecked)1221 ASTPointer<Statement> Parser::parseStatement(bool _allowUnchecked)
1222 {
1223 RecursionGuard recursionGuard(*this);
1224 ASTPointer<ASTString> docString;
1225 ASTPointer<Statement> statement;
1226 try
1227 {
1228 if (m_scanner->currentCommentLiteral() != "")
1229 docString = make_shared<ASTString>(m_scanner->currentCommentLiteral());
1230 switch (m_scanner->currentToken())
1231 {
1232 case Token::If:
1233 return parseIfStatement(docString);
1234 case Token::While:
1235 return parseWhileStatement(docString);
1236 case Token::Do:
1237 return parseDoWhileStatement(docString);
1238 case Token::For:
1239 return parseForStatement(docString);
1240 case Token::Unchecked:
1241 case Token::LBrace:
1242 return parseBlock(_allowUnchecked, docString);
1243 case Token::Continue:
1244 statement = ASTNodeFactory(*this).createNode<Continue>(docString);
1245 advance();
1246 break;
1247 case Token::Break:
1248 statement = ASTNodeFactory(*this).createNode<Break>(docString);
1249 advance();
1250 break;
1251 case Token::Return:
1252 {
1253 ASTNodeFactory nodeFactory(*this);
1254 ASTPointer<Expression> expression;
1255 if (advance() != Token::Semicolon)
1256 {
1257 expression = parseExpression();
1258 nodeFactory.setEndPositionFromNode(expression);
1259 }
1260 statement = nodeFactory.createNode<Return>(docString, expression);
1261 break;
1262 }
1263 case Token::Throw:
1264 {
1265 statement = ASTNodeFactory(*this).createNode<Throw>(docString);
1266 advance();
1267 break;
1268 }
1269 case Token::Try:
1270 return parseTryStatement(docString);
1271 case Token::Assembly:
1272 return parseInlineAssembly(docString);
1273 case Token::Emit:
1274 statement = parseEmitStatement(docString);
1275 break;
1276 case Token::Identifier:
1277 if (m_scanner->currentLiteral() == "revert" && m_scanner->peekNextToken() == Token::Identifier)
1278 statement = parseRevertStatement(docString);
1279 else if (m_insideModifier && m_scanner->currentLiteral() == "_")
1280 {
1281 statement = ASTNodeFactory(*this).createNode<PlaceholderStatement>(docString);
1282 advance();
1283 }
1284 else
1285 statement = parseSimpleStatement(docString);
1286 break;
1287 default:
1288 statement = parseSimpleStatement(docString);
1289 break;
1290 }
1291 }
1292 catch (FatalError const&)
1293 {
1294 if (
1295 !m_errorReporter.hasErrors() ||
1296 !m_parserErrorRecovery ||
1297 m_errorReporter.hasExcessiveErrors()
1298 )
1299 BOOST_THROW_EXCEPTION(FatalError()); /* Don't try to recover here. */
1300 m_inParserRecovery = true;
1301 }
1302 if (m_inParserRecovery)
1303 expectTokenOrConsumeUntil(Token::Semicolon, "Statement");
1304 else
1305 expectToken(Token::Semicolon);
1306 return statement;
1307 }
1308
parseInlineAssembly(ASTPointer<ASTString> const & _docString)1309 ASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> const& _docString)
1310 {
1311 RecursionGuard recursionGuard(*this);
1312 SourceLocation location = currentLocation();
1313
1314 expectToken(Token::Assembly);
1315 yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion);
1316 if (m_scanner->currentToken() == Token::StringLiteral)
1317 {
1318 if (m_scanner->currentLiteral() != "evmasm")
1319 fatalParserError(4531_error, "Only \"evmasm\" supported.");
1320 // This can be used in the future to set the dialect.
1321 advance();
1322 }
1323
1324 yul::Parser asmParser(m_errorReporter, dialect);
1325 shared_ptr<yul::Block> block = asmParser.parseInline(m_scanner);
1326 if (block == nullptr)
1327 BOOST_THROW_EXCEPTION(FatalError());
1328
1329 location.end = nativeLocationOf(*block).end;
1330 return make_shared<InlineAssembly>(nextID(), location, _docString, dialect, block);
1331 }
1332
parseIfStatement(ASTPointer<ASTString> const & _docString)1333 ASTPointer<IfStatement> Parser::parseIfStatement(ASTPointer<ASTString> const& _docString)
1334 {
1335 RecursionGuard recursionGuard(*this);
1336 ASTNodeFactory nodeFactory(*this);
1337 expectToken(Token::If);
1338 expectToken(Token::LParen);
1339 ASTPointer<Expression> condition = parseExpression();
1340 expectToken(Token::RParen);
1341 ASTPointer<Statement> trueBody = parseStatement();
1342 ASTPointer<Statement> falseBody;
1343 if (m_scanner->currentToken() == Token::Else)
1344 {
1345 advance();
1346 falseBody = parseStatement();
1347 nodeFactory.setEndPositionFromNode(falseBody);
1348 }
1349 else
1350 nodeFactory.setEndPositionFromNode(trueBody);
1351 return nodeFactory.createNode<IfStatement>(_docString, condition, trueBody, falseBody);
1352 }
1353
parseTryStatement(ASTPointer<ASTString> const & _docString)1354 ASTPointer<TryStatement> Parser::parseTryStatement(ASTPointer<ASTString> const& _docString)
1355 {
1356 RecursionGuard recursionGuard(*this);
1357 ASTNodeFactory nodeFactory(*this);
1358 expectToken(Token::Try);
1359 ASTPointer<Expression> externalCall = parseExpression();
1360 vector<ASTPointer<TryCatchClause>> clauses;
1361
1362 ASTNodeFactory successClauseFactory(*this);
1363 ASTPointer<ParameterList> returnsParameters;
1364 if (m_scanner->currentToken() == Token::Returns)
1365 {
1366 advance();
1367 VarDeclParserOptions options;
1368 options.allowEmptyName = true;
1369 options.allowLocationSpecifier = true;
1370 returnsParameters = parseParameterList(options, false);
1371 }
1372 ASTPointer<Block> successBlock = parseBlock();
1373 successClauseFactory.setEndPositionFromNode(successBlock);
1374 clauses.emplace_back(successClauseFactory.createNode<TryCatchClause>(
1375 make_shared<ASTString>(), returnsParameters, successBlock
1376 ));
1377
1378 do
1379 {
1380 clauses.emplace_back(parseCatchClause());
1381 }
1382 while (m_scanner->currentToken() == Token::Catch);
1383 nodeFactory.setEndPositionFromNode(clauses.back());
1384 return nodeFactory.createNode<TryStatement>(
1385 _docString, externalCall, clauses
1386 );
1387 }
1388
parseCatchClause()1389 ASTPointer<TryCatchClause> Parser::parseCatchClause()
1390 {
1391 RecursionGuard recursionGuard(*this);
1392 ASTNodeFactory nodeFactory(*this);
1393 expectToken(Token::Catch);
1394 ASTPointer<ASTString> errorName = make_shared<string>();
1395 ASTPointer<ParameterList> errorParameters;
1396 if (m_scanner->currentToken() != Token::LBrace)
1397 {
1398 if (m_scanner->currentToken() == Token::Identifier)
1399 errorName = expectIdentifierToken();
1400 VarDeclParserOptions options;
1401 options.allowEmptyName = true;
1402 options.allowLocationSpecifier = true;
1403 errorParameters = parseParameterList(options, !errorName->empty());
1404 }
1405 ASTPointer<Block> block = parseBlock();
1406 nodeFactory.setEndPositionFromNode(block);
1407 return nodeFactory.createNode<TryCatchClause>(errorName, errorParameters, block);
1408 }
1409
parseWhileStatement(ASTPointer<ASTString> const & _docString)1410 ASTPointer<WhileStatement> Parser::parseWhileStatement(ASTPointer<ASTString> const& _docString)
1411 {
1412 RecursionGuard recursionGuard(*this);
1413 ASTNodeFactory nodeFactory(*this);
1414 expectToken(Token::While);
1415 expectToken(Token::LParen);
1416 ASTPointer<Expression> condition = parseExpression();
1417 expectToken(Token::RParen);
1418 ASTPointer<Statement> body = parseStatement();
1419 nodeFactory.setEndPositionFromNode(body);
1420 return nodeFactory.createNode<WhileStatement>(_docString, condition, body, false);
1421 }
1422
parseDoWhileStatement(ASTPointer<ASTString> const & _docString)1423 ASTPointer<WhileStatement> Parser::parseDoWhileStatement(ASTPointer<ASTString> const& _docString)
1424 {
1425 RecursionGuard recursionGuard(*this);
1426 ASTNodeFactory nodeFactory(*this);
1427 expectToken(Token::Do);
1428 ASTPointer<Statement> body = parseStatement();
1429 expectToken(Token::While);
1430 expectToken(Token::LParen);
1431 ASTPointer<Expression> condition = parseExpression();
1432 expectToken(Token::RParen);
1433 nodeFactory.markEndPosition();
1434 expectToken(Token::Semicolon);
1435 return nodeFactory.createNode<WhileStatement>(_docString, condition, body, true);
1436 }
1437
1438
parseForStatement(ASTPointer<ASTString> const & _docString)1439 ASTPointer<ForStatement> Parser::parseForStatement(ASTPointer<ASTString> const& _docString)
1440 {
1441 RecursionGuard recursionGuard(*this);
1442 ASTNodeFactory nodeFactory(*this);
1443 ASTPointer<Statement> initExpression;
1444 ASTPointer<Expression> conditionExpression;
1445 ASTPointer<ExpressionStatement> loopExpression;
1446 expectToken(Token::For);
1447 expectToken(Token::LParen);
1448
1449 // TODO: Maybe here have some predicate like peekExpression() instead of checking for semicolon and RParen?
1450 if (m_scanner->currentToken() != Token::Semicolon)
1451 initExpression = parseSimpleStatement(ASTPointer<ASTString>());
1452 expectToken(Token::Semicolon);
1453
1454 if (m_scanner->currentToken() != Token::Semicolon)
1455 conditionExpression = parseExpression();
1456 expectToken(Token::Semicolon);
1457
1458 if (m_scanner->currentToken() != Token::RParen)
1459 loopExpression = parseExpressionStatement(ASTPointer<ASTString>());
1460 expectToken(Token::RParen);
1461
1462 ASTPointer<Statement> body = parseStatement();
1463 nodeFactory.setEndPositionFromNode(body);
1464 return nodeFactory.createNode<ForStatement>(
1465 _docString,
1466 initExpression,
1467 conditionExpression,
1468 loopExpression,
1469 body
1470 );
1471 }
1472
parseEmitStatement(ASTPointer<ASTString> const & _docString)1473 ASTPointer<EmitStatement> Parser::parseEmitStatement(ASTPointer<ASTString> const& _docString)
1474 {
1475 expectToken(Token::Emit, false);
1476
1477 ASTNodeFactory nodeFactory(*this);
1478 advance();
1479 ASTNodeFactory eventCallNodeFactory(*this);
1480
1481 if (m_scanner->currentToken() != Token::Identifier)
1482 fatalParserError(5620_error, "Expected event name or path.");
1483
1484 IndexAccessedPath iap;
1485 while (true)
1486 {
1487 iap.path.push_back(parseIdentifier());
1488 if (m_scanner->currentToken() != Token::Period)
1489 break;
1490 advance();
1491 }
1492
1493 auto eventName = expressionFromIndexAccessStructure(iap);
1494 expectToken(Token::LParen);
1495
1496 vector<ASTPointer<Expression>> arguments;
1497 vector<ASTPointer<ASTString>> names;
1498 std::tie(arguments, names) = parseFunctionCallArguments();
1499 eventCallNodeFactory.markEndPosition();
1500 nodeFactory.markEndPosition();
1501 expectToken(Token::RParen);
1502 auto eventCall = eventCallNodeFactory.createNode<FunctionCall>(eventName, arguments, names);
1503 return nodeFactory.createNode<EmitStatement>(_docString, eventCall);
1504 }
1505
parseRevertStatement(ASTPointer<ASTString> const & _docString)1506 ASTPointer<RevertStatement> Parser::parseRevertStatement(ASTPointer<ASTString> const& _docString)
1507 {
1508 ASTNodeFactory nodeFactory(*this);
1509 solAssert(*expectIdentifierToken() == "revert", "");
1510
1511 ASTNodeFactory errorCallNodeFactory(*this);
1512
1513 solAssert(m_scanner->currentToken() == Token::Identifier, "");
1514
1515 IndexAccessedPath iap;
1516 while (true)
1517 {
1518 iap.path.push_back(parseIdentifier());
1519 if (m_scanner->currentToken() != Token::Period)
1520 break;
1521 advance();
1522 }
1523
1524 auto errorName = expressionFromIndexAccessStructure(iap);
1525 expectToken(Token::LParen);
1526
1527 vector<ASTPointer<Expression>> arguments;
1528 vector<ASTPointer<ASTString>> names;
1529 std::tie(arguments, names) = parseFunctionCallArguments();
1530 errorCallNodeFactory.markEndPosition();
1531 nodeFactory.markEndPosition();
1532 expectToken(Token::RParen);
1533 auto errorCall = errorCallNodeFactory.createNode<FunctionCall>(errorName, arguments, names);
1534 return nodeFactory.createNode<RevertStatement>(_docString, errorCall);
1535 }
1536
parseSimpleStatement(ASTPointer<ASTString> const & _docString)1537 ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& _docString)
1538 {
1539 RecursionGuard recursionGuard(*this);
1540 LookAheadInfo statementType;
1541 IndexAccessedPath iap;
1542
1543 if (m_scanner->currentToken() == Token::LParen)
1544 {
1545 ASTNodeFactory nodeFactory(*this);
1546 size_t emptyComponents = 0;
1547 // First consume all empty components.
1548 expectToken(Token::LParen);
1549 while (m_scanner->currentToken() == Token::Comma)
1550 {
1551 advance();
1552 emptyComponents++;
1553 }
1554
1555 // Now see whether we have a variable declaration or an expression.
1556 tie(statementType, iap) = tryParseIndexAccessedPath();
1557 switch (statementType)
1558 {
1559 case LookAheadInfo::VariableDeclaration:
1560 {
1561 vector<ASTPointer<VariableDeclaration>> variables;
1562 ASTPointer<Expression> value;
1563 // We have already parsed something like `(,,,,a.b.c[2][3]`
1564 VarDeclParserOptions options;
1565 options.allowLocationSpecifier = true;
1566 variables = vector<ASTPointer<VariableDeclaration>>(emptyComponents, nullptr);
1567 variables.push_back(parseVariableDeclaration(options, typeNameFromIndexAccessStructure(iap)));
1568
1569 while (m_scanner->currentToken() != Token::RParen)
1570 {
1571 expectToken(Token::Comma);
1572 if (m_scanner->currentToken() == Token::Comma || m_scanner->currentToken() == Token::RParen)
1573 variables.push_back(nullptr);
1574 else
1575 variables.push_back(parseVariableDeclaration(options));
1576 }
1577 expectToken(Token::RParen);
1578 expectToken(Token::Assign);
1579 value = parseExpression();
1580 nodeFactory.setEndPositionFromNode(value);
1581 return nodeFactory.createNode<VariableDeclarationStatement>(_docString, variables, value);
1582 }
1583 case LookAheadInfo::Expression:
1584 {
1585 // Complete parsing the expression in the current component.
1586 vector<ASTPointer<Expression>> components(emptyComponents, nullptr);
1587 components.push_back(parseExpression(expressionFromIndexAccessStructure(iap)));
1588 while (m_scanner->currentToken() != Token::RParen)
1589 {
1590 expectToken(Token::Comma);
1591 if (m_scanner->currentToken() == Token::Comma || m_scanner->currentToken() == Token::RParen)
1592 components.push_back(ASTPointer<Expression>());
1593 else
1594 components.push_back(parseExpression());
1595 }
1596 nodeFactory.markEndPosition();
1597 expectToken(Token::RParen);
1598 return parseExpressionStatement(_docString, nodeFactory.createNode<TupleExpression>(components, false));
1599 }
1600 default:
1601 solAssert(false, "");
1602 }
1603 }
1604 else
1605 {
1606 tie(statementType, iap) = tryParseIndexAccessedPath();
1607 switch (statementType)
1608 {
1609 case LookAheadInfo::VariableDeclaration:
1610 return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap));
1611 case LookAheadInfo::Expression:
1612 return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap));
1613 default:
1614 solAssert(false, "");
1615 }
1616 }
1617 }
1618
empty() const1619 bool Parser::IndexAccessedPath::empty() const
1620 {
1621 if (!indices.empty())
1622 {
1623 solAssert(!path.empty(), "");
1624 }
1625 return path.empty() && indices.empty();
1626 }
1627
1628
tryParseIndexAccessedPath()1629 pair<Parser::LookAheadInfo, Parser::IndexAccessedPath> Parser::tryParseIndexAccessedPath()
1630 {
1631 // These two cases are very hard to distinguish:
1632 // x[7 * 20 + 3] a; and x[7 * 20 + 3] = 9;
1633 // In the first case, x is a type name, in the second it is the name of a variable.
1634 // As an extension, we can even have:
1635 // `x.y.z[1][2] a;` and `x.y.z[1][2] = 10;`
1636 // Where in the first, x.y.z leads to a type name where in the second, it accesses structs.
1637
1638 auto statementType = peekStatementType();
1639 switch (statementType)
1640 {
1641 case LookAheadInfo::VariableDeclaration:
1642 case LookAheadInfo::Expression:
1643 return make_pair(statementType, IndexAccessedPath());
1644 default:
1645 break;
1646 }
1647
1648 // At this point, we have 'Identifier "["' or 'Identifier "." Identifier' or 'ElementoryTypeName "["'.
1649 // We parse '(Identifier ("." Identifier)* |ElementaryTypeName) ( "[" Expression "]" )*'
1650 // until we can decide whether to hand this over to ExpressionStatement or create a
1651 // VariableDeclarationStatement out of it.
1652 IndexAccessedPath iap = parseIndexAccessedPath();
1653
1654 if (m_scanner->currentToken() == Token::Identifier || TokenTraits::isLocationSpecifier(m_scanner->currentToken()))
1655 return make_pair(LookAheadInfo::VariableDeclaration, move(iap));
1656 else
1657 return make_pair(LookAheadInfo::Expression, move(iap));
1658 }
1659
parseVariableDeclarationStatement(ASTPointer<ASTString> const & _docString,ASTPointer<TypeName> const & _lookAheadArrayType)1660 ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement(
1661 ASTPointer<ASTString> const& _docString,
1662 ASTPointer<TypeName> const& _lookAheadArrayType
1663 )
1664 {
1665 // This does not parse multi variable declaration statements starting directly with
1666 // `(`, they are parsed in parseSimpleStatement, because they are hard to distinguish
1667 // from tuple expressions.
1668 RecursionGuard recursionGuard(*this);
1669 ASTNodeFactory nodeFactory(*this);
1670 if (_lookAheadArrayType)
1671 nodeFactory.setLocation(_lookAheadArrayType->location());
1672
1673 VarDeclParserOptions options;
1674 options.allowLocationSpecifier = true;
1675 vector<ASTPointer<VariableDeclaration>> variables;
1676 variables.emplace_back(parseVariableDeclaration(options, _lookAheadArrayType));
1677 nodeFactory.setEndPositionFromNode(variables.back());
1678
1679 ASTPointer<Expression> value;
1680 if (m_scanner->currentToken() == Token::Assign)
1681 {
1682 advance();
1683 value = parseExpression();
1684 nodeFactory.setEndPositionFromNode(value);
1685 }
1686 return nodeFactory.createNode<VariableDeclarationStatement>(_docString, variables, value);
1687 }
1688
parseExpressionStatement(ASTPointer<ASTString> const & _docString,ASTPointer<Expression> const & _partialParserResult)1689 ASTPointer<ExpressionStatement> Parser::parseExpressionStatement(
1690 ASTPointer<ASTString> const& _docString,
1691 ASTPointer<Expression> const& _partialParserResult
1692 )
1693 {
1694 RecursionGuard recursionGuard(*this);
1695 ASTPointer<Expression> expression = parseExpression(_partialParserResult);
1696 return ASTNodeFactory(*this, expression).createNode<ExpressionStatement>(_docString, expression);
1697 }
1698
parseExpression(ASTPointer<Expression> const & _partiallyParsedExpression)1699 ASTPointer<Expression> Parser::parseExpression(
1700 ASTPointer<Expression> const& _partiallyParsedExpression
1701 )
1702 {
1703 RecursionGuard recursionGuard(*this);
1704 ASTPointer<Expression> expression = parseBinaryExpression(4, _partiallyParsedExpression);
1705 if (TokenTraits::isAssignmentOp(m_scanner->currentToken()))
1706 {
1707 Token assignmentOperator = m_scanner->currentToken();
1708 advance();
1709 ASTPointer<Expression> rightHandSide = parseExpression();
1710 ASTNodeFactory nodeFactory(*this, expression);
1711 nodeFactory.setEndPositionFromNode(rightHandSide);
1712 return nodeFactory.createNode<Assignment>(expression, assignmentOperator, rightHandSide);
1713 }
1714 else if (m_scanner->currentToken() == Token::Conditional)
1715 {
1716 advance();
1717 ASTPointer<Expression> trueExpression = parseExpression();
1718 expectToken(Token::Colon);
1719 ASTPointer<Expression> falseExpression = parseExpression();
1720 ASTNodeFactory nodeFactory(*this, expression);
1721 nodeFactory.setEndPositionFromNode(falseExpression);
1722 return nodeFactory.createNode<Conditional>(expression, trueExpression, falseExpression);
1723 }
1724 else
1725 return expression;
1726 }
1727
parseBinaryExpression(int _minPrecedence,ASTPointer<Expression> const & _partiallyParsedExpression)1728 ASTPointer<Expression> Parser::parseBinaryExpression(
1729 int _minPrecedence,
1730 ASTPointer<Expression> const& _partiallyParsedExpression
1731 )
1732 {
1733 RecursionGuard recursionGuard(*this);
1734 ASTPointer<Expression> expression = parseUnaryExpression(_partiallyParsedExpression);
1735 ASTNodeFactory nodeFactory(*this, expression);
1736 int precedence = TokenTraits::precedence(m_scanner->currentToken());
1737 for (; precedence >= _minPrecedence; --precedence)
1738 while (TokenTraits::precedence(m_scanner->currentToken()) == precedence)
1739 {
1740 Token op = m_scanner->currentToken();
1741 advance();
1742
1743 static_assert(TokenTraits::hasExpHighestPrecedence(), "Exp does not have the highest precedence");
1744
1745 // Parse a**b**c as a**(b**c)
1746 ASTPointer<Expression> right = (op == Token::Exp) ?
1747 parseBinaryExpression(precedence) :
1748 parseBinaryExpression(precedence + 1);
1749 nodeFactory.setEndPositionFromNode(right);
1750 expression = nodeFactory.createNode<BinaryOperation>(expression, op, right);
1751 }
1752 return expression;
1753 }
1754
parseUnaryExpression(ASTPointer<Expression> const & _partiallyParsedExpression)1755 ASTPointer<Expression> Parser::parseUnaryExpression(
1756 ASTPointer<Expression> const& _partiallyParsedExpression
1757 )
1758 {
1759 RecursionGuard recursionGuard(*this);
1760 ASTNodeFactory nodeFactory = _partiallyParsedExpression ?
1761 ASTNodeFactory(*this, _partiallyParsedExpression) : ASTNodeFactory(*this);
1762 Token token = m_scanner->currentToken();
1763 if (!_partiallyParsedExpression && (TokenTraits::isUnaryOp(token) || TokenTraits::isCountOp(token)))
1764 {
1765 // prefix expression
1766 advance();
1767 ASTPointer<Expression> subExpression = parseUnaryExpression();
1768 nodeFactory.setEndPositionFromNode(subExpression);
1769 return nodeFactory.createNode<UnaryOperation>(token, subExpression, true);
1770 }
1771 else
1772 {
1773 // potential postfix expression
1774 ASTPointer<Expression> subExpression = parseLeftHandSideExpression(_partiallyParsedExpression);
1775 token = m_scanner->currentToken();
1776
1777 if (!TokenTraits::isCountOp(token))
1778 return subExpression;
1779 nodeFactory.markEndPosition();
1780 advance();
1781 return nodeFactory.createNode<UnaryOperation>(token, subExpression, false);
1782 }
1783 }
1784
parseLeftHandSideExpression(ASTPointer<Expression> const & _partiallyParsedExpression)1785 ASTPointer<Expression> Parser::parseLeftHandSideExpression(
1786 ASTPointer<Expression> const& _partiallyParsedExpression
1787 )
1788 {
1789 RecursionGuard recursionGuard(*this);
1790 ASTNodeFactory nodeFactory = _partiallyParsedExpression ?
1791 ASTNodeFactory(*this, _partiallyParsedExpression) : ASTNodeFactory(*this);
1792
1793 ASTPointer<Expression> expression;
1794 if (_partiallyParsedExpression)
1795 expression = _partiallyParsedExpression;
1796 else if (m_scanner->currentToken() == Token::New)
1797 {
1798 expectToken(Token::New);
1799 ASTPointer<TypeName> typeName(parseTypeName());
1800 nodeFactory.setEndPositionFromNode(typeName);
1801 expression = nodeFactory.createNode<NewExpression>(typeName);
1802 }
1803 else if (m_scanner->currentToken() == Token::Payable)
1804 {
1805 expectToken(Token::Payable);
1806 nodeFactory.markEndPosition();
1807 auto expressionType = nodeFactory.createNode<ElementaryTypeName>(
1808 ElementaryTypeNameToken(Token::Address, 0, 0),
1809 std::make_optional(StateMutability::Payable)
1810 );
1811 expression = nodeFactory.createNode<ElementaryTypeNameExpression>(expressionType);
1812 expectToken(Token::LParen, false);
1813 }
1814 else
1815 expression = parsePrimaryExpression();
1816
1817 while (true)
1818 {
1819 switch (m_scanner->currentToken())
1820 {
1821 case Token::LBrack:
1822 {
1823 advance();
1824 ASTPointer<Expression> index;
1825 ASTPointer<Expression> endIndex;
1826 if (m_scanner->currentToken() != Token::RBrack && m_scanner->currentToken() != Token::Colon)
1827 index = parseExpression();
1828 if (m_scanner->currentToken() == Token::Colon)
1829 {
1830 expectToken(Token::Colon);
1831 if (m_scanner->currentToken() != Token::RBrack)
1832 endIndex = parseExpression();
1833 nodeFactory.markEndPosition();
1834 expectToken(Token::RBrack);
1835 expression = nodeFactory.createNode<IndexRangeAccess>(expression, index, endIndex);
1836 }
1837 else
1838 {
1839 nodeFactory.markEndPosition();
1840 expectToken(Token::RBrack);
1841 expression = nodeFactory.createNode<IndexAccess>(expression, index);
1842 }
1843 break;
1844 }
1845 case Token::Period:
1846 {
1847 advance();
1848 nodeFactory.markEndPosition();
1849 expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierTokenOrAddress());
1850 break;
1851 }
1852 case Token::LParen:
1853 {
1854 advance();
1855 vector<ASTPointer<Expression>> arguments;
1856 vector<ASTPointer<ASTString>> names;
1857 std::tie(arguments, names) = parseFunctionCallArguments();
1858 nodeFactory.markEndPosition();
1859 expectToken(Token::RParen);
1860 expression = nodeFactory.createNode<FunctionCall>(expression, arguments, names);
1861 break;
1862 }
1863 case Token::LBrace:
1864 {
1865 // See if this is followed by <identifier>, followed by ":". If not, it is not
1866 // a function call options but a Block (from a try statement).
1867 if (
1868 m_scanner->peekNextToken() != Token::Identifier ||
1869 m_scanner->peekNextNextToken() != Token::Colon
1870 )
1871 return expression;
1872
1873 expectToken(Token::LBrace);
1874 auto optionList = parseNamedArguments();
1875
1876 nodeFactory.markEndPosition();
1877 expectToken(Token::RBrace);
1878
1879 expression = nodeFactory.createNode<FunctionCallOptions>(expression, optionList.first, optionList.second);
1880 break;
1881 }
1882 default:
1883 return expression;
1884 }
1885 }
1886 }
1887
parsePrimaryExpression()1888 ASTPointer<Expression> Parser::parsePrimaryExpression()
1889 {
1890 RecursionGuard recursionGuard(*this);
1891 ASTNodeFactory nodeFactory(*this);
1892 Token token = m_scanner->currentToken();
1893 ASTPointer<Expression> expression;
1894
1895 switch (token)
1896 {
1897 case Token::TrueLiteral:
1898 case Token::FalseLiteral:
1899 nodeFactory.markEndPosition();
1900 expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
1901 break;
1902 case Token::Number:
1903 if (TokenTraits::isEtherSubdenomination(m_scanner->peekNextToken()))
1904 {
1905 ASTPointer<ASTString> literal = getLiteralAndAdvance();
1906 nodeFactory.markEndPosition();
1907 Literal::SubDenomination subdenomination = static_cast<Literal::SubDenomination>(m_scanner->currentToken());
1908 advance();
1909 expression = nodeFactory.createNode<Literal>(token, literal, subdenomination);
1910 }
1911 else if (TokenTraits::isTimeSubdenomination(m_scanner->peekNextToken()))
1912 {
1913 ASTPointer<ASTString> literal = getLiteralAndAdvance();
1914 nodeFactory.markEndPosition();
1915 Literal::SubDenomination subdenomination = static_cast<Literal::SubDenomination>(m_scanner->currentToken());
1916 advance();
1917 expression = nodeFactory.createNode<Literal>(token, literal, subdenomination);
1918 }
1919 else
1920 {
1921 nodeFactory.markEndPosition();
1922 expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
1923 }
1924 break;
1925 case Token::StringLiteral:
1926 case Token::UnicodeStringLiteral:
1927 case Token::HexStringLiteral:
1928 {
1929 string literal = m_scanner->currentLiteral();
1930 Token firstToken = m_scanner->currentToken();
1931 while (m_scanner->peekNextToken() == firstToken)
1932 {
1933 advance();
1934 literal += m_scanner->currentLiteral();
1935 }
1936 nodeFactory.markEndPosition();
1937 advance();
1938 if (m_scanner->currentToken() == Token::Illegal)
1939 fatalParserError(5428_error, to_string(m_scanner->currentError()));
1940 expression = nodeFactory.createNode<Literal>(token, make_shared<ASTString>(literal));
1941 break;
1942 }
1943 case Token::Identifier:
1944 nodeFactory.markEndPosition();
1945 expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance());
1946 break;
1947 case Token::Type:
1948 // Inside expressions "type" is the name of a special, globally-available function.
1949 nodeFactory.markEndPosition();
1950 advance();
1951 expression = nodeFactory.createNode<Identifier>(make_shared<ASTString>("type"));
1952 break;
1953 case Token::LParen:
1954 case Token::LBrack:
1955 {
1956 // Tuple/parenthesized expression or inline array/bracketed expression.
1957 // Special cases: ()/[] is empty tuple/array type, (x) is not a real tuple,
1958 // (x,) is one-dimensional tuple, elements in arrays cannot be left out, only in tuples.
1959 advance();
1960 vector<ASTPointer<Expression>> components;
1961 Token oppositeToken = (token == Token::LParen ? Token::RParen : Token::RBrack);
1962 bool isArray = (token == Token::LBrack);
1963
1964 if (m_scanner->currentToken() != oppositeToken)
1965 while (true)
1966 {
1967 if (m_scanner->currentToken() != Token::Comma && m_scanner->currentToken() != oppositeToken)
1968 components.push_back(parseExpression());
1969 else if (isArray)
1970 parserError(4799_error, "Expected expression (inline array elements cannot be omitted).");
1971 else
1972 components.push_back(ASTPointer<Expression>());
1973
1974 if (m_scanner->currentToken() == oppositeToken)
1975 break;
1976
1977 expectToken(Token::Comma);
1978 }
1979 nodeFactory.markEndPosition();
1980 expectToken(oppositeToken);
1981 expression = nodeFactory.createNode<TupleExpression>(components, isArray);
1982 break;
1983 }
1984 case Token::Illegal:
1985 fatalParserError(8936_error, to_string(m_scanner->currentError()));
1986 break;
1987 default:
1988 if (TokenTraits::isElementaryTypeName(token))
1989 {
1990 //used for casts
1991 unsigned firstSize;
1992 unsigned secondSize;
1993 tie(firstSize, secondSize) = m_scanner->currentTokenInfo();
1994 auto expressionType = nodeFactory.createNode<ElementaryTypeName>(
1995 ElementaryTypeNameToken(m_scanner->currentToken(), firstSize, secondSize)
1996 );
1997 expression = nodeFactory.createNode<ElementaryTypeNameExpression>(expressionType);
1998 advance();
1999 }
2000 else
2001 fatalParserError(6933_error, "Expected primary expression.");
2002 break;
2003 }
2004 return expression;
2005 }
2006
parseFunctionCallListArguments()2007 vector<ASTPointer<Expression>> Parser::parseFunctionCallListArguments()
2008 {
2009 RecursionGuard recursionGuard(*this);
2010 vector<ASTPointer<Expression>> arguments;
2011 if (m_scanner->currentToken() != Token::RParen)
2012 {
2013 arguments.push_back(parseExpression());
2014 while (m_scanner->currentToken() != Token::RParen)
2015 {
2016 expectToken(Token::Comma);
2017 arguments.push_back(parseExpression());
2018 }
2019 }
2020 return arguments;
2021 }
2022
parseFunctionCallArguments()2023 pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::parseFunctionCallArguments()
2024 {
2025 RecursionGuard recursionGuard(*this);
2026 pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> ret;
2027 Token token = m_scanner->currentToken();
2028 if (token == Token::LBrace)
2029 {
2030 // call({arg1 : 1, arg2 : 2 })
2031 expectToken(Token::LBrace);
2032 ret = parseNamedArguments();
2033 expectToken(Token::RBrace);
2034 }
2035 else
2036 ret.first = parseFunctionCallListArguments();
2037 return ret;
2038 }
2039
parseNamedArguments()2040 pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::parseNamedArguments()
2041 {
2042 pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> ret;
2043
2044 bool first = true;
2045 while (m_scanner->currentToken() != Token::RBrace)
2046 {
2047 if (!first)
2048 expectToken(Token::Comma);
2049
2050 ret.second.push_back(expectIdentifierToken());
2051 expectToken(Token::Colon);
2052 ret.first.push_back(parseExpression());
2053
2054 if (
2055 m_scanner->currentToken() == Token::Comma &&
2056 m_scanner->peekNextToken() == Token::RBrace
2057 )
2058 {
2059 parserError(2074_error, "Unexpected trailing comma.");
2060 advance();
2061 }
2062
2063 first = false;
2064 }
2065
2066 return ret;
2067 }
2068
variableDeclarationStart()2069 bool Parser::variableDeclarationStart()
2070 {
2071 Token currentToken = m_scanner->currentToken();
2072 return
2073 currentToken == Token::Identifier ||
2074 currentToken == Token::Mapping ||
2075 TokenTraits::isElementaryTypeName(currentToken) ||
2076 (currentToken == Token::Function && m_scanner->peekNextToken() == Token::LParen);
2077 }
2078
findLicenseString(std::vector<ASTPointer<ASTNode>> const & _nodes)2079 optional<string> Parser::findLicenseString(std::vector<ASTPointer<ASTNode>> const& _nodes)
2080 {
2081 // We circumvent the scanner here, because it skips non-docstring comments.
2082 static regex const licenseNameRegex("([a-zA-Z0-9 ()+.-]+)");
2083 static regex const licenseDeclarationRegex("SPDX-License-Identifier:\\s*(.+?)([\n\r]|(\\*/))");
2084
2085 // Search inside all parts of the source not covered by parsed nodes.
2086 // This will leave e.g. "global comments".
2087 using iter = std::string::const_iterator;
2088 vector<pair<iter, iter>> sequencesToSearch;
2089 string const& source = m_scanner->charStream().source();
2090 sequencesToSearch.emplace_back(source.begin(), source.end());
2091 for (ASTPointer<ASTNode> const& node: _nodes)
2092 if (node->location().hasText())
2093 {
2094 sequencesToSearch.back().second = source.begin() + node->location().start;
2095 sequencesToSearch.emplace_back(source.begin() + node->location().end, source.end());
2096 }
2097
2098 vector<string> licenseNames;
2099 for (auto const& [start, end]: sequencesToSearch)
2100 {
2101 auto declarationsBegin = std::sregex_iterator(start, end, licenseDeclarationRegex);
2102 auto declarationsEnd = std::sregex_iterator();
2103
2104 for (std::sregex_iterator declIt = declarationsBegin; declIt != declarationsEnd; ++declIt)
2105 if (!declIt->empty())
2106 {
2107 string license = boost::trim_copy(string((*declIt)[1]));
2108 licenseNames.emplace_back(std::move(license));
2109 }
2110 }
2111
2112 if (licenseNames.size() == 1)
2113 {
2114 string const& license = licenseNames.front();
2115 if (regex_match(license, licenseNameRegex))
2116 return license;
2117 else
2118 parserError(
2119 1114_error,
2120 {-1, -1, m_scanner->currentLocation().sourceName},
2121 "Invalid SPDX license identifier."
2122 );
2123 }
2124 else if (licenseNames.empty())
2125 parserWarning(
2126 1878_error,
2127 {-1, -1, m_scanner->currentLocation().sourceName},
2128 "SPDX license identifier not provided in source file. "
2129 "Before publishing, consider adding a comment containing "
2130 "\"SPDX-License-Identifier: <SPDX-License>\" to each source file. "
2131 "Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. "
2132 "Please see https://spdx.org for more information."
2133 );
2134 else
2135 parserError(
2136 3716_error,
2137 {-1, -1, m_scanner->currentLocation().sourceName},
2138 "Multiple SPDX license identifiers found in source file. "
2139 "Use \"AND\" or \"OR\" to combine multiple licenses. "
2140 "Please see https://spdx.org for more information."
2141 );
2142
2143 return {};
2144 }
2145
peekStatementType() const2146 Parser::LookAheadInfo Parser::peekStatementType() const
2147 {
2148 // Distinguish between variable declaration (and potentially assignment) and expression statement
2149 // (which include assignments to other expressions and pre-declared variables).
2150 // We have a variable declaration if we get a keyword that specifies a type name.
2151 // If it is an identifier or an elementary type name followed by an identifier
2152 // or a mutability specifier, we also have a variable declaration.
2153 // If we get an identifier followed by a "[" or ".", it can be both ("lib.type[9] a;" or "variable.el[9] = 7;").
2154 // In all other cases, we have an expression statement.
2155 Token token(m_scanner->currentToken());
2156 bool mightBeTypeName = (TokenTraits::isElementaryTypeName(token) || token == Token::Identifier);
2157
2158 if (token == Token::Mapping || token == Token::Function)
2159 return LookAheadInfo::VariableDeclaration;
2160 if (mightBeTypeName)
2161 {
2162 Token next = m_scanner->peekNextToken();
2163 // So far we only allow ``address payable`` in variable declaration statements and in no other
2164 // kind of statement. This means, for example, that we do not allow type expressions of the form
2165 // ``address payable;``.
2166 // If we want to change this in the future, we need to consider another scanner token here.
2167 if (TokenTraits::isElementaryTypeName(token) && TokenTraits::isStateMutabilitySpecifier(next))
2168 return LookAheadInfo::VariableDeclaration;
2169 if (next == Token::Identifier || TokenTraits::isLocationSpecifier(next))
2170 return LookAheadInfo::VariableDeclaration;
2171 if (next == Token::LBrack || next == Token::Period)
2172 return LookAheadInfo::IndexAccessStructure;
2173 }
2174 return LookAheadInfo::Expression;
2175 }
2176
parseIndexAccessedPath()2177 Parser::IndexAccessedPath Parser::parseIndexAccessedPath()
2178 {
2179 IndexAccessedPath iap;
2180 if (m_scanner->currentToken() == Token::Identifier)
2181 {
2182 iap.path.push_back(parseIdentifier());
2183 while (m_scanner->currentToken() == Token::Period)
2184 {
2185 advance();
2186 iap.path.push_back(parseIdentifierOrAddress());
2187 }
2188 }
2189 else
2190 {
2191 unsigned firstNum;
2192 unsigned secondNum;
2193 tie(firstNum, secondNum) = m_scanner->currentTokenInfo();
2194 auto expressionType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(
2195 ElementaryTypeNameToken(m_scanner->currentToken(), firstNum, secondNum)
2196 );
2197 iap.path.push_back(ASTNodeFactory(*this).createNode<ElementaryTypeNameExpression>(expressionType));
2198 advance();
2199 }
2200 while (m_scanner->currentToken() == Token::LBrack)
2201 {
2202 expectToken(Token::LBrack);
2203 ASTPointer<Expression> index;
2204 if (m_scanner->currentToken() != Token::RBrack && m_scanner->currentToken() != Token::Colon)
2205 index = parseExpression();
2206 SourceLocation indexLocation = iap.path.front()->location();
2207 if (m_scanner->currentToken() == Token::Colon)
2208 {
2209 expectToken(Token::Colon);
2210 ASTPointer<Expression> endIndex;
2211 if (m_scanner->currentToken() != Token::RBrack)
2212 endIndex = parseExpression();
2213 indexLocation.end = currentLocation().end;
2214 iap.indices.emplace_back(IndexAccessedPath::Index{index, {endIndex}, indexLocation});
2215 expectToken(Token::RBrack);
2216 }
2217 else
2218 {
2219 indexLocation.end = currentLocation().end;
2220 iap.indices.emplace_back(IndexAccessedPath::Index{index, {}, indexLocation});
2221 expectToken(Token::RBrack);
2222 }
2223 }
2224
2225 return iap;
2226 }
2227
typeNameFromIndexAccessStructure(Parser::IndexAccessedPath const & _iap)2228 ASTPointer<TypeName> Parser::typeNameFromIndexAccessStructure(Parser::IndexAccessedPath const& _iap)
2229 {
2230 if (_iap.empty())
2231 return {};
2232
2233 RecursionGuard recursionGuard(*this);
2234 ASTNodeFactory nodeFactory(*this);
2235 SourceLocation location = _iap.path.front()->location();
2236 location.end = _iap.path.back()->location().end;
2237 nodeFactory.setLocation(location);
2238
2239 ASTPointer<TypeName> type;
2240 if (auto typeName = dynamic_cast<ElementaryTypeNameExpression const*>(_iap.path.front().get()))
2241 {
2242 solAssert(_iap.path.size() == 1, "");
2243 type = nodeFactory.createNode<ElementaryTypeName>(typeName->type().typeName());
2244 }
2245 else
2246 {
2247 vector<ASTString> path;
2248 for (auto const& el: _iap.path)
2249 path.push_back(dynamic_cast<Identifier const&>(*el).name());
2250 type = nodeFactory.createNode<UserDefinedTypeName>(nodeFactory.createNode<IdentifierPath>(path));
2251 }
2252 for (auto const& lengthExpression: _iap.indices)
2253 {
2254 if (lengthExpression.end)
2255 parserError(5464_error, lengthExpression.location, "Expected array length expression.");
2256 nodeFactory.setLocation(lengthExpression.location);
2257 type = nodeFactory.createNode<ArrayTypeName>(type, lengthExpression.start);
2258 }
2259 return type;
2260 }
2261
expressionFromIndexAccessStructure(Parser::IndexAccessedPath const & _iap)2262 ASTPointer<Expression> Parser::expressionFromIndexAccessStructure(
2263 Parser::IndexAccessedPath const& _iap
2264 )
2265 {
2266 if (_iap.empty())
2267 return {};
2268
2269 RecursionGuard recursionGuard(*this);
2270 ASTNodeFactory nodeFactory(*this, _iap.path.front());
2271 ASTPointer<Expression> expression(_iap.path.front());
2272 for (size_t i = 1; i < _iap.path.size(); ++i)
2273 {
2274 SourceLocation location(_iap.path.front()->location());
2275 location.end = _iap.path[i]->location().end;
2276 nodeFactory.setLocation(location);
2277 Identifier const& identifier = dynamic_cast<Identifier const&>(*_iap.path[i]);
2278 expression = nodeFactory.createNode<MemberAccess>(
2279 expression,
2280 make_shared<ASTString>(identifier.name())
2281 );
2282 }
2283 for (auto const& index: _iap.indices)
2284 {
2285 nodeFactory.setLocation(index.location);
2286 if (index.end)
2287 expression = nodeFactory.createNode<IndexRangeAccess>(expression, index.start, *index.end);
2288 else
2289 expression = nodeFactory.createNode<IndexAccess>(expression, index.start);
2290 }
2291 return expression;
2292 }
2293
createEmptyParameterList()2294 ASTPointer<ParameterList> Parser::createEmptyParameterList()
2295 {
2296 RecursionGuard recursionGuard(*this);
2297 ASTNodeFactory nodeFactory(*this);
2298 nodeFactory.setLocationEmpty();
2299 return nodeFactory.createNode<ParameterList>(vector<ASTPointer<VariableDeclaration>>());
2300 }
2301
expectIdentifierToken()2302 ASTPointer<ASTString> Parser::expectIdentifierToken()
2303 {
2304 expectToken(Token::Identifier, false /* do not advance */);
2305 return getLiteralAndAdvance();
2306 }
2307
expectIdentifierTokenOrAddress()2308 ASTPointer<ASTString> Parser::expectIdentifierTokenOrAddress()
2309 {
2310 ASTPointer<ASTString> result;
2311 if (m_scanner->currentToken() == Token::Address)
2312 {
2313 result = make_shared<ASTString>("address");
2314 advance();
2315 }
2316 else
2317 {
2318 expectToken(Token::Identifier, false /* do not advance */);
2319 result = getLiteralAndAdvance();
2320 }
2321 return result;
2322 }
2323
getLiteralAndAdvance()2324 ASTPointer<ASTString> Parser::getLiteralAndAdvance()
2325 {
2326 ASTPointer<ASTString> identifier = make_shared<ASTString>(m_scanner->currentLiteral());
2327 advance();
2328 return identifier;
2329 }
2330
2331 }
2332