如何在Raku中以编程式(运行时动态)方式创建Grammar文法
Raku动态创建文法相关问题
问题背景
给定文法G,包含两条产生式:
- S → λ
- S → aSb
需要在Raku中实现运行时动态创建对应该文法的解析器,其静态编写的等价形式如下:
grammar Parser { token TOP { <S> } token S { '' | 'a' <S> 'b' } }
初始实现的问题
最开始参考资料尝试动态创建仅包含TOP规则的文法,对应静态等价代码为:
grammar Parser { token TOP { <S> } }
编写的测试代码如下:
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 token,以及后续S这类其他token规则。
调试得到的可行方案
经过多次调试,找到可以正常完成解析的实现方式:
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文法输出的本地方法列表:
(token TOP { <S> } token S { '' | 'a' 'a' <S> 'b' 'b' } BUILDALL)
动态创建的文法方法列表中缺少BUILDALL项,目前没有检索到足够的参考资料说明BUILDALL的具体作用,需要明确该方法的功能,以及动态创建文法时是否需要手动处理该方法。
内容的提问来源于stack exchange,提问作者user3134725
相关产品推荐
相关产品推荐

