I’m puzzled. I have the same rules in two grammars one parse a sequence and the other not.
self parse: ‘payable internal' _FunctionTypeNameOptions : | FunctionTypeNameOptions ; FunctionTypeNameOptions : FunctionTypeNameOption 'option' {{}} | FunctionTypeNameOptions FunctionTypeNameOption 'option' {{}} ; FunctionTypeNameOption : "internal" 'token' {{FunctionOption}} | "external" 'token' {{FunctionOption}} | "constant" 'token' {{FunctionOption}} | "payable" 'token' {{FunctionOption}} ; In the following grammar it parses well sequence %glr; %prefix Sol ; %suffix Node ; %root TypeName ; <whitespace> : \s+; %root Object; %prefix FO; _FunctionTypeNameOptions : | FunctionTypeNameOptions ; FunctionTypeNameOptions : FunctionTypeNameOption 'option' {{}} | FunctionTypeNameOptions FunctionTypeNameOption 'option' {{}} ; FunctionTypeNameOption : "internal" 'token' {{FunctionOption}} | "external" 'token' {{FunctionOption}} | "constant" 'token' {{FunctionOption}} | "payable" 'token' {{FunctionOption}} ; In this one not (note that it is not connected to the rest yet) and that I use the start directive to test incrementally. %glr; %prefix Sol ; %suffix Node ; %root TypeName ; %start TypeName FunctionTypeName _FunctionTypeNameOptions FunctionTypeNameOptions; <eol> : \r | \n | \r\n ; <whitespace> : \s+ ; <comment> : \/\/\/ [^\r\n]* | \/\/ [^\r\n]* ; <IDENTIFIER> : [a-zA-Z_$] [a-zA-Z0-9_$]* ; # UserDefinedTypeName = Identifier ( '.' Identifier )* <UserDefinedTypeName> : <IDENTIFIER> ( . <IDENTIFIER> )* ; <DECIMALNUMBER> : [0-9]+ ; ############################################### #TypeNameList = '(' ( TypeName (',' TypeName )* )? ')' ParenthesizedTypeNameList : "(" TypeNameList_Opt ")" ; # return nil when empty TypeNameList_Opt : | TypeNameList ; TypeNameList : TypeName 'typename' {{}} | TypeNameList "," TypeName 'typename' {{}} ; ############################################### #TypeName = ElementaryTypeName # | UserDefinedTypeName # | Mapping # | ArrayTypeName # | FunctionTypeName TypeName : <UserDefinedTypeName> | ElementaryTypeName | Mapping | ArrayTypeName ; # Mapping = 'mapping' '(' ElementaryTypeName '=>' TypeName ')' Mapping : "mapping" "(" ElementaryTypeName 'from' "=>" TypeName 'to' ")" {{Mapping}} ; #ArrayTypeName = TypeName '[' Expression? ']' # for now we will do ArrayTypeName = TypeName '[' PrimaryExpression? ']' ArrayTypeName : TypeName 'typeName' "[" "]" {{ArrayTypeName}} | TypeName 'typeName' "[" PrimaryExpression 'expression' "]" {{ArrayTypeName}} ; #FunctionTypeName = 'function' TypeNameList ( 'internal' | 'external' | 'constant' | 'payable' )* ( 'returns' TypeNameList )? #FunctionTypeName # : "function" TypeNameList 'typenameList' ( "internal" | "external" | "constant" | "payable" )* 'kind' # | "function" TypeNameList 'typenameList' ( "internal" | "external" | "constant" | "payable" )* ( "returns" TypeNameList returnTypeList )? {{FunctionTypeName}} # ; ######################################################## #FunctionTypeNameOptions # : {{}} # | FunctionTypeNameOptions "internal" 'option' {{}} # | FunctionTypeNameOptions "external" 'option' {{}} # | FunctionTypeNameOptions "constant" 'option' {{}} # | FunctionTypeNameOptions "payable" 'option' {{}} # ; _FunctionTypeNameOptions : | FunctionTypeNameOptions ; FunctionTypeNameOptions : FunctionTypeNameOption 'option' {{}} | FunctionTypeNameOptions FunctionTypeNameOption 'option' {{}} ; FunctionTypeNameOption : "internal" 'token' {{FunctionOption}} | "external" 'token' {{FunctionOption}} | "constant" 'token' {{FunctionOption}} | "payable" 'token' {{FunctionOption}} ; #################################################### # To complete later. Basically copy and paste all the variations.... PrimaryExpression : ElementaryTypeNameExpression ; ElementaryTypeNameExpression : ElementaryTypeName 'type' {{Type}} ; ElementaryTypeName : "address" | "bool" | "string" | "var" | Int | Uint | Byte | Fixed | Ufixed ; Int : "int" | "int8" | "int16" ; Uint : "uint" | "uint8" | "uint16" ; Byte : "byte" | "bytes" ; Fixed : "fixed" | "fixed0x8" ; UFixed : "ufixed" | "ufixed0x8" ; -------------------------------------------- Stéphane Ducasse http://stephane.ducasse.free.fr http://www.synectique.eu / http://www.pharo.org 03 59 35 87 52 Assistant: Julie Jonas FAX 03 59 57 78 50 TEL 03 59 35 86 16 S. Ducasse - Inria 40, avenue Halley, Parc Scientifique de la Haute Borne, Bât.A, Park Plaza Villeneuve d'Ascq 59650 France On Tue, Mar 28, 2017 at 8:28 AM, Stephane Ducasse <stepharo.s...@gmail.com> wrote: > I’m puzzled. I have the same rules in two grammars one parse a sequence > and the other not. > > > self parse: ‘payable internal' > > > _FunctionTypeNameOptions > > : > > | FunctionTypeNameOptions > > ; > > FunctionTypeNameOptions > > : FunctionTypeNameOption 'option' {{}} > > | FunctionTypeNameOptions FunctionTypeNameOption 'option' {{}} > > ; > > FunctionTypeNameOption > > : "internal" 'token' {{FunctionOption}} > > | "external" 'token' {{FunctionOption}} > > | "constant" 'token' {{FunctionOption}} > > | "payable" 'token' {{FunctionOption}} > > ; > > > > In the following grammar it parses well sequence > > > %glr; > > %prefix Sol ; > > %suffix Node ; > > %root TypeName ; > > > <whitespace> : \s+; > > %root Object; > > %prefix FO; > > > _FunctionTypeNameOptions > > : > > | FunctionTypeNameOptions > > ; > > FunctionTypeNameOptions > > : FunctionTypeNameOption 'option' {{}} > > | FunctionTypeNameOptions FunctionTypeNameOption 'option' {{}} > > ; > > FunctionTypeNameOption > > : "internal" 'token' {{FunctionOption}} > > | "external" 'token' {{FunctionOption}} > > | "constant" 'token' {{FunctionOption}} > > | "payable" 'token' {{FunctionOption}} > > ; > > > In this one not (note that it is not connected to the rest yet) and that I > use the start directive to test incrementally. > > > %glr; > > %prefix Sol ; > > %suffix Node ; > > %root TypeName ; > > > %start TypeName FunctionTypeName _FunctionTypeNameOptions > FunctionTypeNameOptions; > > <eol> > > : \r > > | \n > > | \r\n > > ; > > <whitespace> > > : \s+ > > ; > > > <comment> > > : \/\/\/ [^\r\n]* > > | \/\/ [^\r\n]* > > ; > > <IDENTIFIER> > > : [a-zA-Z_$] [a-zA-Z0-9_$]* > > ; > > > # UserDefinedTypeName = Identifier ( '.' Identifier )* > > > <UserDefinedTypeName> > > : <IDENTIFIER> ( . <IDENTIFIER> )* > > ; > > <DECIMALNUMBER> > > : [0-9]+ > > ; > > ############################################### > > #TypeNameList = '(' ( TypeName (',' TypeName )* )? ')' > > ParenthesizedTypeNameList > > : "(" TypeNameList_Opt ")" > > ; > > > # return nil when empty > > TypeNameList_Opt > > : > > | TypeNameList > > ; > > TypeNameList > > : TypeName 'typename' {{}} > > | TypeNameList "," TypeName 'typename' {{}} > > ; > > ############################################### > > #TypeName = ElementaryTypeName > > # | UserDefinedTypeName > > # | Mapping > > # | ArrayTypeName > > # | FunctionTypeName > > > TypeName > > : <UserDefinedTypeName> > > | ElementaryTypeName > > | Mapping > > | ArrayTypeName > > ; > > > # Mapping = 'mapping' '(' ElementaryTypeName '=>' TypeName ')' > > Mapping > > : "mapping" "(" ElementaryTypeName 'from' "=>" TypeName 'to' ")" > {{Mapping}} > > ; > > > #ArrayTypeName = TypeName '[' Expression? ']' > > # for now we will do ArrayTypeName = TypeName '[' PrimaryExpression? ']' > > ArrayTypeName > > : TypeName 'typeName' "[" "]" {{ArrayTypeName}} > > | TypeName 'typeName' "[" PrimaryExpression 'expression' "]" > {{ArrayTypeName}} > > ; > > > > #FunctionTypeName = 'function' TypeNameList ( 'internal' | 'external' | > 'constant' | 'payable' )* ( 'returns' TypeNameList )? > > > #FunctionTypeName > > # : "function" TypeNameList 'typenameList' ( "internal" | "external" | > "constant" | "payable" )* 'kind' > > # | "function" TypeNameList 'typenameList' ( "internal" | "external" | > "constant" | "payable" )* ( "returns" TypeNameList returnTypeList )? > {{FunctionTypeName}} > > # ; > > > ######################################################## > > #FunctionTypeNameOptions > > # : {{}} > > # | FunctionTypeNameOptions "internal" 'option' {{}} > > # | FunctionTypeNameOptions "external" 'option' {{}} > > # | FunctionTypeNameOptions "constant" 'option' {{}} > > # | FunctionTypeNameOptions "payable" 'option' {{}} > > # ; > > > _FunctionTypeNameOptions > > : > > | FunctionTypeNameOptions > > ; > > > FunctionTypeNameOptions > > : FunctionTypeNameOption 'option' {{}} > > | FunctionTypeNameOptions FunctionTypeNameOption 'option' {{}} > > ; > > FunctionTypeNameOption > > : "internal" 'token' {{FunctionOption}} > > | "external" 'token' {{FunctionOption}} > > | "constant" 'token' {{FunctionOption}} > > | "payable" 'token' {{FunctionOption}} > > ; > > > > #################################################### > > # To complete later. Basically copy and paste all the variations.... > > > PrimaryExpression > > : ElementaryTypeNameExpression > > ; > > ElementaryTypeNameExpression > > : ElementaryTypeName 'type' {{Type}} > > ; > > ElementaryTypeName > > : "address" | "bool" | "string" | "var" | Int | Uint | Byte | Fixed | > Ufixed > > ; > > > Int > > : "int" | "int8" | "int16" > > ; > > Uint > > : "uint" | "uint8" | "uint16" > > ; > > Byte > > : "byte" | "bytes" > > ; > > Fixed > > : "fixed" | "fixed0x8" > > ; > > UFixed > > : "ufixed" | "ufixed0x8" > > ; > > > > > > > > > > > > > > > > > -------------------------------------------- > > Stéphane Ducasse > > http://stephane.ducasse.free.fr > > http://www.synectique.eu / http://www.pharo.org > > 03 59 35 87 52 > > Assistant: Julie Jonas > > FAX 03 59 57 78 50 > > TEL 03 59 35 86 16 > > S. Ducasse - Inria > > 40, avenue Halley, > > Parc Scientifique de la Haute Borne, Bât.A, Park Plaza > > Villeneuve d'Ascq 59650 > > France > > On Mon, Mar 27, 2017 at 9:37 PM, Thierry Goubier < > thierry.goub...@gmail.com> wrote: > >> Le 27/03/2017 à 21:12, Stephane Ducasse a écrit : >> >>> what was strange is that this version >>> >>> <whitespace> : \s+; >>> >>> %root MultiListObject; >>> %prefix XPML; >>> modifiers_opt >>> : >>> | modifiers >>> ; >>> modifiers >>> : modifier 'modifier' {{}} >>> | modifiers modifier 'modifier' {{}} >>> ; >>> modifier >>> : "public" 'token' {{Modifier}} >>> | "protected" 'token' {{Modifier}} >>> | "private" 'token' {{Modifier}} >>> | "static" 'token' {{Modifier}} >>> ; >>> >>> >>> did not accept 'public static' >>> >>> I found that there were obsolete classes around and I reloaded SmaCC in >>> a fresh image >>> then regenerate this and my test pass now. So I will do the same for my >>> solidity parser. >>> >> >> Yes, the ast generation code does that sometimes, when you iterate >> modifying the grammar and ast classes. It doesn't delete pre-existing >> classes, even if they are not correct anymore because the grammar has >> changed. >> >> Thierry >> >> >>> On Mon, Mar 27, 2017 at 6:40 PM, Stephane Ducasse >>> <stepharo.s...@gmail.com <mailto:stepharo.s...@gmail.com>> wrote: >>> >>> Apparently there is an interaction with the root directives. >>> >>> On Mon, Mar 27, 2017 at 6:34 PM, Stephane Ducasse >>> <stepharo.s...@gmail.com <mailto:stepharo.s...@gmail.com>> wrote: >>> >>> Now I tried to hook modifier logic to test and I cannot have two >>> modifiers. >>> I thought that >>> >>> modifiers >>> : modifier 'modifier' >>> | modifiers modifier 'modifier' >>> ; >>> allows one to have 'public static' but apparently not so I'm >>> totally confused. >>> >>> >>> On Mon, Mar 27, 2017 at 6:30 PM, Stephane Ducasse >>> <stepharo.s...@gmail.com <mailto:stepharo.s...@gmail.com>> >>> wrote: >>> >>> Hi john >>> >>> I'm learning smacc as a challenge :) I read a review the >>> tutorial that we extracted form your doc. >>> >>> I have the following expression >>> >>> FunctionTypeName = 'function' TypeNameList ( 'internal' | >>> 'external' | 'constant' | 'payable' )* ( 'returns' >>> TypeNameList )? >>> >>> and I started to handle the 'internal'.... >>> >>> Now my grammar does not succeed to parse >>> (self parser parseFunctionTypeNameOptions: 'internal >>> payable') >>> >>> Attempt one: did not work >>> =================== >>> FunctionTypeNameOptions >>> : {{}} >>> | FunctionTypeNameOptions "internal" 'option' {{}} >>> | FunctionTypeNameOptions "external" 'option' {{}} >>> | FunctionTypeNameOptions "constant" 'option' {{}} >>> | FunctionTypeNameOptions "payable" 'option' {{}} >>> >>> >>> Attempt two: did not work >>> =================== >>> FunctionTypeNameOptions >>> : >>> | FunctTypeNameOptions >>> ; >>> FunctTypeNameOptions >>> : FunctTypeNameOptions "internal" 'option' {{}} >>> | FunctTypeNameOptions "external" 'option' {{}} >>> | FunctTypeNameOptions "constant" 'option' {{}} >>> | FunctTypeNameOptions "payable" 'option' {{}} >>> ; >>> >>> Attempt three: did not work >>> ===================== >>> >>> FunctionTypeNameOptions >>> : >>> | FunctTypeNameOptions >>> ; >>> >>> FunctTypeNameOptions >>> : FunctTypeNameOption 'option' >>> | FunctTypeNameOptions FunctTypeNameOption 'option' >>> ; >>> FunctTypeNameOption >>> : "internal" 'option' {{}} >>> | "external" 'option' {{}} >>> | "constant" 'option' {{}} >>> | "payable" 'option' {{}} >>> ; >>> >>> >>> >>> I studied the JavaParser and I do not get why my version >>> does not work >>> >>> modifiers_opt >>> : >>> | modifiers >>> ; >>> modifiers >>> : modifier 'modifier' >>> | modifiers modifier 'modifier' >>> ; >>> modifier >>> : "public" 'token' {{Modifier}} >>> | "protected" 'token' {{Modifier}} >>> | "private" 'token' {{Modifier}} >>> | "static" 'token' {{Modifier}} >>> ; >>> >>> >>> Thanks in advance. I could have try to do it in petitParser >>> but I want to have a real experience with Smacc. >>> >>> Stef >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >> >> >