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