树梢回溯类似于正则表达式?



我读到的所有内容都表明树顶回溯像正则表达式,但我很难做到这一点。

假设我有以下语法:

grammar TestGrammar
rule open_close
'{' .+ '}'
end
end

这与字符串{abc}不匹配。我怀疑这是因为.+正在消耗从信件a开始的所有东西。也就是说,当我只希望它消耗abc时,它正在消耗abc}.

这似乎与类似的正则表达式不同。正则表达式/{.+}/将匹配{abc}。我的理解是,这是可能的,因为正则表达式引擎在将关闭}作为.+的一部分消耗后回溯,然后无法匹配。

那么树顶能做这样的回溯吗?如果是这样,如何?

我知道你可以用否定来匹配"除}以外的任何东西"。但这不是我的本意。假设我希望能够匹配字符串{ab}c}.在这种情况下,我想要的标记是开始{,中间的ab}c串和结束}。这是一个人为的例子,但在使用嵌套表达式(如{a b {c d}})时变得非常相关。

Treetop 是解析表达式语法解析器的实现。PEG 的优势之一是它们结合了灵活性、速度和内存要求。然而,这种平衡行为有一些权衡。

引用维基百科文章:

零或多、一个或多个

和可选运算符分别使用零个或多个、一个或多个、零个或一个连续重复的子表达式 e。然而,与上下文无关的语法和正则表达式不同,这些运算符总是贪婪地行为,消耗尽可能多的输入,从不回溯。[...]表达式(a* a)将始终失败,因为第一部分(a*)永远不会为第二部分留下任何 A 进行匹配。

(强调我的。

简而言之:虽然某些PEG运营商可以回溯以尝试采取另一条路线,但+运营商不能。

相反,为了匹配嵌套的子表达式,您希望在分隔的子表达式(首先选中)与非表达式字符之间创建交替。类似的东西(未经测试):

grammar TestGrammar
rule open_close
'{' contents '}'
end
rule contents
open_close / non_brackets
end
rule non_brackets
# …
end
end

最新更新