【问题标题】:proto token candidates ordering原型令牌候选人订购
【发布时间】:2019-05-15 21:25:32
【问题描述】:

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

下面的代码按预期工作,它匹配字符串1234,而Grammar::Tracer 表明匹配的第一个令牌是s:sym<d>,这是有道理的,因为它是最长的令牌。

但是,如果我将文字更改为令牌,例如,将 token three'3' 更改为 <digit>,则匹配失败,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
# Output No Match
# token three { <digit> }

TOP
|  s
|  |  s:sym<b>
|  |  |  one

【问题讨论】:

    标签: regex grammar raku


    【解决方案1】:

    perl6 如何决定首先匹配哪个 proto 令牌?

    它使用"Longest alternation" logic。在您的(很好的介绍!)案例中,相关的决定因素如下。

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

    所以首先要关注的是它不是“最长的标记”,而是最长的声明性前缀,一个模式的开始,它只包含连续的“声明性” “原子”。

    3 是一个声明性原子。

    &lt;foo&gt; 可能是也可能不是;这取决于它包含的内容。

    我还没有找到明确的官方文档来确定哪些内置模式是声明性的,哪些不是,但看起来所有用斜杠声明的模式,例如\d,都是声明性的,而所有以&lt;foo&gt; 形式声明的那些,例如&lt;digit&gt;,不是。 (特别注意,内置的&lt;ws&gt; 模式是not声明性的。鉴于rules 中的原子后的空格被转换为&lt;ws&gt;,这意味着第一个这样的空格终止了声明性前缀这条规则。)

    所以&lt;digit&gt; 原子不是声明性前缀的一部分,而是终止前缀。

    s:sym&lt;d&gt; 移到顶部,在这两种情况下都匹配字符串,但是这种行为的解释是什么?

    因为将&lt;three&gt; 更改为调用&lt;digit&gt;,您已将规则更改为三个与最长声明性前缀(&lt;one&gt; &lt;two&gt;) 并列的规则。所以other tie-breaking rules are used

    如果在这些打破平局的规则中所有其他规则都未能选出获胜者,则选择最后一个“最左边”规则,ignoring inheritance,表示词法上首先出现的规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      • 2020-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多