Suppose grammar G has two productions …
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.
Using the metamodel, of course. Same as there are HOWs (Higher Order Working) for every basic type, there's a GrammarHOW for grammars. Unfortunately, there's not a whole lot of information on the metamodel; there's this article by Masak which mentions the GrammarHOW, and that's that. However, looking at the code, it's essentially a class; you're probably OK if you look at the classHOW
examples, and make methods be tokens and classes be grammars.
Metaprogramming, in general, is a subject that's not been extensively covered so far. Which is a pity.