Peg.js 引擎是否像正则表达式那样在展望后退步?



根据环顾四周的 regular-expressions.info,发动机在向前看后退:

让我们再看看里面,以确保您了解 展望的影响。让我们应用 q(?=u(i 退出。这 展望现在是积极的,后面跟着另一个令牌。再次,q 匹配 Q,U 匹配 U。同样,从前瞻来看的比赛必须是 丢弃,因此引擎从字符串中的 i 退到您。这 展望是成功的,所以引擎继续使用 I。但我不能 匹配你。因此,此匹配尝试失败。所有剩余的尝试都失败了,因为 好吧,因为字符串中没有更多的 q。

然而,在 Peg 中.js引擎似乎仍然通过&!移动,因此实际上它不是与正则表达式相同意义上的展望,而是对消耗的决定,并且没有后退,因此没有真正的展望。

是这样吗?

(如果是这样,那么某些解析甚至是不可能的,就像这个一样?

Lookahead 的工作方式类似于它在正则表达式引擎中的工作方式。

此查询不匹配,因为下一个字母应该是'u',而不是'i'

word = 'q' &'u' 'i' 't'

此查询成功:

word = 'q' &'u' 'u' 'i' 't'

此查询成功:

word = 'q' 'u' 'i' 't'

至于您的示例,请尝试以下操作,您根本不需要使用前瞻:

expression
= termPair ( _ delimiter _ termPair )*
termPair
= term ('.' term)? ' ' term ('.' term)?
term "term"
= $([a-z0-9]+)
delimiter "delimiter"
= "."
_ "whitespace"
= [ tnr]+

编辑:在下面的评论中添加了另一个示例。

expression
= first:term rest:delimTerm* { return [first].concat(rest); }
delimTerm
= delimiter t:term { return t; }
term "term"
= $((!delimiter [a-z0-9. ])+)
delimiter "delimiter"
= _ "." _
_ "whitespace"
= [ tnr]+

编辑:添加了术语表达式的额外解释。

我将尝试$((!delimiter [a-z0-9. ])+)分解术语规则。

$()将内部的所有内容转换为单个文本节点,例如[].join('').

一个术语的单个"字符"是任何字符[a-z0-9. ],如果我们想简化它,我们可以说.。在匹配字符之前,我们要提前查看delimiter,如果我们找到一个delimiter我们将停止匹配该字符。由于我们想要多个角色,因此我们多次使用+执行整个操作。

它认为PEG解析器中的常见习语以这种方式前进。我从树顶文档中学到了匹配字符串的想法。

相关内容

最新更新