原始令牌候选者排序

hyt*_*thm 13 regex grammar perl6 raku

perl6如何确定proto token首先匹配哪个?

下面的代码按预期方式工作,它与string匹配1234,并Grammar::Tracer显示与之匹配的第一个标记是s:sym<d>,这是有意义的,因为它是最长的标记。

但是,如果我将文字更改为令牌,例如,将token threeform 更改'3'<digit>,它将无法匹配,并Grammar::Tracer显示s:sym<b>与first匹配。

移动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';
Run Code Online (Sandbox Code Playgroud)
# Output: Match
# token three { '3' }

TOP
|  s
|  |  s:sym<d>
|  |  |  one
Run Code Online (Sandbox Code Playgroud)
# Output No Match
# token three { <digit> }

TOP
|  s
|  |  s:sym<b>
|  |  |  one
Run Code Online (Sandbox Code Playgroud)

rai*_*iph 13

perl6如何确定首先要匹配哪个原型令牌?

它使用“最长交替”逻辑。在您(表现良好!)的情况下,相关的决定因素如下。

首先,选择具有最长声明性前缀的分支。

因此,首先要注意的是它不是“最长令牌”,而是最长声明性前缀,即除了连续的“声明性”“原子”之外什么都不包含的模式的开始

A 3是声明性原子。

一个<foo>可能会或可能不会;这取决于它包含的内容。

我还没有找到明确的官方文件确定其内置的模式是声明,哪些不是,但它看起来像所有的那些以斜线声明,例如\d,是声明而所有的那些形式的形式声明<foo>,例如<digit>,都没有。(特别注意,内置<ws>模式不是声明性的。鉴于原子中的空格rules被转换为<ws>,这意味着第一个此类空格终止该规则的声明性前缀。)

因此,<digit>原子不是声明性前缀的一部分,而是终止前缀。

移动s:sym<d>到顶部,在两种情况下都匹配字符串,但是对该行为的解释是什么?

因为更改<three>为call,<digit>您已更改了规则,使三个具有最长声明性前缀(<one> <two>)的关系。因此,使用了其他打破平局规则

如果所有其他规则均未通过那些打破平局的规则来选择获胜者,则将选择最后一个“最左边的”规则,这将忽略继承,这意味着该规则在词法上排在第一位。