2020-08-12 01:05:53 +00:00
|
|
|
lexer grammar SolidityLexer;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Keywords reserved for future use in Solidity.
|
|
|
|
*/
|
|
|
|
ReservedKeywords:
|
2020-12-14 15:10:00 +00:00
|
|
|
'after' | 'alias' | 'apply' | 'auto' | 'byte' | 'case' | 'copyof' | 'default' | 'define' | 'final'
|
2020-08-12 01:05:53 +00:00
|
|
|
| 'implements' | 'in' | 'inline' | 'let' | 'macro' | 'match' | 'mutable' | 'null' | 'of'
|
|
|
|
| 'partial' | 'promise' | 'reference' | 'relocatable' | 'sealed' | 'sizeof' | 'static'
|
2020-09-16 10:55:24 +00:00
|
|
|
| 'supports' | 'switch' | 'typedef' | 'typeof' | 'var';
|
2020-08-12 01:05:53 +00:00
|
|
|
|
|
|
|
Abstract: 'abstract';
|
|
|
|
Address: 'address';
|
2022-05-29 15:15:48 +00:00
|
|
|
Anonymous: 'anonymous';
|
2020-08-12 01:05:53 +00:00
|
|
|
As: 'as';
|
|
|
|
Assembly: 'assembly' -> pushMode(AssemblyBlockMode);
|
|
|
|
Bool: 'bool';
|
|
|
|
Break: 'break';
|
|
|
|
Bytes: 'bytes';
|
|
|
|
Calldata: 'calldata';
|
|
|
|
Catch: 'catch';
|
|
|
|
Constant: 'constant';
|
|
|
|
Constructor: 'constructor';
|
|
|
|
Continue: 'continue';
|
|
|
|
Contract: 'contract';
|
|
|
|
Delete: 'delete';
|
|
|
|
Do: 'do';
|
|
|
|
Else: 'else';
|
|
|
|
Emit: 'emit';
|
|
|
|
Enum: 'enum';
|
2021-01-28 11:56:22 +00:00
|
|
|
Error: 'error'; // not a real keyword
|
2020-08-12 01:05:53 +00:00
|
|
|
Event: 'event';
|
|
|
|
External: 'external';
|
|
|
|
Fallback: 'fallback';
|
|
|
|
False: 'false';
|
2020-12-14 13:09:28 +00:00
|
|
|
Fixed: 'fixed' | ('fixed' [1-9][0-9]* 'x' [1-9][0-9]*);
|
2020-08-12 01:05:53 +00:00
|
|
|
/**
|
|
|
|
* Bytes types of fixed length.
|
|
|
|
*/
|
|
|
|
FixedBytes:
|
2020-12-14 15:10:00 +00:00
|
|
|
'bytes1' | 'bytes2' | 'bytes3' | 'bytes4' | 'bytes5' | 'bytes6' | 'bytes7' | 'bytes8' |
|
2020-08-12 01:05:53 +00:00
|
|
|
'bytes9' | 'bytes10' | 'bytes11' | 'bytes12' | 'bytes13' | 'bytes14' | 'bytes15' | 'bytes16' |
|
|
|
|
'bytes17' | 'bytes18' | 'bytes19' | 'bytes20' | 'bytes21' | 'bytes22' | 'bytes23' | 'bytes24' |
|
|
|
|
'bytes25' | 'bytes26' | 'bytes27' | 'bytes28' | 'bytes29' | 'bytes30' | 'bytes31' | 'bytes32';
|
|
|
|
For: 'for';
|
2022-05-29 15:15:48 +00:00
|
|
|
From: 'from'; // not a real keyword
|
2020-08-12 01:05:53 +00:00
|
|
|
Function: 'function';
|
2021-11-16 16:01:09 +00:00
|
|
|
Global: 'global'; // not a real keyword
|
2020-08-12 01:05:53 +00:00
|
|
|
Hex: 'hex';
|
|
|
|
If: 'if';
|
|
|
|
Immutable: 'immutable';
|
|
|
|
Import: 'import';
|
|
|
|
Indexed: 'indexed';
|
|
|
|
Interface: 'interface';
|
|
|
|
Internal: 'internal';
|
|
|
|
Is: 'is';
|
|
|
|
Library: 'library';
|
|
|
|
Mapping: 'mapping';
|
|
|
|
Memory: 'memory';
|
|
|
|
Modifier: 'modifier';
|
|
|
|
New: 'new';
|
|
|
|
/**
|
|
|
|
* Unit denomination for numbers.
|
|
|
|
*/
|
2023-03-20 19:49:39 +00:00
|
|
|
SubDenomination: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years';
|
2020-08-12 01:05:53 +00:00
|
|
|
Override: 'override';
|
|
|
|
Payable: 'payable';
|
2022-05-29 15:15:48 +00:00
|
|
|
Pragma: 'pragma' -> pushMode(PragmaMode);
|
2020-08-12 01:05:53 +00:00
|
|
|
Private: 'private';
|
|
|
|
Public: 'public';
|
|
|
|
Pure: 'pure';
|
|
|
|
Receive: 'receive';
|
|
|
|
Return: 'return';
|
|
|
|
Returns: 'returns';
|
2022-05-29 15:15:48 +00:00
|
|
|
Revert: 'revert'; // not a real keyword
|
2020-08-12 01:05:53 +00:00
|
|
|
/**
|
|
|
|
* Sized signed integer types.
|
|
|
|
* int is an alias of int256.
|
|
|
|
*/
|
|
|
|
SignedIntegerType:
|
|
|
|
'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';
|
|
|
|
Storage: 'storage';
|
|
|
|
String: 'string';
|
|
|
|
Struct: 'struct';
|
|
|
|
True: 'true';
|
|
|
|
Try: 'try';
|
|
|
|
Type: 'type';
|
2020-12-14 13:09:28 +00:00
|
|
|
Ufixed: 'ufixed' | ('ufixed' [1-9][0-9]+ 'x' [1-9][0-9]+);
|
2020-09-16 10:55:24 +00:00
|
|
|
Unchecked: 'unchecked';
|
2023-03-25 20:04:02 +00:00
|
|
|
Unicode: 'unicode';
|
2020-08-12 01:05:53 +00:00
|
|
|
/**
|
|
|
|
* Sized unsigned integer types.
|
|
|
|
* uint is an alias of uint256.
|
|
|
|
*/
|
|
|
|
UnsignedIntegerType:
|
|
|
|
'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';
|
|
|
|
Using: 'using';
|
|
|
|
View: 'view';
|
|
|
|
Virtual: 'virtual';
|
|
|
|
While: 'while';
|
|
|
|
|
|
|
|
LParen: '(';
|
|
|
|
RParen: ')';
|
|
|
|
LBrack: '[';
|
|
|
|
RBrack: ']';
|
|
|
|
LBrace: '{';
|
|
|
|
RBrace: '}';
|
|
|
|
Colon: ':';
|
|
|
|
Semicolon: ';';
|
|
|
|
Period: '.';
|
|
|
|
Conditional: '?';
|
2020-08-27 10:42:00 +00:00
|
|
|
DoubleArrow: '=>';
|
2020-08-12 17:56:24 +00:00
|
|
|
RightArrow: '->';
|
2020-08-12 01:05:53 +00:00
|
|
|
|
|
|
|
Assign: '=';
|
|
|
|
AssignBitOr: '|=';
|
|
|
|
AssignBitXor: '^=';
|
|
|
|
AssignBitAnd: '&=';
|
|
|
|
AssignShl: '<<=';
|
|
|
|
AssignSar: '>>=';
|
|
|
|
AssignShr: '>>>=';
|
|
|
|
AssignAdd: '+=';
|
|
|
|
AssignSub: '-=';
|
|
|
|
AssignMul: '*=';
|
|
|
|
AssignDiv: '/=';
|
|
|
|
AssignMod: '%=';
|
|
|
|
|
|
|
|
Comma: ',';
|
|
|
|
Or: '||';
|
|
|
|
And: '&&';
|
|
|
|
BitOr: '|';
|
|
|
|
BitXor: '^';
|
|
|
|
BitAnd: '&';
|
|
|
|
Shl: '<<';
|
|
|
|
Sar: '>>';
|
|
|
|
Shr: '>>>';
|
|
|
|
Add: '+';
|
|
|
|
Sub: '-';
|
|
|
|
Mul: '*';
|
|
|
|
Div: '/';
|
|
|
|
Mod: '%';
|
|
|
|
Exp: '**';
|
|
|
|
|
|
|
|
Equal: '==';
|
|
|
|
NotEqual: '!=';
|
|
|
|
LessThan: '<';
|
|
|
|
GreaterThan: '>';
|
|
|
|
LessThanOrEqual: '<=';
|
|
|
|
GreaterThanOrEqual: '>=';
|
|
|
|
Not: '!';
|
|
|
|
BitNot: '~';
|
|
|
|
Inc: '++';
|
|
|
|
Dec: '--';
|
2021-04-08 20:40:49 +00:00
|
|
|
//@doc:inline
|
|
|
|
DoubleQuote: '"';
|
|
|
|
//@doc:inline
|
|
|
|
SingleQuote: '\'';
|
2020-08-12 01:05:53 +00:00
|
|
|
|
|
|
|
/**
|
2021-04-08 20:40:49 +00:00
|
|
|
* A non-empty quoted string literal restricted to printable characters.
|
2020-08-12 01:05:53 +00:00
|
|
|
*/
|
2021-04-08 20:40:49 +00:00
|
|
|
NonEmptyStringLiteral: '"' DoubleQuotedStringCharacter+ '"' | '\'' SingleQuotedStringCharacter+ '\'';
|
2020-08-12 01:05:53 +00:00
|
|
|
/**
|
2021-04-08 20:40:49 +00:00
|
|
|
* An empty string literal
|
2020-08-12 01:05:53 +00:00
|
|
|
*/
|
2021-04-08 20:40:49 +00:00
|
|
|
EmptyStringLiteral: '"' '"' | '\'' '\'';
|
|
|
|
|
2020-08-12 01:05:53 +00:00
|
|
|
// Note that this will also be used for Yul string literals.
|
|
|
|
//@doc:inline
|
|
|
|
fragment DoubleQuotedStringCharacter: DoubleQuotedPrintable | EscapeSequence;
|
|
|
|
// Note that this will also be used for Yul string literals.
|
|
|
|
//@doc:inline
|
|
|
|
fragment SingleQuotedStringCharacter: SingleQuotedPrintable | EscapeSequence;
|
|
|
|
/**
|
|
|
|
* Any printable character except single quote or back slash.
|
|
|
|
*/
|
|
|
|
fragment SingleQuotedPrintable: [\u0020-\u0026\u0028-\u005B\u005D-\u007E];
|
|
|
|
/**
|
|
|
|
* Any printable character except double quote or back slash.
|
|
|
|
*/
|
|
|
|
fragment DoubleQuotedPrintable: [\u0020-\u0021\u0023-\u005B\u005D-\u007E];
|
|
|
|
/**
|
|
|
|
* Escape sequence.
|
|
|
|
* Apart from common single character escape sequences, line breaks can be escaped
|
|
|
|
* as well as four hex digit unicode escapes \\uXXXX and two digit hex escape sequences \\xXX are allowed.
|
|
|
|
*/
|
|
|
|
fragment EscapeSequence:
|
|
|
|
'\\' (
|
2020-11-25 15:29:40 +00:00
|
|
|
['"\\nrt\n\r]
|
2020-08-12 01:05:53 +00:00
|
|
|
| 'u' HexCharacter HexCharacter HexCharacter HexCharacter
|
|
|
|
| 'x' HexCharacter HexCharacter
|
|
|
|
);
|
|
|
|
/**
|
|
|
|
* A single quoted string literal allowing arbitrary unicode characters.
|
|
|
|
*/
|
2023-03-11 08:29:45 +00:00
|
|
|
UnicodeStringLiteral: 'unicode' (('"' DoubleQuotedUnicodeStringCharacter* '"') | ('\'' SingleQuotedUnicodeStringCharacter* '\''));
|
2020-08-12 01:05:53 +00:00
|
|
|
//@doc:inline
|
|
|
|
fragment DoubleQuotedUnicodeStringCharacter: ~["\r\n\\] | EscapeSequence;
|
|
|
|
//@doc:inline
|
|
|
|
fragment SingleQuotedUnicodeStringCharacter: ~['\r\n\\] | EscapeSequence;
|
|
|
|
|
2021-04-08 20:40:49 +00:00
|
|
|
// Note that this will also be used for Yul hex string literals.
|
2020-08-12 01:05:53 +00:00
|
|
|
/**
|
|
|
|
* Hex strings need to consist of an even number of hex digits that may be grouped using underscores.
|
|
|
|
*/
|
|
|
|
HexString: 'hex' (('"' EvenHexDigits? '"') | ('\'' EvenHexDigits? '\''));
|
|
|
|
/**
|
|
|
|
* Hex numbers consist of a prefix and an arbitrary number of hex digits that may be delimited by underscores.
|
|
|
|
*/
|
|
|
|
HexNumber: '0' 'x' HexDigits;
|
|
|
|
//@doc:inline
|
|
|
|
fragment HexDigits: HexCharacter ('_'? HexCharacter)*;
|
|
|
|
//@doc:inline
|
|
|
|
fragment EvenHexDigits: HexCharacter HexCharacter ('_'? HexCharacter HexCharacter)*;
|
|
|
|
//@doc:inline
|
|
|
|
fragment HexCharacter: [0-9A-Fa-f];
|
|
|
|
|
2023-03-20 19:49:39 +00:00
|
|
|
/**
|
|
|
|
* Scanned but not used by any rule, i.e, disallowed.
|
|
|
|
* solc parser considers number starting with '0', not immediately followed by '.' or 'x' as
|
|
|
|
* octal, even if non octal digits '8' and '9' are present.
|
|
|
|
*/
|
|
|
|
OctalNumber: '0' DecimalDigits ('.' DecimalDigits)?;
|
|
|
|
|
|
|
|
|
2020-08-12 01:05:53 +00:00
|
|
|
/**
|
|
|
|
* A decimal number literal consists of decimal digits that may be delimited by underscores and
|
|
|
|
* an optional positive or negative exponent.
|
|
|
|
* If the digits contain a decimal point, the literal has fixed point type.
|
|
|
|
*/
|
|
|
|
DecimalNumber: (DecimalDigits | (DecimalDigits? '.' DecimalDigits)) ([eE] '-'? DecimalDigits)?;
|
|
|
|
//@doc:inline
|
|
|
|
fragment DecimalDigits: [0-9] ('_'? [0-9])* ;
|
|
|
|
|
|
|
|
|
2023-03-20 19:49:39 +00:00
|
|
|
/**
|
|
|
|
* This is needed to avoid successfully parsing a number followed by a string with no whitespace between.
|
|
|
|
*/
|
|
|
|
DecimalNumberFollowedByIdentifier: DecimalNumber Identifier;
|
|
|
|
|
|
|
|
|
2020-08-12 01:05:53 +00:00
|
|
|
/**
|
|
|
|
* An identifier in solidity has to start with a letter, a dollar-sign or an underscore and
|
|
|
|
* may additionally contain numbers after the first symbol.
|
|
|
|
*/
|
|
|
|
Identifier: IdentifierStart IdentifierPart*;
|
|
|
|
//@doc:inline
|
|
|
|
fragment IdentifierStart: [a-zA-Z$_];
|
|
|
|
//@doc:inline
|
|
|
|
fragment IdentifierPart: [a-zA-Z0-9$_];
|
|
|
|
|
|
|
|
WS: [ \t\r\n\u000C]+ -> skip ;
|
|
|
|
COMMENT: '/*' .*? '*/' -> channel(HIDDEN) ;
|
|
|
|
LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN);
|
|
|
|
|
|
|
|
mode AssemblyBlockMode;
|
|
|
|
|
|
|
|
//@doc:inline
|
|
|
|
AssemblyDialect: '"evmasm"';
|
|
|
|
AssemblyLBrace: '{' -> popMode, pushMode(YulMode);
|
|
|
|
|
2022-02-14 12:57:56 +00:00
|
|
|
AssemblyFlagString: '"' DoubleQuotedStringCharacter+ '"';
|
|
|
|
|
|
|
|
AssemblyBlockLParen: '(';
|
|
|
|
AssemblyBlockRParen: ')';
|
|
|
|
AssemblyBlockComma: ',';
|
|
|
|
|
2020-08-12 01:05:53 +00:00
|
|
|
AssemblyBlockWS: [ \t\r\n\u000C]+ -> skip ;
|
|
|
|
AssemblyBlockCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ;
|
|
|
|
AssemblyBlockLINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN) ;
|
|
|
|
|
|
|
|
mode YulMode;
|
|
|
|
|
|
|
|
YulBreak: 'break';
|
|
|
|
YulCase: 'case';
|
|
|
|
YulContinue: 'continue';
|
|
|
|
YulDefault: 'default';
|
|
|
|
YulFalse: 'false';
|
|
|
|
YulFor: 'for';
|
|
|
|
YulFunction: 'function';
|
|
|
|
YulIf: 'if';
|
|
|
|
YulLeave: 'leave';
|
|
|
|
YulLet: 'let';
|
|
|
|
YulSwitch: 'switch';
|
|
|
|
YulTrue: 'true';
|
2021-03-25 16:00:05 +00:00
|
|
|
YulHex: 'hex';
|
2020-08-12 01:05:53 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Builtin functions in the EVM Yul dialect.
|
|
|
|
*/
|
|
|
|
YulEVMBuiltin:
|
|
|
|
'stop' | 'add' | 'sub' | 'mul' | 'div' | 'sdiv' | 'mod' | 'smod' | 'exp' | 'not'
|
|
|
|
| 'lt' | 'gt' | 'slt' | 'sgt' | 'eq' | 'iszero' | 'and' | 'or' | 'xor' | 'byte'
|
|
|
|
| 'shl' | 'shr' | 'sar' | 'addmod' | 'mulmod' | 'signextend' | 'keccak256'
|
|
|
|
| 'pop' | 'mload' | 'mstore' | 'mstore8' | 'sload' | 'sstore' | 'msize' | 'gas'
|
|
|
|
| 'address' | 'balance' | 'selfbalance' | 'caller' | 'callvalue' | 'calldataload'
|
|
|
|
| 'calldatasize' | 'calldatacopy' | 'extcodesize' | 'extcodecopy' | 'returndatasize'
|
|
|
|
| 'returndatacopy' | 'extcodehash' | 'create' | 'create2' | 'call' | 'callcode'
|
|
|
|
| 'delegatecall' | 'staticcall' | 'return' | 'revert' | 'selfdestruct' | 'invalid'
|
|
|
|
| 'log0' | 'log1' | 'log2' | 'log3' | 'log4' | 'chainid' | 'origin' | 'gasprice'
|
2022-11-23 10:51:34 +00:00
|
|
|
| 'blockhash' | 'coinbase' | 'timestamp' | 'number' | 'difficulty' | 'prevrandao'
|
|
|
|
| 'gaslimit' | 'basefee';
|
2020-08-12 01:05:53 +00:00
|
|
|
|
|
|
|
YulLBrace: '{' -> pushMode(YulMode);
|
|
|
|
YulRBrace: '}' -> popMode;
|
|
|
|
YulLParen: '(';
|
|
|
|
YulRParen: ')';
|
|
|
|
YulAssign: ':=';
|
|
|
|
YulPeriod: '.';
|
|
|
|
YulComma: ',';
|
2020-08-12 17:56:24 +00:00
|
|
|
YulArrow: '->';
|
2020-08-12 01:05:53 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Yul identifiers consist of letters, dollar signs, underscores and numbers, but may not start with a number.
|
|
|
|
* In inline assembly there cannot be dots in user-defined identifiers. Instead see yulPath for expressions
|
|
|
|
* consisting of identifiers with dots.
|
|
|
|
*/
|
|
|
|
YulIdentifier: YulIdentifierStart YulIdentifierPart*;
|
|
|
|
//@doc:inline
|
|
|
|
fragment YulIdentifierStart: [a-zA-Z$_];
|
|
|
|
//@doc:inline
|
|
|
|
fragment YulIdentifierPart: [a-zA-Z0-9$_];
|
|
|
|
/**
|
|
|
|
* Hex literals in Yul consist of a prefix and one or more hexadecimal digits.
|
|
|
|
*/
|
|
|
|
YulHexNumber: '0' 'x' [0-9a-fA-F]+;
|
|
|
|
/**
|
|
|
|
* Decimal literals in Yul may be zero or any sequence of decimal digits without leading zeroes.
|
|
|
|
*/
|
|
|
|
YulDecimalNumber: '0' | ([1-9] [0-9]*);
|
|
|
|
/**
|
|
|
|
* String literals in Yul consist of one or more double-quoted or single-quoted strings
|
|
|
|
* that may contain escape sequences and printable characters except unescaped line breaks or
|
|
|
|
* unescaped double-quotes or single-quotes, respectively.
|
|
|
|
*/
|
|
|
|
YulStringLiteral:
|
|
|
|
'"' DoubleQuotedStringCharacter* '"'
|
|
|
|
| '\'' SingleQuotedStringCharacter* '\'';
|
2021-04-08 20:40:49 +00:00
|
|
|
//@doc:inline
|
2021-03-25 16:00:05 +00:00
|
|
|
YulHexStringLiteral: HexString;
|
2020-08-12 01:05:53 +00:00
|
|
|
|
|
|
|
YulWS: [ \t\r\n\u000C]+ -> skip ;
|
|
|
|
YulCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ;
|
|
|
|
YulLINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN) ;
|
|
|
|
|
|
|
|
mode PragmaMode;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Pragma token. Can contain any kind of symbol except a semicolon.
|
|
|
|
* Note that currently the solidity parser only allows a subset of this.
|
|
|
|
*/
|
|
|
|
//@doc:name pragma-token
|
|
|
|
//@doc:no-diagram
|
|
|
|
PragmaToken: ~[;]+;
|
|
|
|
PragmaSemicolon: ';' -> popMode;
|
|
|
|
|
|
|
|
PragmaWS: [ \t\r\n\u000C]+ -> skip ;
|
|
|
|
PragmaCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ;
|
|
|
|
PragmaLINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN) ;
|