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



我在 2018.04 玩这个最长的代币匹配,但我认为最长的代币不是匹配:

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

我希望第二种选择具有最长的令牌,因为它具有贪婪的量词。看起来非贪婪量词被算作最长代币的一部分,尽管概要 5 表明它不应该被包括在内。

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

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

这是应该这样发生的吗?引擎认为这些代币的长度是多少?官方文档非常模糊,所以我正在利用 Synopsis 5 来说明它应该如何工作。

我在编译器中挖掘了一下,看看那里发生了什么。+量词操作方法调用 backmod,后者又将 backtrack 属性设置为 "f"。

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

这似乎与 S05 的设想不符,即a+?应该简单地被视为"命运"(在这种情况下,这意味着a+?替代方案将具有零长度最长令牌(。然而,规范(即指定语言的测试套件(对此事保持沉默,使其目前处于未定义的行为。

S05 中提议的行为对我来说很有意义,所以我主张以这种方式指定和实现它。我已经打开了这个问题来跟踪它。

我相信当前的行为是正确的。

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

最新更新