非贪婪模式是 Perl 6 最长标记匹配的一部分吗?

Is a nongreedy pattern part of Perl 6's longest token matching?

我在 2018.04 玩这个最长的令牌匹配,但我认为最长的令牌不匹配:

say 'aaaaaaaaa' ~~ m/
    | a+?
    | a+
    /; # 「a」

我希望第二个备选方案具有最长的标记,因为它具有贪婪量词。看起来非贪婪量词被计为最长标记的一部分,尽管 Synopsis 5 表示不应包含它。

如果我颠倒顺序,我会得到我期望的输出:

say 'aaaaaaaaa' ~~ m/
    | a+
    | a+?
    /;  # 「aaaaaaaaa」

这应该是这样的吗?引擎认为这些标记的长度是多少?官方文档非常模糊,所以我利用 Synopsis 5 来弄清楚这应该如何工作。

我认为当前的行为是正确的。

只有 NFA 或 DFA 可以匹配的东西才能成为最长令牌匹配的一部分,据我所知,节俭量词不会转化为自动机形式(它通过喂养所有字符进入自动机,并且在读取完整字符串之前没有接受的概念。

我深入研究了编译器,看看那里发生了什么。 +量词作用法calls backmod which in turn sets the backtrack property to "f".

然而,code to compile an NFA for a quantifier 根本不考虑回溯 属性,因此无论其回溯模式如何,都对每个量词一视同仁。因此,它的行为就好像 ? 不存在一样,这意味着它将考虑两个长度相等的分支。然后它使用声明顺序作为决胜局,导致它选择第一个分支。一旦选择,它就会应用 frugal 量词,因此匹配单个 "a"。 (这也解释了为什么交换顺序会改变事情。)

这似乎与 S05 envisions 不一致,即 a+? 应该简单地视为 "fate"(在这种情况下意味着 a+? 替代将有一个零长度的最长标记)。规范(即指定语言的测试套件)对此事保持沉默,但目前使其成为未定义的行为。

S05 中提议的行为对我来说很有意义,因此我主张以这种方式指定和实施它。我已经打开 this issue 进行跟踪。