Suppose grammar G has two productions …
- S → λ
- S → aSb
In Raku, how would one create this grammar programmatically (i.e., dynamically, at runtime)?
The goal is to have a Raku program create — at runtime — a Raku grammar that might be written statically as …
grammar Parser
{
token TOP { <S> }
token S { '' | 'a' <S> 'b' }
}
Given the first answer to my question, I am trying to dynamically create what would be statically written as …
grammar Parser
{
token TOP { <S> }
} # end grammar Parser
I have tried …
constant Parser := Metamodel::GrammarHOW.new_type( name => 'Parser' ) ;
Parser.^add_method('TOP', my method TOP(Parser:) { <S> }) ;
Parser.^compose; # }
say Parser.HOW.^name ;
say Parser.^methods(:local) ;
However, the reply is …
Perl6::Metamodel::GrammarHOW
(TOP)
… rather than the hoped-for …
Perl6::Metamodel::GrammarHOW
(token TOP { <S> } BUILDALL)
How should add_method
be invoked to add the TOP
token (and later, other tokens such as the S
token)?
After more work, I believe that I may have a solution …
constant Parser := Metamodel::GrammarHOW.new_type( name => 'Parser' ) ;
Parser.^add_method( 'TOP', my token TOP { <S> } ) ;
Parser.^add_method( 'S', my token S { '' | 'a' <S> 'b' } ) ;
Parser.^compose ;
say Parser.HOW.^name ;
say Parser.^methods( :local ) ;
say Parser.parse: 'aabb' ;
Output is …
Perl6::Metamodel::GrammarHOW
(token TOP { <S> } token S { '' | 'a' <S> 'b' })
「aabb」
S => 「aabb」
S => 「ab」
S => 「」
I had coded a static version of Parser
and for that static Parser
similar output to that shown above had been …
(token TOP { <S> } token S { '' | 'a' 'a' <S> 'b' 'b' } BUILDALL)
I am not sure about the fact that BUILDALL
is missing from my dynamically created Parser
. I do not understand BUILDALL
and did not find much when searching on-line.