1/**
2 * Solidity is a statically typed, contract-oriented, high-level language for implementing smart contracts on the Ethereum platform.
3 */
4parser grammar SolidityParser;
5
6options { tokenVocab=SolidityLexer; }
7
8/**
9 * On top level, Solidity allows pragmas, import directives, and
10 * definitions of contracts, interfaces, libraries, structs, enums and constants.
11 */
12sourceUnit: (
13	pragmaDirective
14	| importDirective
15	| contractDefinition
16	| interfaceDefinition
17	| libraryDefinition
18	| functionDefinition
19	| constantVariableDeclaration
20	| structDefinition
21	| enumDefinition
22	| userDefinedValueTypeDefinition
23	| errorDefinition
24)* EOF;
25
26//@doc: inline
27pragmaDirective: Pragma PragmaToken+ PragmaSemicolon;
28
29/**
30 * Import directives import identifiers from different files.
31 */
32importDirective:
33	Import (
34		(path (As unitAlias=identifier)?)
35		| (symbolAliases From path)
36		| (Mul As unitAlias=identifier From path)
37	) Semicolon;
38//@doc: inline
39//@doc:name aliases
40importAliases: symbol=identifier (As alias=identifier)?;
41/**
42 * Path of a file to be imported.
43 */
44path: NonEmptyStringLiteral;
45/**
46 * List of aliases for symbols to be imported.
47 */
48symbolAliases: LBrace aliases+=importAliases (Comma aliases+=importAliases)* RBrace;
49
50/**
51 * Top-level definition of a contract.
52 */
53contractDefinition:
54	Abstract? Contract name=identifier
55	inheritanceSpecifierList?
56	LBrace contractBodyElement* RBrace;
57/**
58 * Top-level definition of an interface.
59 */
60interfaceDefinition:
61	Interface name=identifier
62	inheritanceSpecifierList?
63	LBrace contractBodyElement* RBrace;
64/**
65 * Top-level definition of a library.
66 */
67libraryDefinition: Library name=identifier LBrace contractBodyElement* RBrace;
68
69//@doc:inline
70inheritanceSpecifierList:
71	Is inheritanceSpecifiers+=inheritanceSpecifier
72	(Comma inheritanceSpecifiers+=inheritanceSpecifier)*?;
73/**
74 * Inheritance specifier for contracts and interfaces.
75 * Can optionally supply base constructor arguments.
76 */
77inheritanceSpecifier: name=identifierPath arguments=callArgumentList?;
78
79/**
80 * Declarations that can be used in contracts, interfaces and libraries.
81 *
82 * Note that interfaces and libraries may not contain constructors, interfaces may not contain state variables
83 * and libraries may not contain fallback, receive functions nor non-constant state variables.
84 */
85contractBodyElement:
86	constructorDefinition
87	| functionDefinition
88	| modifierDefinition
89	| fallbackFunctionDefinition
90	| receiveFunctionDefinition
91	| structDefinition
92	| enumDefinition
93	| userDefinedValueTypeDefinition
94	| stateVariableDeclaration
95	| eventDefinition
96	| errorDefinition
97	| usingDirective;
98//@doc:inline
99namedArgument: name=identifier Colon value=expression;
100/**
101 * Arguments when calling a function or a similar callable object.
102 * The arguments are either given as comma separated list or as map of named arguments.
103 */
104callArgumentList: LParen ((expression (Comma expression)*)? | LBrace (namedArgument (Comma namedArgument)*)? RBrace) RParen;
105/**
106 * Qualified name.
107 */
108identifierPath: identifier (Period identifier)*;
109
110/**
111 * Call to a modifier. If the modifier takes no arguments, the argument list can be skipped entirely
112 * (including opening and closing parentheses).
113 */
114modifierInvocation: identifierPath callArgumentList?;
115/**
116 * Visibility for functions and function types.
117 */
118visibility: Internal | External | Private | Public;
119/**
120 * A list of parameters, such as function arguments or return values.
121 */
122parameterList: parameters+=parameterDeclaration (Comma parameters+=parameterDeclaration)*;
123//@doc:inline
124parameterDeclaration: type=typeName location=dataLocation? name=identifier?;
125/**
126 * Definition of a constructor.
127 * Must always supply an implementation.
128 * Note that specifying internal or public visibility is deprecated.
129 */
130constructorDefinition
131locals[boolean payableSet = false, boolean visibilitySet = false]
132:
133	Constructor LParen (arguments=parameterList)? RParen
134	(
135		modifierInvocation
136		| {!$payableSet}? Payable {$payableSet = true;}
137		| {!$visibilitySet}? Internal {$visibilitySet = true;}
138		| {!$visibilitySet}? Public {$visibilitySet = true;}
139	)*
140	body=block;
141
142/**
143 * State mutability for function types.
144 * The default mutability 'non-payable' is assumed if no mutability is specified.
145 */
146stateMutability: Pure | View | Payable;
147/**
148 * An override specifier used for functions, modifiers or state variables.
149 * In cases where there are ambiguous declarations in several base contracts being overridden,
150 * a complete list of base contracts has to be given.
151 */
152overrideSpecifier: Override (LParen overrides+=identifierPath (Comma overrides+=identifierPath)* RParen)?;
153/**
154 * The definition of contract, library and interface functions.
155 * Depending on the context in which the function is defined, further restrictions may apply,
156 * e.g. functions in interfaces have to be unimplemented, i.e. may not contain a body block.
157 */
158functionDefinition
159locals[
160	boolean visibilitySet = false,
161	boolean mutabilitySet = false,
162	boolean virtualSet = false,
163	boolean overrideSpecifierSet = false
164]
165:
166	Function (identifier | Fallback | Receive)
167	LParen (arguments=parameterList)? RParen
168	(
169		{!$visibilitySet}? visibility {$visibilitySet = true;}
170		| {!$mutabilitySet}? stateMutability {$mutabilitySet = true;}
171		| modifierInvocation
172		| {!$virtualSet}? Virtual {$virtualSet = true;}
173		| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}
174	 )*
175	(Returns LParen returnParameters=parameterList RParen)?
176	(Semicolon | body=block);
177/**
178 * The definition of a modifier.
179 * Note that within the body block of a modifier, the underscore cannot be used as identifier,
180 * but is used as placeholder statement for the body of a function to which the modifier is applied.
181 */
182modifierDefinition
183locals[
184	boolean virtualSet = false,
185	boolean overrideSpecifierSet = false
186]
187:
188	Modifier name=identifier
189	(LParen (arguments=parameterList)? RParen)?
190	(
191		{!$virtualSet}? Virtual {$virtualSet = true;}
192		| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}
193	)*
194	(Semicolon | body=block);
195
196/**
197 * Definition of the special fallback function.
198 */
199fallbackFunctionDefinition
200locals[
201	boolean visibilitySet = false,
202	boolean mutabilitySet = false,
203	boolean virtualSet = false,
204	boolean overrideSpecifierSet = false,
205	boolean hasParameters = false
206]
207:
208	kind=Fallback LParen (parameterList { $hasParameters = true; } )? RParen
209	(
210		{!$visibilitySet}? External {$visibilitySet = true;}
211		| {!$mutabilitySet}? stateMutability {$mutabilitySet = true;}
212		| modifierInvocation
213		| {!$virtualSet}? Virtual {$virtualSet = true;}
214		| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}
215	)*
216	( {$hasParameters}? Returns LParen returnParameters=parameterList RParen | {!$hasParameters}? )
217	(Semicolon | body=block);
218
219/**
220 * Definition of the special receive function.
221 */
222receiveFunctionDefinition
223locals[
224	boolean visibilitySet = false,
225	boolean mutabilitySet = false,
226	boolean virtualSet = false,
227	boolean overrideSpecifierSet = false
228]
229:
230	kind=Receive LParen RParen
231	(
232		{!$visibilitySet}? External {$visibilitySet = true;}
233		| {!$mutabilitySet}? Payable {$mutabilitySet = true;}
234		| modifierInvocation
235		| {!$virtualSet}? Virtual {$virtualSet = true;}
236		| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}
237	 )*
238	(Semicolon | body=block);
239
240/**
241 * Definition of a struct. Can occur at top-level within a source unit or within a contract, library or interface.
242 */
243structDefinition: Struct name=identifier LBrace members=structMember+ RBrace;
244/**
245 * The declaration of a named struct member.
246 */
247structMember: type=typeName name=identifier Semicolon;
248/**
249 * Definition of an enum. Can occur at top-level within a source unit or within a contract, library or interface.
250 */
251enumDefinition:	Enum name=identifier LBrace enumValues+=identifier (Comma enumValues+=identifier)* RBrace;
252/**
253 * Definition of a user defined value type. Can occur at top-level within a source unit or within a contract, library or interface.
254 */
255userDefinedValueTypeDefinition:
256	Type name=identifier Is elementaryTypeName[true] Semicolon;
257
258/**
259 * The declaration of a state variable.
260 */
261stateVariableDeclaration
262locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean overrideSpecifierSet = false]
263:
264	type=typeName
265	(
266		{!$visibilitySet}? Public {$visibilitySet = true;}
267		| {!$visibilitySet}? Private {$visibilitySet = true;}
268		| {!$visibilitySet}? Internal {$visibilitySet = true;}
269		| {!$constantnessSet}? Constant {$constantnessSet = true;}
270		| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}
271		| {!$constantnessSet}? Immutable {$constantnessSet = true;}
272	)*
273	name=identifier
274	(Assign initialValue=expression)?
275	Semicolon;
276
277/**
278 * The declaration of a constant variable.
279 */
280constantVariableDeclaration
281:
282	type=typeName
283	Constant
284	name=identifier
285	Assign initialValue=expression
286	Semicolon;
287
288/**
289 * Parameter of an event.
290 */
291eventParameter: type=typeName Indexed? name=identifier?;
292/**
293 * Definition of an event. Can occur in contracts, libraries or interfaces.
294 */
295eventDefinition:
296	Event name=identifier
297	LParen (parameters+=eventParameter (Comma parameters+=eventParameter)*)? RParen
298	Anonymous?
299	Semicolon;
300
301/**
302 * Parameter of an error.
303 */
304errorParameter: type=typeName name=identifier?;
305/**
306 * Definition of an error.
307 */
308errorDefinition:
309	Error name=identifier
310	LParen (parameters+=errorParameter (Comma parameters+=errorParameter)*)? RParen
311	Semicolon;
312
313/**
314 * Using directive to bind library functions to types.
315 * Can occur within contracts and libraries.
316 */
317usingDirective: Using identifierPath For (Mul | typeName) Semicolon;
318/**
319 * A type name can be an elementary type, a function type, a mapping type, a user-defined type
320 * (e.g. a contract or struct) or an array type.
321 */
322typeName: elementaryTypeName[true] | functionTypeName | mappingType | identifierPath | typeName LBrack expression? RBrack;
323elementaryTypeName[boolean allowAddressPayable]: Address | {$allowAddressPayable}? Address Payable | Bool | String | Bytes | SignedIntegerType | UnsignedIntegerType | FixedBytes | Fixed | Ufixed;
324functionTypeName
325locals [boolean visibilitySet = false, boolean mutabilitySet = false]
326:
327	Function LParen (arguments=parameterList)? RParen
328	(
329		{!$visibilitySet}? visibility {$visibilitySet = true;}
330		| {!$mutabilitySet}? stateMutability {$mutabilitySet = true;}
331	)*
332	(Returns LParen returnParameters=parameterList RParen)?;
333
334/**
335 * The declaration of a single variable.
336 */
337variableDeclaration: type=typeName location=dataLocation? name=identifier;
338dataLocation: Memory | Storage | Calldata;
339
340/**
341 * Complex expression.
342 * Can be an index access, an index range access, a member access, a function call (with optional function call options),
343 * a type conversion, an unary or binary expression, a comparison or assignment, a ternary expression,
344 * a new-expression (i.e. a contract creation or the allocation of a dynamic memory array),
345 * a tuple, an inline array or a primary expression (i.e. an identifier, literal or type name).
346 */
347expression:
348	expression LBrack index=expression? RBrack # IndexAccess
349	| expression LBrack start=expression? Colon end=expression? RBrack # IndexRangeAccess
350	| expression Period (identifier | Address) # MemberAccess
351	| expression LBrace (namedArgument (Comma namedArgument)*)? RBrace # FunctionCallOptions
352	| expression callArgumentList # FunctionCall
353	| Payable callArgumentList # PayableConversion
354	| Type LParen typeName RParen # MetaType
355	| (Inc | Dec | Not | BitNot | Delete | Sub) expression # UnaryPrefixOperation
356	| expression (Inc | Dec) # UnarySuffixOperation
357	|<assoc=right> expression Exp expression # ExpOperation
358	| expression (Mul | Div | Mod) expression # MulDivModOperation
359	| expression (Add | Sub) expression # AddSubOperation
360	| expression (Shl | Sar | Shr) expression # ShiftOperation
361	| expression BitAnd expression # BitAndOperation
362	| expression BitXor expression # BitXorOperation
363	| expression BitOr expression # BitOrOperation
364	| expression (LessThan | GreaterThan | LessThanOrEqual | GreaterThanOrEqual) expression # OrderComparison
365	| expression (Equal | NotEqual) expression # EqualityComparison
366	| expression And expression # AndOperation
367	| expression Or expression # OrOperation
368	|<assoc=right> expression Conditional expression Colon expression # Conditional
369	|<assoc=right> expression assignOp expression # Assignment
370	| New typeName # NewExpression
371	| tupleExpression # Tuple
372	| inlineArrayExpression # InlineArray
373 	| (
374		identifier
375		| literal
376		| elementaryTypeName[false]
377	  ) # PrimaryExpression
378;
379
380//@doc:inline
381assignOp: Assign | AssignBitOr | AssignBitXor | AssignBitAnd | AssignShl | AssignSar | AssignShr | AssignAdd | AssignSub | AssignMul | AssignDiv | AssignMod;
382tupleExpression: LParen (expression? ( Comma expression?)* ) RParen;
383/**
384 * An inline array expression denotes a statically sized array of the common type of the contained expressions.
385 */
386inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack;
387
388/**
389 * Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers.
390 */
391identifier: Identifier | From | Error | Revert;
392
393literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral;
394booleanLiteral: True | False;
395/**
396 * A full string literal consists of either one or several consecutive quoted strings.
397 */
398stringLiteral: (NonEmptyStringLiteral | EmptyStringLiteral)+;
399/**
400 * A full hex string literal that consists of either one or several consecutive hex strings.
401 */
402hexStringLiteral: HexString+;
403/**
404 * A full unicode string literal that consists of either one or several consecutive unicode strings.
405 */
406unicodeStringLiteral: UnicodeStringLiteral+;
407
408/**
409 * Number literals can be decimal or hexadecimal numbers with an optional unit.
410 */
411numberLiteral: (DecimalNumber | HexNumber) NumberUnit?;
412/**
413 * A curly-braced block of statements. Opens its own scope.
414 */
415block:
416	LBrace ( statement | uncheckedBlock )* RBrace;
417
418uncheckedBlock: Unchecked block;
419
420statement:
421	block
422	| simpleStatement
423	| ifStatement
424	| forStatement
425	| whileStatement
426	| doWhileStatement
427	| continueStatement
428	| breakStatement
429	| tryStatement
430	| returnStatement
431	| emitStatement
432	| revertStatement
433	| assemblyStatement
434;
435
436//@doc:inline
437simpleStatement: variableDeclarationStatement | expressionStatement;
438/**
439 * If statement with optional else part.
440 */
441ifStatement: If LParen expression RParen statement (Else statement)?;
442/**
443 * For statement with optional init, condition and post-loop part.
444 */
445forStatement: For LParen (simpleStatement | Semicolon) (expressionStatement | Semicolon) expression? RParen statement;
446whileStatement: While LParen expression RParen statement;
447doWhileStatement: Do statement While LParen expression RParen Semicolon;
448/**
449 * A continue statement. Only allowed inside for, while or do-while loops.
450 */
451continueStatement: Continue Semicolon;
452/**
453 * A break statement. Only allowed inside for, while or do-while loops.
454 */
455breakStatement: Break Semicolon;
456/**
457 * A try statement. The contained expression needs to be an external function call or a contract creation.
458 */
459tryStatement: Try expression (Returns LParen returnParameters=parameterList RParen)? block catchClause+;
460/**
461 * The catch clause of a try statement.
462 */
463catchClause: Catch (identifier? LParen (arguments=parameterList) RParen)? block;
464
465returnStatement: Return expression? Semicolon;
466/**
467 * An emit statement. The contained expression needs to refer to an event.
468 */
469emitStatement: Emit expression callArgumentList Semicolon;
470/**
471 * A revert statement. The contained expression needs to refer to an error.
472 */
473revertStatement: Revert expression callArgumentList Semicolon;
474/**
475 * An inline assembly block.
476 * The contents of an inline assembly block use a separate scanner/lexer, i.e. the set of keywords and
477 * allowed identifiers is different inside an inline assembly block.
478 */
479assemblyStatement: Assembly AssemblyDialect? AssemblyLBrace yulStatement* YulRBrace;
480
481//@doc:inline
482variableDeclarationList: variableDeclarations+=variableDeclaration (Comma variableDeclarations+=variableDeclaration)*;
483/**
484 * A tuple of variable names to be used in variable declarations.
485 * May contain empty fields.
486 */
487variableDeclarationTuple:
488	LParen
489		(Comma* variableDeclarations+=variableDeclaration)
490		(Comma (variableDeclarations+=variableDeclaration)?)*
491	RParen;
492/**
493 * A variable declaration statement.
494 * A single variable may be declared without initial value, whereas a tuple of variables can only be
495 * declared with initial value.
496 */
497variableDeclarationStatement: ((variableDeclaration (Assign expression)?) | (variableDeclarationTuple Assign expression)) Semicolon;
498expressionStatement: expression Semicolon;
499
500mappingType: Mapping LParen key=mappingKeyType DoubleArrow value=typeName RParen;
501/**
502 * Only elementary types or user defined types are viable as mapping keys.
503 */
504mappingKeyType: elementaryTypeName[false] | identifierPath;
505
506/**
507 * A Yul statement within an inline assembly block.
508 * continue and break statements are only valid within for loops.
509 * leave statements are only valid within function bodies.
510 */
511yulStatement:
512	yulBlock
513	| yulVariableDeclaration
514	| yulAssignment
515	| yulFunctionCall
516	| yulIfStatement
517	| yulForStatement
518	| yulSwitchStatement
519	| YulLeave
520	| YulBreak
521	| YulContinue
522	| yulFunctionDefinition;
523
524yulBlock: YulLBrace yulStatement* YulRBrace;
525
526/**
527 * The declaration of one or more Yul variables with optional initial value.
528 * If multiple variables are declared, only a function call is a valid initial value.
529 */
530yulVariableDeclaration:
531	(YulLet variables+=YulIdentifier (YulAssign yulExpression)?)
532	| (YulLet variables+=YulIdentifier (YulComma variables+=YulIdentifier)* (YulAssign yulFunctionCall)?);
533
534/**
535 * Any expression can be assigned to a single Yul variable, whereas
536 * multi-assignments require a function call on the right-hand side.
537 */
538yulAssignment: yulPath YulAssign yulExpression | (yulPath (YulComma yulPath)+) YulAssign yulFunctionCall;
539
540yulIfStatement: YulIf cond=yulExpression body=yulBlock;
541
542yulForStatement: YulFor init=yulBlock cond=yulExpression post=yulBlock body=yulBlock;
543
544//@doc:inline
545yulSwitchCase: YulCase yulLiteral yulBlock;
546/**
547 * A Yul switch statement can consist of only a default-case (deprecated) or
548 * one or more non-default cases optionally followed by a default-case.
549 */
550yulSwitchStatement:
551	YulSwitch yulExpression
552	(
553		(yulSwitchCase+ (YulDefault yulBlock)?)
554		| (YulDefault yulBlock)
555	);
556
557yulFunctionDefinition:
558	YulFunction YulIdentifier
559	YulLParen (arguments+=YulIdentifier (YulComma arguments+=YulIdentifier)*)? YulRParen
560	(YulArrow returnParameters+=YulIdentifier (YulComma returnParameters+=YulIdentifier)*)?
561	body=yulBlock;
562
563/**
564 * While only identifiers without dots can be declared within inline assembly,
565 * paths containing dots can refer to declarations outside the inline assembly block.
566 */
567yulPath: YulIdentifier (YulPeriod YulIdentifier)*;
568/**
569 * A call to a function with return values can only occur as right-hand side of an assignment or
570 * a variable declaration.
571 */
572yulFunctionCall: (YulIdentifier | YulEVMBuiltin) YulLParen (yulExpression (YulComma yulExpression)*)? YulRParen;
573yulBoolean: YulTrue | YulFalse;
574yulLiteral: YulDecimalNumber | YulStringLiteral | YulHexNumber | yulBoolean | YulHexStringLiteral;
575yulExpression: yulPath | yulFunctionCall | yulLiteral;
576