在Raku版本v2022.06中,我試圖動(dòng)態(tài)創(chuàng)建語(yǔ)法G,其中包含兩個(gè)結(jié)果…
- S→ λ
- S→ aSb公司
我的草稿程序是…
sub MAIN ( )
{
my @variableRightHandSidesMap is Array[Pair] ;
@variableRightHandSidesMap.push: Pair.new("S", "") ;
@variableRightHandSidesMap.push: Pair.new("S", "'a' <S> 'b'") ;
constant Parser := Metamodel::GrammarHOW.new_type( name => 'Parser' ) ;
my $myTopCode = my token TOP { <S> } ;
my $mySCode = my token S { '' | 'a' <S> 'b' } ;
Parser.^add_method( 'TOP', $myTopCode ) ;
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
程序輸出為…
Perl6::Metamodel::GrammarHOW
(token TOP { <S> } token S { '' | 'a' <S> 'b' })
True
True
False
False
上面顯示的草稿程序有$myTopCode
和$mySCode
硬編碼。
然而,如何從@variableRightHandSidesMap
中的字符串對(duì)動(dòng)態(tài)(以編程方式)創(chuàng)建Code
對(duì)象$myTopCode
和$mySCode
??
Update …
下面的答案讓我得出了以下草案,該草案產(chǎn)生了所希望的產(chǎn)出(如上所示)…
use MONKEY-SEE-NO-EVAL ;
sub MAIN ( )
{
my @variableRightHandSidesMap is Array[Pair] ;
@variableRightHandSidesMap.push: Pair.new("S", "") ;
@variableRightHandSidesMap.push: Pair.new("S", "'a' <S> '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
如有任何建議(如使上述草案更加簡(jiǎn)明的建議),將不勝感激。
在RakuAST分支落地之前,我會(huì)說(shuō)使用
EVAL
。您可以在當(dāng)前的Raku語(yǔ)法中進(jìn)行探索,以了解它當(dāng)前是如何完成的,但無(wú)法保證在RakuAST分支著陸后仍能正常工作。
RakuAST分支落地后,將有一個(gè)穩(wěn)定的API來(lái)實(shí)現(xiàn)這一點(diǎn)。