如何在Raku动作方法中直接获取匹配Token的参数$level的值?
解决方案
当然可以直接获取$level参数值,不需要从匹配文本推导。核心思路是把token的参数值附加到匹配对象$/上,这样动作方法就能直接读取。这里提供两种常用方案:
方案1:使用make和made(规范写法)
在token内部用make把$level存入匹配对象的made属性,动作方法里通过$/.made读取:
grammar G { token tab-indent(Int $level) { \t+ <?{ $/.chars == $level }> make $level; # 将参数值绑定到匹配对象的made属性 } } class G::Actions { method tab-indent($/) { my $target-level = $/.made; # 直接获取传入的level参数 say "指定的tab层级: $target-level"; say "匹配的tab数量: " ~ $/.chars; } } # 测试调用 G.parse("\t\t", :actions(G::Actions), :rule<tab-indent(2)>);
方案2:给Match对象添加自定义属性
直接给匹配对象$/动态添加属性,动作方法里直接访问该属性:
grammar G { token tab-indent(Int $level) { \t+ <?{ $/.chars == $level }> $/.target-level = $level; # 自定义属性存储参数值 } } class G::Actions { method tab-indent($/) { my $target-level = $/.target-level; say "指定的tab层级: $target-level"; } } # 测试调用 G.parse("\t\t\t", :actions(G::Actions), :rule<tab-indent(3)>);
说明
- 两种方案都能避免从匹配文本反向推导参数值的麻烦,尤其适合参数值和匹配内容无直接关联的复杂场景。
make是Raku语法中专门用于传递匹配上下文数据的标准机制,推荐优先使用;自定义属性则更灵活,但要注意属性名不要和Match对象的内置属性(比如chars、pos)冲突。
内容的提问来源于stack exchange,提问作者VZ.
相关产品推荐
相关产品推荐

