Perl 6最长令牌匹配中的“附加平局决胜规则”是什么?
Perl 6正则平局决胜:拆解“附加平局决胜规则”
你好奇的这条“附加平局决胜规则”,其实是Perl 6正则在处理相同长度匹配分支时的补充性细节——毕竟前两条规则(最长声明前缀、最高特异性)覆盖了大部分常见场景,但总有一些边缘情况需要额外处理。
先快速回顾下前两条规则的作用:
- 最长声明前缀:如果某个备选分支的前缀是一个更长的、预先用
token/regex声明过的正则片段,那它会被优先选中。 - 最高特异性:比如明确的字符类
[a-z]比通配符.更具体,这种情况下特异性高的分支胜出。
第三条:附加平局决胜规则
这条规则主要处理前两条规则无法区分的语义高度接近甚至等价的分支场景,比如:
- 写法不同但语义完全一致的量词:比如
a**1和a+(当匹配单个a时),两者匹配长度相同,特异性和声明前缀也没有差异。 - 有无捕获组的分支:比如
(a)和a,捕获组属于附加的语义信息,不影响匹配的长度和特异性。 - 其他语法形式不同但匹配效果一致的模式:比如
a && b和b && a(当a和b都能匹配同一字符时)。
在这些场景下,Perl 6的“附加规则”其实并没有引入新的优先级判断,而是确认这些分支在匹配能力上是等价的,然后顺理成章地过渡到最后一条规则——最左侧的备选分支最终胜出。
举几个实际代码例子更直观:
# 完全相同的分支,触发附加规则后选最左侧 my regex identical { a | a } say 'a' ~~ /<identical>/; # 匹配第一个a分支 # 语义等价的量词,选最左侧 my regex quant-equiv { a**1 | a+ } say 'a' ~~ /<quant-equiv>/; # 匹配a**1分支 # 有无捕获组的分支,选最左侧 my regex capture-diff { (a) | a } say 'a' ~~ /<capture-diff>/; # 匹配带捕获组的第一个分支
最后兜底:最左侧分支胜出
当所有前面的规则都无法打破平局时,Perl 6就会回到最直观的逻辑:选择定义在最左边的那个备选分支。这是确保匹配结果确定性的最后一道防线。
内容的提问来源于stack exchange,提问作者brian d foy
相关产品推荐
相关产品推荐

