如何以编程方式(动态)创建Raku语法?



假设语法G有两个结果…

  1. S→λ

在Raku中,如何以编程方式(即,动态地,在运行时)创建此语法?

目标是让Raku程序在运行时创建一个Raku语法,它可以静态地写成…

grammar Parser
{
token  TOP  { <S> }
token S { '' | 'a' <S> 'b' }
}

给出我的问题的第一个答案,我正试图动态地创建将被静态地写为…

grammar Parser
{
token TOP { <S> }
} # end grammar Parser

I have try…

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) ;

然而,回复是…

Perl6::Metamodel::GrammarHOW
(TOP)

…而不是希望的…

Perl6::Metamodel::GrammarHOW
(token TOP { <S> } BUILDALL)

如何调用add_method来添加TOP令牌(以及之后的其他令牌)例如S令牌(?


经过更多的工作,我相信我可能有解决方案

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' ;

输出是…

Perl6::Metamodel::GrammarHOW
(token TOP { <S> } token S { '' | 'a' <S> 'b' })
「aabb」
S => 「aabb」
S => 「ab」
S => 「」
我已经编写了一个静态Parser的版本,对于staticParser与上面显示的类似的输出是…
(token TOP { <S> } token S { '' | 'a' 'a' <S> 'b' 'b' } BUILDALL)

我不确定BUILDALL从我的动态中丢失的事实创建Parser。我不懂BUILDALL,在网上搜索时没有发现太多。


当然是使用元模型。就像每种基本类型都有"如何(高阶工作)"一样,语法也有"语法如何"。不幸的是,关于元模型的信息并不多;Masak的一篇文章提到了GrammarHOW,就是这样。然而,看看代码,它本质上是一个类;如果您查看classHOW示例,并将方法设置为令牌,将类设置为语法,则可能没有问题。

总的来说,元编程是一个到目前为止还没有被广泛讨论的主题。真可惜。

最新更新