能否将Raku Grammar中state和zipcode的made值提升至TOP层级?
问题描述
我编写了如下Raku语法规则(Grammar)及对应的Actions类:
#!/usr/bin/env raku use v6.d; use Grammar::Tracer; grammar Grammar { token TOP { <city> \v <state-zip> \v? } token city { ^^ \V* $$ } token state-zip { ^^ <state> <.ws>? <zipcode> $$ #<.ws> is [\h* | \v] } token state { \w \w } token zipcode { \d ** 5 } } class Actions { method TOP($/) { #works say "city is ", $_ with $<city>.made; say "state is ", $_ with $<state-zip><state>.made; say "zipcode is ", $_ with $<state-zip><zipcode>.made; #doesn't work say "state2 is ", $_ with $<state>.made; say "zipcode2 is ", $_ with $<zipcode>.made; } method city($/) { make ~$/ } method state($/) { make ~$/ } method zipcode($/) { make ~$/ } } my $address = q:to/END/; Springfield, IL 62704 END Grammar.parse($address, :actions(Actions));
当前代码运行正常,输出如下:
TOP | city | * MATCH "Springfield," | state-zip | | state | | * MATCH "IL" | | zipcode | | * MATCH "62704" | * MATCH "IL 62704" city is Springfield, state is IL zipcode is 62704 * MATCH "Springfield,\nIL 62704\n"
其中token <state-zip>用于支持州(state)与邮编(zipcode)在同一行或跨行。这是最小可复现示例,我希望不修改Grammar规则,仅通过调整Actions中的make/made逻辑,实现在TOP方法中直接访问state和zipcode的made值(即示例中state2和zipcode2的访问方式),请问是否可行?
解决方案
可行。核心思路是在state-zip的Action方法中,把内部state和zipcode的made值向上绑定到当前匹配对象的哈希结构中,让TOP方法能直接访问到这些值。
修改后的Actions类如下:
class Actions { method TOP($/) { # 原有可用代码保留 say "city is ", $_ with $<city>.made; say "state is ", $_ with $<state-zip><state>.made; say "zipcode is ", $_ with $<state-zip><zipcode>.made; # 现在可以正常工作 say "state2 is ", $_ with $<state>.made; say "zipcode2 is ", $_ with $<zipcode>.made; } method city($/) { make ~$/ } method state($/) { make ~$/ } method zipcode($/) { make ~$/ } # 新增state-zip方法,将内部子规则的made值绑定到当前匹配对象 method state-zip($/) { # 把state和zipcode的made值挂载到当前$/的哈希表,让上层可直接访问 $/<state> = $<state>.made; $/<zipcode> = $<zipcode>.made; # 可选择make一个包含两者的结构,不影响上层访问逻辑 make { state => $<state>.made, zipcode => $<zipcode>.made }; } }
原理说明
- Raku的匹配对象
$/本质是哈希结构,子规则的匹配结果以键值对形式存储其中。 - 默认情况下,
state和zipcode的匹配结果仅存在于state-zip的子匹配对象中,TOP方法无法直接访问。 - 通过在
state-zip的Action方法中,将state和zipcode的made值赋值给当前$/的对应键,相当于把这些值“提升”到了上层匹配对象的作用域中,这样TOP方法就能通过$<state>和$<zipcode>直接获取到它们的made值。
内容的提问来源于stack exchange,提问作者librasteve
相关产品推荐
相关产品推荐

