diff --git a/docs/grammar/SolidityLexer.g4 b/docs/grammar/SolidityLexer.g4 index 0452f9fa0..d3a387d97 100644 --- a/docs/grammar/SolidityLexer.g4 +++ b/docs/grammar/SolidityLexer.g4 @@ -85,6 +85,7 @@ SignedIntegerType: Storage: 'storage'; String: 'string'; Struct: 'struct'; +Suffix: 'suffix'; True: 'true'; Try: 'try'; Type: 'type'; diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index d3cd8f8c9..2c7a2f1e5 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -16,7 +16,7 @@ sourceUnit: ( | contractDefinition | interfaceDefinition | libraryDefinition - | functionDefinition + | functionDefinition[true] | constantVariableDeclaration | structDefinition | enumDefinition @@ -85,7 +85,7 @@ inheritanceSpecifier: name=identifierPath arguments=callArgumentList?; */ contractBodyElement: constructorDefinition - | functionDefinition + | functionDefinition[false] | modifierDefinition | fallbackFunctionDefinition | receiveFunctionDefinition @@ -156,10 +156,11 @@ overrideSpecifier: Override (LParen overrides+=identifierPath (Comma overrides+= * 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. */ -functionDefinition +functionDefinition[boolean free] locals[ boolean visibilitySet = false, boolean mutabilitySet = false, + boolean suffixSet = false, boolean virtualSet = false, boolean overrideSpecifierSet = false, ] @@ -169,7 +170,8 @@ locals[ ( {!$visibilitySet}? visibility {$visibilitySet = true;} | {!$mutabilitySet}? stateMutability {$mutabilitySet = true;} - | modifierInvocation + | {!$free}? modifierInvocation + | {$free}? {!$suffixSet}? Suffix {$suffixSet = true;} | {!$virtualSet}? Virtual {$virtualSet = true;} | {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;} )* @@ -396,6 +398,7 @@ expression: identifier | literal | literalWithSubDenomination + | suffixedLiteral | elementaryTypeName[false] ) # PrimaryExpression ; @@ -411,12 +414,14 @@ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack; /** * Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers. */ -identifier: Identifier | From | Error | Revert | Global; +identifier: Identifier | From | Error | Revert | Global | Suffix; literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral; literalWithSubDenomination: numberLiteral SubDenomination; +suffixedLiteral: literal identifier (Period identifier)*; + booleanLiteral: True | False; /** * A full string literal consists of either one or several consecutive quoted strings. diff --git a/scripts/test_antlr_grammar.sh b/scripts/test_antlr_grammar.sh index 6ab28fc5f..df64db97c 100755 --- a/scripts/test_antlr_grammar.sh +++ b/scripts/test_antlr_grammar.sh @@ -129,7 +129,8 @@ done < <( grep -v -E 'license/license_hidden_unicode.sol' | grep -v -E 'license/license_unicode.sol' | # Skipping tests with 'something.address' as 'address' as the grammar fails on those - grep -v -E 'inlineAssembly/external_function_pointer_address.*.sol' + grep -v -E 'inlineAssembly/external_function_pointer_address.*.sol' | + grep -v -E 'literalSuffixes/application/invalid_address_member_on_suffix.sol' ) YUL_FILES=()