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

zdwk9cvp  于 2022-12-19  发布在  Perl
关注(0)|答案(2)|浏览(142)

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

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

我期望第二个选项有最长的标记,因为它有一个贪婪的量词,看起来非贪婪的量词被算作最长标记的一部分,尽管大纲5指出它不应该被包括在内。
如果颠倒顺序,我会得到预期的输出:

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

这应该是这样发生的吗?引擎认为这些标记的长度是多少?官方文档是相当模糊的,所以我借鉴了大纲5来苏斯清楚这是如何工作的。

ar5n3qh5

ar5n3qh51#

我在编译器中进行了深入的研究,看看那里发生了什么,+限定符action方法调用backmod,它反过来将backtrack属性设置为“f”。
然而,为量词编译NFA的代码根本不考虑回溯属性,因此对每个量词都一视同仁,而不管其回溯模式如何。因此,它的行为就像?不存在一样,这意味着它将考虑长度相等的两个分支。然后,它使用声明顺序作为平局决胜局。这导致它选择第一个分支。然后,一旦选择,就应用节俭量词,因此匹配单个“a”。(这也解释了为什么交换顺序会改变事情。)
这看起来确实与S05的设想不一致,即a+?应该被简单地视为“命运”(在本例中,意味着a+?替代品将具有零长度的最长令牌)。规范(即指定语言的测试套件)对这一问题保持沉默,然而,目前使其成为未定义的行为。
S05中提出的行为对我来说是有意义的,所以我主张以这种方式指定和实现它。

axkjgtzd

axkjgtzd2#

我认为目前的行为是正确的。
只有能被NFA或DFA匹配的东西才能成为Longest-Token Match的一部分,而且据我所知,简约量词并不能转化为自动机形式(自动机的工作原理是将所有字符输入自动机,并且在读取完整字符串之前没有接受的概念)。

相关问题