Question:
In Raku version v2022.06, I am trying to dynamically create grammar G having two productions …- S → λ
- S → aSb
My draft program is …
$myTopCode
and $mySCode
hardcoded.However, how does one dynamically (programmatically) create the
Code
objects $myTopCode
and $mySCode
from the pairs of strings in the @variableRightHandSidesMap
?Update …
The answers below led me to the following draft, which produces the hoped‑for output (as shown above) …
use MONKEY-SEE-NO-EVAL ;
sub MAIN ( )
{
my @variableRightHandSidesMap is Array[Pair] ;
@variableRightHandSidesMap.push: Pair.new(“S”, “”) ;
@variableRightHandSidesMap.push: Pair.new(“S”, “‘a’ ‘b'”) ;
constant Parser := Metamodel::GrammarHOW.new_type( name => ‘Parser’ ) ;
my $startVariable = @variableRightHandSidesMap[0].key ; # ‘S’
my $myTopCode = EVAL ( ‘my token TOP { <' ~ $startVariable ~ '> }’ ) ;
Parser.^add_method( ‘TOP’, $myTopCode ) ;
my Str $sCumulativeRightHandSide = ” ;
loop ( my $i = 0 ; $i < @variableRightHandSidesMap.elems ; $i++ )
{
if ( $i > 0 )
{
$sCumulativeRightHandSide ~= ( ‘ | ‘ ) ;
}
if ( @variableRightHandSidesMap[$i].value.chars <= 0 )
{
$sCumulativeRightHandSide ~= ( '\'\'' ) ;
}
else
{
$sCumulativeRightHandSide ~= ( @variableRightHandSidesMap[$i].value ) ;
} # end else
} # end loop
my $mySCode = EVAL ( 'my token ' ~ 'S' ~ ' { ' ~ $sCumulativeRightHandSide ~ ' }' ) ;
Parser.^add_method( 'S', $mySCode ) ;
Parser.^compose ;
say Parser.HOW.^name ;
say Parser.^methods( :local ) ;
say ?(Parser.parse: 'aabb') ;
say ?(Parser.parse: 'aaaaabbbbb') ;
say ?(Parser.parse: 'aabbb') ;
say ?(Parser.parse: 'abab') ;
} # end sub MAIN
[/code]
Answer:
TheEVAL
function can be used to parse, compile, and evaluate Raku source. If you want to produce some kind of code object, then make sure the evaluated expression is a code object, e.g. EVAL 'anon regex { x }'
.If you have better answer, please add a comment about this, thank you!