Merge pull request #14066 from ethereum/update_grammar

Update grammar `functionDefinition` parser rule and rename `NumberUnit` lexer rule
This commit is contained in:
Kamil Śliwak 2023-03-24 21:19:42 +01:00 committed by GitHub
commit 5dbfa9409b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 75 additions and 6 deletions

View File

@ -10,6 +10,9 @@ Compiler Features:
Bugfixes: Bugfixes:
* Antlr Grammar: Fix discrepancy with the parser, which allowed octal numbers.
* Antlr Grammar: Fix of a discrepancy with the parser, which allowed numbers followed by an identifier with no whitespace.
* Antlr Grammar: Stricter rules for function definitions. The grammar will no longer accept as valid free functions having specifiers which are exclusive to contract functions.
### 0.8.19 (2023-02-22) ### 0.8.19 (2023-02-22)

View File

@ -62,7 +62,7 @@ New: 'new';
/** /**
* Unit denomination for numbers. * Unit denomination for numbers.
*/ */
NumberUnit: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years'; SubDenomination: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years';
Override: 'override'; Override: 'override';
Payable: 'payable'; Payable: 'payable';
Pragma: 'pragma' -> pushMode(PragmaMode); Pragma: 'pragma' -> pushMode(PragmaMode);
@ -220,6 +220,14 @@ fragment EvenHexDigits: HexCharacter HexCharacter ('_'? HexCharacter HexCharacte
//@doc:inline //@doc:inline
fragment HexCharacter: [0-9A-Fa-f]; fragment HexCharacter: [0-9A-Fa-f];
/**
* 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)?;
/** /**
* A decimal number literal consists of decimal digits that may be delimited by underscores and * A decimal number literal consists of decimal digits that may be delimited by underscores and
* an optional positive or negative exponent. * an optional positive or negative exponent.
@ -230,6 +238,12 @@ DecimalNumber: (DecimalDigits | (DecimalDigits? '.' DecimalDigits)) ([eE] '-'? D
fragment DecimalDigits: [0-9] ('_'? [0-9])* ; fragment DecimalDigits: [0-9] ('_'? [0-9])* ;
/**
* This is needed to avoid successfully parsing a number followed by a string with no whitespace between.
*/
DecimalNumberFollowedByIdentifier: DecimalNumber Identifier;
/** /**
* An identifier in solidity has to start with a letter, a dollar-sign or an underscore and * 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. * may additionally contain numbers after the first symbol.

View File

@ -16,7 +16,7 @@ sourceUnit: (
| contractDefinition | contractDefinition
| interfaceDefinition | interfaceDefinition
| libraryDefinition | libraryDefinition
| functionDefinition | freeFunctionDefinition
| constantVariableDeclaration | constantVariableDeclaration
| structDefinition | structDefinition
| enumDefinition | enumDefinition
@ -85,7 +85,7 @@ inheritanceSpecifier: name=identifierPath arguments=callArgumentList?;
*/ */
contractBodyElement: contractBodyElement:
constructorDefinition constructorDefinition
| functionDefinition | contractFunctionDefinition
| modifierDefinition | modifierDefinition
| fallbackFunctionDefinition | fallbackFunctionDefinition
| receiveFunctionDefinition | receiveFunctionDefinition
@ -156,12 +156,12 @@ overrideSpecifier: Override (LParen overrides+=identifierPath (Comma overrides+=
* Depending on the context in which the function is defined, further restrictions may apply, * Depending on the context in which the function is defined, further restrictions may apply,
* e.g. functions in interfaces have to be unimplemented, i.e. may not contain a body block. * e.g. functions in interfaces have to be unimplemented, i.e. may not contain a body block.
*/ */
functionDefinition contractFunctionDefinition
locals[ locals[
boolean visibilitySet = false, boolean visibilitySet = false,
boolean mutabilitySet = false, boolean mutabilitySet = false,
boolean virtualSet = false, boolean virtualSet = false,
boolean overrideSpecifierSet = false boolean overrideSpecifierSet = false,
] ]
: :
Function (identifier | Fallback | Receive) Function (identifier | Fallback | Receive)
@ -175,6 +175,17 @@ locals[
)* )*
(Returns LParen returnParameters=parameterList RParen)? (Returns LParen returnParameters=parameterList RParen)?
(Semicolon | body=block); (Semicolon | body=block);
/**
* The definition of a free function.
*/
freeFunctionDefinition:
Function (identifier | Fallback | Receive)
LParen (arguments=parameterList)? RParen
stateMutability?
(Returns LParen returnParameters=parameterList RParen)?
(Semicolon | body=block);
/** /**
* The definition of a modifier. * The definition of a modifier.
* Note that within the body block of a modifier, the underscore cannot be used as identifier, * Note that within the body block of a modifier, the underscore cannot be used as identifier,
@ -394,6 +405,7 @@ expression:
| ( | (
identifier identifier
| literal | literal
| literalWithSubDenomination
| elementaryTypeName[false] | elementaryTypeName[false]
) # PrimaryExpression ) # PrimaryExpression
; ;
@ -412,6 +424,9 @@ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack;
identifier: Identifier | From | Error | Revert | Global; identifier: Identifier | From | Error | Revert | Global;
literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral; literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral;
literalWithSubDenomination: numberLiteral SubDenomination;
booleanLiteral: True | False; booleanLiteral: True | False;
/** /**
* A full string literal consists of either one or several consecutive quoted strings. * A full string literal consists of either one or several consecutive quoted strings.
@ -429,7 +444,8 @@ unicodeStringLiteral: UnicodeStringLiteral+;
/** /**
* Number literals can be decimal or hexadecimal numbers with an optional unit. * Number literals can be decimal or hexadecimal numbers with an optional unit.
*/ */
numberLiteral: (DecimalNumber | HexNumber) NumberUnit?; numberLiteral: DecimalNumber | HexNumber;
/** /**
* A curly-braced block of statements. Opens its own scope. * A curly-braced block of statements. Opens its own scope.
*/ */

View File

@ -0,0 +1,5 @@
contract C {
uint constant y = 1wei;
}
// ----
// ParserError 8936: (32-33): Identifier-start is not allowed at end of a number.

View File

@ -0,0 +1,5 @@
contract C {
uint constant y = 8 gwei ether;
}
// ----
// ParserError 2314: (39-44): Expected ';' but got 'ether'

View File

@ -0,0 +1,3 @@
function fallback() {}
// ----
// Warning 3445: (9-17): This function is named "fallback" but is not the fallback function of the contract. If you intend this to be a fallback function, use "fallback(...) { ... }" without the "function" keyword to define it.

View File

@ -0,0 +1,3 @@
function receive() {}
// ----
// Warning 3445: (9-16): This function is named "receive" but is not the receive function of the contract. If you intend this to be a receive function, use "receive(...) { ... }" without the "function" keyword to define it.

View File

@ -0,0 +1,5 @@
contract C {
uint x = 0x1000abcdefgh;
}
// ----
// ParserError 8936: (26-38): Identifier-start is not allowed at end of a number.

View File

@ -0,0 +1,5 @@
contract C {
uint y = 01gwei;
}
// ----
// ParserError 8936: (26-27): Octal numbers not allowed.

View File

@ -0,0 +1,5 @@
contract C {
uint y = 098;
}
// ----
// ParserError 8936: (26-27): Octal numbers not allowed.

View File

@ -0,0 +1,5 @@
contract C {
uint x = 0100;
}
// ----
// ParserError 8936: (26-27): Octal numbers not allowed.