jak*_*kar 5 grammar assertion raku
在节下的语法文档中:
“永远成功”断言
我复制了那里提供的示例,并添加了代码来显示在解析机制的每个阶段生成的表:
use v6.d;
grammar Digifier {
rule TOP { [ <.succ> <digit>+ ]+ }
token succ { <?> }
token digit { <[0..9]> }
}
class Letters {
has @!numbers;
method digit ($/) { @!numbers.tail ~= <a b c d e f g h i j>[$/]; say '---> ' ~ @!numbers }
method succ ($/) { @!numbers.push: '!'; say @!numbers }
method TOP ($/) { make @!numbers[^(*-1)] }
}
say 'FINAL ====> ' ~ Digifier.parse('123 456 789', actions => Letters.new).made;
Run Code Online (Sandbox Code Playgroud)
结果如下:
[!]
---> !b
---> !bc
---> !bcd
[!bcd !]
---> !bcd !e
---> !bcd !ef
---> !bcd !efg
[!bcd !efg !]
---> !bcd !efg !h
---> !bcd !efg !hi
---> !bcd !efg !hij
[!bcd !efg !hij !]
FINAL ====> !bcd !efg !hij
Run Code Online (Sandbox Code Playgroud)
我预计表@!numbers 中只有 3 次推送,但我得到了 4 次。我对排除方法“TOP”中表 @!numbers 的最后一个值感到困惑。
是的,我知道代码产生了正确的结果,但为什么呢?
最后一个“Always Succeed”断言从何而来?
一个量化的组,例如[ A B ]+,实际上是一个循环,反复尝试匹配A,如果匹配,则尝试匹配B。
除非它是一个无限循环——在这种情况下你的程序会挂起——它最终会匹配 N 次然后继续。如果A 总是匹配,但你的程序没有挂起,那么这一定意味着B最终失败了。如果是,A则保证比 多匹配 1 次B。
在您的代码中,Ais<.succ>减少到<?>,始终匹配。有4次尝试,因此A匹配4次。相反B,即<digit>+,在第四次尝试中失败,因此只匹配3次。
| 归档时间: |
|
| 查看次数: |
62 次 |
| 最近记录: |