我在2018.04玩这个最长的代币比赛,但我认为最长的代币是匹配的:
say 'aaaaaaaaa' ~~ m/
| a+?
| a+
/; # 「a」
我预计第二种替代品会拥有最长的令牌,因为它有一个贪婪的量词。虽然Synopsis 5表示它不应被包括在内,但看起来非贪婪量词被计为最长令牌的一部分。
如果我颠倒顺序,我会得到我期望的输出:
say 'aaaaaaaaa' ~~ m/
| a+
| a+?
/; # 「aaaaaaaaa」
这应该是这样发生的吗?引擎认为这些令牌的长度是多少?官方文档非常含糊,所以我在Synopsis 5上使用它来证明它应该如何工作。
答案 0 :(得分:7)
我在编译器中挖掘了一下,看看那里发生了什么。 +
量词操作方法calls backmod依次为sets the backtrack property to "f"。
但是,code to compile an NFA for a quantifier根本不会查看回溯属性,因此无论其回溯模式如何,都会将每个量词视为相同。因此,它就好像?
不在那里,这意味着它将考虑两个相等长度的分支。然后它使用声明顺序作为打破平局,导致它选择第一个分支。然后,一旦选择,就应用节俭量词,因此匹配单个“a”。 (这也解释了为什么交换订单会改变一些事情。)
这似乎与S05 envisions不符,a+?
应该只被视为“命运”(在这种情况下意味着a+?
替代将为零最长的令牌)。规范(即指定语言的测试套件)在此问题上保持沉默,但目前使其成为未定义的行为。
S05中的建议行为对我来说很有意义,因此我会争论以这种方式指定和实现它。我已打开this issue来跟踪它。
答案 1 :(得分:0)
我认为目前的行为是正确的。
只有NFA或DFA可以匹配的内容才能成为最长令牌匹配的一部分,据我所知,节俭量词并不能转化为自动机形式主义(通过将所有字符输入到自动机,并且在读取完整字符串之前没有接受的概念。)