perl6如何确定首先匹配哪个proto
token
?
以下代码按预期工作,它与字符串1234
匹配,并且Grammar::Tracer
显示与之匹配的第一个令牌是s:sym<d>
,这是有道理的,因为它是最长的令牌。 / p>
但是,如果我将文字更改为令牌,例如,将token
的{{1}} three
形式从'3'
更改为<digit>
,则它将不匹配,并且{{1} }显示Grammar::Tracer
与第一个匹配。
将s:sym<b>
移到顶部,在两种情况下都匹配字符串,但是对此行为的解释是什么?
s:sym<d>
#!/usr/bin/env perl6
no precompilation;
use Grammar::Tracer;
grammar G {
token TOP { <s> }
proto token s { * }
token s:sym<a> { <one> }
token s:sym<b> { <one> <two> }
token s:sym<c> { <one> <two> <three> }
token s:sym<d> { <one> <two> <three> <four> }
token one { '1' }
token two { '2' }
token three { '3' }
token four { '4' }
}
my $g = G.new;
say $g.parse: '1234';
# Output: Match
# token three { '3' }
TOP
| s
| | s:sym<d>
| | | one
答案 0 :(得分:13)
perl6如何确定首先匹配哪个原型令牌?
它使用"Longest alternation" logic。在您(表现出色!)的情况下,相关的决定因素如下。
首先,选择具有最长声明性前缀的分支。
因此,首先要注意的是它不是“最长令牌”,而是最长声明性前缀,即除了连续的“声明性”内容之外,什么都不包含的模式的 start “原子”。
3
是声明性原子。
<foo>
可能会或可能不会;这取决于它包含的内容。
我还没有找到明确的官方文档来确定哪些内置模式是声明性的,哪些不是声明性的,但是看起来所有用斜杠声明的那些声明,例如\d
都是声明性的而所有以<foo>
形式声明的变量,例如<digit>
都不是。
(尤其要注意,内置<ws>
模式不是声明性的。rules
中原子之后的空格被转换为<ws>
,这意味着第一个这样的空格会终止该规则的声明性前缀。)
因此<digit>
原子不是声明性前缀的一部分,而是终止了前缀。
将
s:sym<d>
移到顶部,在两种情况下都匹配字符串,但是对此行为的解释是什么?
由于将<three>
更改为调用<digit>
,因此您已经更改了规则,使三个具有最长声明性前缀(<one> <two>
)的关系。 other tie-breaking rules are used。
如果所有其他规则都未能通过平局规则选出获胜者,则将选择最后一个“最左侧”规则,ignoring inheritance表示该规则在词汇上排在第一位。