Revision ace5e5f48c6ec6e7254b9b4f83e722e31be24302 authored by Chris Cranford on 20 February 2024, 10:13:11 UTC, committed by GitHub on 20 February 2024, 10:13:11 UTC
1 parent 247de8e
Solidity.g4
// Copyright 2016-2017 Federico Bond <federicobond@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Copied from https://solidity.readthedocs.io/en/latest/grammar.html
// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false
// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging
grammar Solidity;
sourceUnit
: (pragmaDirective | importDirective | structDefinition | enumDefinition | contractDefinition)* EOF
;
pragmaDirective
: 'pragma' pragmaName pragmaValue ';'
;
pragmaName
: identifier
;
pragmaValue
: version
| expression
;
version
: versionConstraint versionConstraint?
;
versionConstraint
: versionOperator? VersionLiteral
;
versionOperator
: '^'
| '~'
| '>='
| '>'
| '<'
| '<='
| '='
;
importDirective
: 'import' StringLiteralFragment ('as' identifier)? ';'
| 'import' ('*' | identifier) ('as' identifier)? 'from' StringLiteralFragment ';'
| 'import' '{' importDeclaration (',' importDeclaration)* '}' 'from' StringLiteralFragment ';'
;
importDeclaration
: identifier ('as' identifier)?
;
contractDefinition
: 'abstract'? ('contract' | 'interface' | 'library') identifier (
'is' inheritanceSpecifier (',' inheritanceSpecifier)*
)? '{' contractPart* '}'
;
inheritanceSpecifier
: userDefinedTypeName ('(' expressionList? ')')?
;
contractPart
: stateVariableDeclaration
| usingForDeclaration
| structDefinition
| modifierDefinition
| functionDefinition
| eventDefinition
| enumDefinition
;
stateVariableDeclaration
: typeName (
PublicKeyword
| InternalKeyword
| PrivateKeyword
| ConstantKeyword
| ImmutableKeyword
| overrideSpecifier
)* identifier ('=' expression)? ';'
;
overrideSpecifier
: 'override' ('(' userDefinedTypeName (',' userDefinedTypeName)* ')')?
;
usingForDeclaration
: 'using' identifier 'for' ('*' | typeName) ';'
;
structDefinition
: 'struct' identifier '{' (variableDeclaration ';' (variableDeclaration ';')*)? '}'
;
modifierDefinition
: 'modifier' identifier parameterList? (VirtualKeyword | overrideSpecifier)* (';' | block)
;
functionDefinition
: functionDescriptor parameterList modifierList returnParameters? (';' | block)
;
functionDescriptor
: 'function' (identifier | ReceiveKeyword | FallbackKeyword)?
| ConstructorKeyword
| FallbackKeyword
| ReceiveKeyword
;
returnParameters
: 'returns' parameterList
;
modifierList
: (
modifierInvocation
| stateMutability
| ExternalKeyword
| PublicKeyword
| InternalKeyword
| PrivateKeyword
| VirtualKeyword
| overrideSpecifier
)*
;
modifierInvocation
: identifier ('(' expressionList? ')')?
;
eventDefinition
: 'event' identifier eventParameterList AnonymousKeyword? ';'
;
enumDefinition
: 'enum' identifier '{' enumValue? (',' enumValue)* '}'
;
enumValue
: identifier
;
parameterList
: '(' (parameter (',' parameter)*)? ')'
;
parameter
: typeName storageLocation? identifier?
;
eventParameterList
: '(' (eventParameter (',' eventParameter)*)? ')'
;
eventParameter
: typeName IndexedKeyword? identifier?
;
variableDeclaration
: typeName storageLocation? identifier
;
typeName
: elementaryTypeName
| userDefinedTypeName
| mapping
| typeName '[' expression? ']'
| functionTypeName
;
userDefinedTypeName
: identifier ('.' identifier)*
;
mapping
: 'mapping' '(' (elementaryTypeName | userDefinedTypeName) '=>' typeName ')'
;
functionTypeName
: 'function' parameterList modifierList returnParameters?
;
storageLocation
: 'memory'
| 'storage'
| 'calldata'
;
stateMutability
: PureKeyword
| ConstantKeyword
| ViewKeyword
| PayableKeyword
;
block
: '{' statement* '}'
;
statement
: ifStatement
| tryStatement
| whileStatement
| forStatement
| block
| inlineAssemblyStatement
| doWhileStatement
| continueStatement
| breakStatement
| returnStatement
| throwStatement
| emitStatement
| simpleStatement
;
expressionStatement
: expression ';'
;
ifStatement
: 'if' '(' expression ')' statement ('else' statement)?
;
tryStatement
: 'try' expression returnParameters? block catchClause+
;
// In reality catch clauses still are not processed as below
// the identifier can only be a set string: "Error". But plans
// of the Solidity team include possible expansion so we'll
// leave this as is, befitting with the Solidity docs.
catchClause
: 'catch' (identifier? parameterList)? block
;
whileStatement
: 'while' '(' expression ')' statement
;
forStatement
: 'for' '(' (simpleStatement | ';') (expressionStatement | ';') expression? ')' statement
;
simpleStatement
: (variableDeclarationStatement | expressionStatement)
;
inlineAssemblyStatement
: 'assembly' StringLiteralFragment? assemblyBlock
;
doWhileStatement
: 'do' statement 'while' '(' expression ')' ';'
;
continueStatement
: 'continue' ';'
;
breakStatement
: 'break' ';'
;
returnStatement
: 'return' expression? ';'
;
// throw is no longer supported by latest Solidity.
throwStatement
: 'throw' ';'
;
emitStatement
: 'emit' functionCall ';'
;
// 'var' is no longer supported by latest Solidity.
variableDeclarationStatement
: ('var' identifierList | variableDeclaration | '(' variableDeclarationList ')') (
'=' expression
)? ';'
;
variableDeclarationList
: variableDeclaration? (',' variableDeclaration?)*
;
identifierList
: '(' (identifier? ',')* identifier? ')'
;
elementaryTypeName
: 'address' PayableKeyword?
| 'bool'
| 'string'
| 'var'
| Int
| Uint
| 'byte'
| Byte
| Fixed
| Ufixed
;
Int
: 'int'
| 'int8'
| 'int16'
| 'int24'
| 'int32'
| 'int40'
| 'int48'
| 'int56'
| 'int64'
| 'int72'
| 'int80'
| 'int88'
| 'int96'
| 'int104'
| 'int112'
| 'int120'
| 'int128'
| 'int136'
| 'int144'
| 'int152'
| 'int160'
| 'int168'
| 'int176'
| 'int184'
| 'int192'
| 'int200'
| 'int208'
| 'int216'
| 'int224'
| 'int232'
| 'int240'
| 'int248'
| 'int256'
;
Uint
: 'uint'
| 'uint8'
| 'uint16'
| 'uint24'
| 'uint32'
| 'uint40'
| 'uint48'
| 'uint56'
| 'uint64'
| 'uint72'
| 'uint80'
| 'uint88'
| 'uint96'
| 'uint104'
| 'uint112'
| 'uint120'
| 'uint128'
| 'uint136'
| 'uint144'
| 'uint152'
| 'uint160'
| 'uint168'
| 'uint176'
| 'uint184'
| 'uint192'
| 'uint200'
| 'uint208'
| 'uint216'
| 'uint224'
| 'uint232'
| 'uint240'
| 'uint248'
| 'uint256'
;
Byte
: 'bytes'
| 'bytes1'
| 'bytes2'
| 'bytes3'
| 'bytes4'
| 'bytes5'
| 'bytes6'
| 'bytes7'
| 'bytes8'
| 'bytes9'
| 'bytes10'
| 'bytes11'
| 'bytes12'
| 'bytes13'
| 'bytes14'
| 'bytes15'
| 'bytes16'
| 'bytes17'
| 'bytes18'
| 'bytes19'
| 'bytes20'
| 'bytes21'
| 'bytes22'
| 'bytes23'
| 'bytes24'
| 'bytes25'
| 'bytes26'
| 'bytes27'
| 'bytes28'
| 'bytes29'
| 'bytes30'
| 'bytes31'
| 'bytes32'
;
Fixed
: 'fixed'
| ( 'fixed' [0-9]+ 'x' [0-9]+)
;
Ufixed
: 'ufixed'
| ( 'ufixed' [0-9]+ 'x' [0-9]+)
;
expression
: expression ('++' | '--')
| 'new' typeName
| expression '[' expression? ']'
| expression '[' expression? ':' expression? ']'
| expression '.' identifier
| expression '{' nameValueList '}'
| expression '(' functionCallArguments ')'
| PayableKeyword '(' expression ')'
| '(' expression ')'
| ('++' | '--') expression
| ('+' | '-') expression
| ('after' | 'delete') expression
| '!' expression
| '~' expression
| expression '**' expression
| expression ('*' | '/' | '%') expression
| expression ('+' | '-') expression
| expression ('<<' | '>>') expression
| expression '&' expression
| expression '^' expression
| expression '|' expression
| expression ('<' | '>' | '<=' | '>=') expression
| expression ('==' | '!=') expression
| expression '&&' expression
| expression '||' expression
| expression '?' expression ':' expression
| expression ('=' | '|=' | '^=' | '&=' | '<<=' | '>>=' | '+=' | '-=' | '*=' | '/=' | '%=') expression
| primaryExpression
;
primaryExpression
: BooleanLiteral
| numberLiteral
| hexLiteral
| stringLiteral
| identifier ('[' ']')?
| TypeKeyword
| tupleExpression
| typeNameExpression ('[' ']')?
;
expressionList
: expression (',' expression)*
;
nameValueList
: nameValue (',' nameValue)* ','?
;
nameValue
: identifier ':' expression
;
functionCallArguments
: '{' nameValueList? '}'
| expressionList?
;
functionCall
: expression '(' functionCallArguments ')'
;
tupleExpression
: '(' (expression? ( ',' expression?)*) ')'
| '[' ( expression ( ',' expression)*)? ']'
;
typeNameExpression
: elementaryTypeName
| userDefinedTypeName
;
assemblyItem
: identifier
| assemblyBlock
| assemblyExpression
| assemblyLocalDefinition
| assemblyAssignment
| assemblyStackAssignment
| labelDefinition
| assemblySwitch
| assemblyFunctionDefinition
| assemblyFor
| assemblyIf
| BreakKeyword
| ContinueKeyword
| LeaveKeyword
| subAssembly
| numberLiteral
| stringLiteral
| hexLiteral
;
assemblyBlock
: '{' assemblyItem* '}'
;
assemblyExpression
: assemblyCall
| assemblyLiteral
;
assemblyCall
: ('return' | 'address' | 'byte' | identifier) (
'(' assemblyExpression? ( ',' assemblyExpression)* ')'
)?
;
assemblyLocalDefinition
: 'let' assemblyIdentifierList (':=' assemblyExpression)?
;
assemblyAssignment
: assemblyIdentifierList ':=' assemblyExpression
;
assemblyIdentifierList
: identifier (',' identifier)*
;
assemblyStackAssignment
: '=:' identifier
;
labelDefinition
: identifier ':'
;
assemblySwitch
: 'switch' assemblyExpression assemblyCase*
;
assemblyCase
: 'case' assemblyLiteral assemblyType? assemblyBlock
| 'default' assemblyBlock
;
assemblyFunctionDefinition
: 'function' identifier '(' assemblyTypedVariableList? ')' assemblyFunctionReturns? assemblyBlock
;
assemblyFunctionReturns
: ('-' '>' assemblyTypedVariableList)
;
assemblyFor
: 'for' assemblyBlock assemblyExpression assemblyBlock assemblyBlock
;
assemblyIf
: 'if' assemblyExpression assemblyBlock
;
assemblyLiteral
: (stringLiteral | DecimalNumber | HexNumber | hexLiteral | BooleanLiteral) assemblyType?
;
assemblyTypedVariableList
: identifier assemblyType? (',' assemblyTypedVariableList)?
;
assemblyType
: ':' identifier
;
subAssembly
: 'assembly' identifier assemblyBlock
;
numberLiteral
: (DecimalNumber | HexNumber) NumberUnit?
;
identifier
: ('from' | 'calldata' | 'address' | Identifier)
;
BooleanLiteral
: 'true'
| 'false'
;
DecimalNumber
: (DecimalDigits | (DecimalDigits? '.' DecimalDigits)) ([eE] '-'? DecimalDigits)?
;
fragment DecimalDigits
: [0-9] ('_'? [0-9])*
;
HexNumber
: '0' [xX] HexDigits
;
fragment HexDigits
: HexCharacter ('_'? HexCharacter)*
;
NumberUnit
: 'wei'
| 'szabo'
| 'finney'
| 'ether'
| 'seconds'
| 'minutes'
| 'hours'
| 'days'
| 'weeks'
| 'years'
;
HexLiteralFragment
: 'hex' (('"' HexDigits? '"') | ('\'' HexDigits? '\''))
;
hexLiteral
: HexLiteralFragment+
;
fragment HexPair
: HexCharacter HexCharacter
;
fragment HexCharacter
: [0-9A-Fa-f]
;
ReservedKeyword
: 'after'
| 'case'
| 'default'
| 'final'
| 'in'
| 'inline'
| 'let'
| 'match'
| 'null'
| 'of'
| 'relocatable'
| 'static'
| 'switch'
| 'typeof'
;
AnonymousKeyword
: 'anonymous'
;
BreakKeyword
: 'break'
;
ConstantKeyword
: 'constant'
;
ImmutableKeyword
: 'immutable'
;
ContinueKeyword
: 'continue'
;
LeaveKeyword
: 'leave'
;
ExternalKeyword
: 'external'
;
IndexedKeyword
: 'indexed'
;
InternalKeyword
: 'internal'
;
PayableKeyword
: 'payable'
;
PrivateKeyword
: 'private'
;
PublicKeyword
: 'public'
;
VirtualKeyword
: 'virtual'
;
PureKeyword
: 'pure'
;
TypeKeyword
: 'type'
;
ViewKeyword
: 'view'
;
ConstructorKeyword
: 'constructor'
;
FallbackKeyword
: 'fallback'
;
ReceiveKeyword
: 'receive'
;
Identifier
: IdentifierStart IdentifierPart*
;
fragment IdentifierStart
: [a-zA-Z$_]
;
fragment IdentifierPart
: [a-zA-Z0-9$_]
;
stringLiteral
: StringLiteralFragment+
;
StringLiteralFragment
: '"' DoubleQuotedStringCharacter* '"'
| '\'' SingleQuotedStringCharacter* '\''
;
fragment DoubleQuotedStringCharacter
: ~["\r\n\\]
| ('\\' .)
;
fragment SingleQuotedStringCharacter
: ~['\r\n\\]
| ('\\' .)
;
VersionLiteral
: [0-9]+ '.' [0-9]+ ('.' [0-9]+)?
;
WS
: [ \t\r\n\u000C]+ -> skip
;
COMMENT
: '/*' .*? '*/' -> channel(HIDDEN)
;
LINE_COMMENT
: '//' ~[\r\n]* -> channel(HIDDEN)
;
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...