PEG语法和解析器生成器的限制是什么?

15

如果需要解析PHP,我可以建议使用phc吗? - Paul Biggar
2个回答

20

我认为PEG语法的一个大“问题”是它们不符合正常语法分类的方式,因为它们的运作方式根本不同。通常的语法在描述可以生成的所有可能句子(程序)时是“向后”的,而PEG则描述了如何进行解析——它们从另一端着手解决这个问题。

在我看来,这是一种更自然的思考问题的方式,对于任何手写的(递归下降)解析器,我都不会做其他事情。


1
感谢DrPizza!我读到PEG不能解析Python和C++中的上下文敏感部分。不确定这是真的。我正在尝试编写PHP解析器,并发现与Bison/Yacc相比,PEG解决方案非常容易。 - Viet
4
大多数解析器无法正确处理上下文敏感的语法,除非采用某种技巧(例如,在解析C时,您可以使解析器反馈到词法分析器以便将正确的符号类型分配给类型名称,以便它们不会被视为常规标识符)。PEG很有趣,因为它们可以直接表达C和C ++使用的消歧规则(我不知道Python如何)。具体而言,“如果看起来像声明,那么就是声明”。它们可以通过对其规则进行排序,以便在语句规则之前尝试声明规则来实现这一点。 - DrPizza
10
如果解析的含义由其他信息确定,那么订购规则是无效的。C++以臭名昭著的方式允许" x*y;"作为一个语句,有两种解释:声明或算术运算。没有规则的排序可以帮助你决定这是什么。您需要上下文信息。C和C++解析器通常通过在执行过程中构建符号表来解决此问题; 知道x是一种类型可以解决问题。但是,如果x或y的定义出现在语句之后,即使使用此技巧也无法解决问题。安全的选择是GLR解析器,它只需捕获两个解析结果以供稍后解决。 - Ira Baxter
16
顺便提一句,PEGs 的真正价值在于设计自己的语言;使用 PEG 可确保语言被明确地解析,而传统的语言设计方法要么不关心解析(从而创建像 C 和 C++ 这样令人难以接受的语法),要么设计一个语法,然后不断修改它,直到最终成为你的工具(传统上是 yacc)可以实际解析的东西。通过将基本操作设为解析(而不是生成句子),PEGs 使语言设计中的这个方面变得更加容易。 - DrPizza
1
除非你坚持认为你的语言永远不会发展,或者你坚持认为任何演进都要使用相同的解析技术,否则你不应该围绕解析技术设计你的语言。这是本末倒置。当你设计语言时,你想要追求表达能力和可读性。后台编译器的人可能会因此而受苦(我就是其中之一),但他们并不多,而且有很多很多的语言用户。优化他们的体验,而不是为了编译器的人(或更糟糕的是,只为了解析器的人)而进行优化。 - Ira Baxter
显示剩余5条评论

7
PEG语法的主要局限是完全无法处理歧义。
当然,这也是它们的优点,因为使用CFG(上下文无关语法)工具处理歧义是最令人沮丧的部分之一。
使用PEG时,您需要通过将要匹配的规则排在另一个可能产生歧义但您不想要的规则之前来明确处理歧义。
问题在于,您并不总是知道某个语言或语法中的一些甚至所有歧义,并且PEG生成器(至少我尝试过的那些)不会分析语法以帮助您找到它们,然后设计和排序规则以正确地处理它们。
像yacc和bison这样的CFG解析器生成器会分析您的语法并报告所有歧义。不幸的是,他们经常用一种难以理解的方式报告它们。当然,修复语法以处理它们通常很困难。但至少您会意识到存在这些歧义。
使用PEG语法,您可以对概念上的语法中的歧义毫不知情,因为一旦将其变成PEG,它就不再有歧义,只有匹配规则和可能静默不可达的规则,如果它们具有更高的优先级也会进行匹配。这些可能不会在测试中出现,但可能会在发布后出现。
使用CFG语法,您被迫在开发过程中处理歧义,但这并不容易。
如果我没有表述清楚,则在Lambda the Ultimate编程语言博客上,Joshua Haberman在六年前进行了讨论:PEGs and Packrat Parsing are not the answer

1
一旦你将它转换为PEG,它就不再有歧义了。确实,你可以将PEG强制执行的("这个优先于那个")视为答案。但在许多情况下,特别是为了支持表现力,最好让语言具有歧义,并使用代码中的非上下文自由信息来解决这种歧义。虽然我不会声称C++到处存在的歧义一定是有帮助的,但如果你切换到GLR,你也可以对解析过程中的歧义毫不知情。(PEG是否进行任意前瞻?)请参见https://dev59.com/6nVC5IYBdhLWcg3wnCSA#1004737 - Ira Baxter
我也不确定 PEG 是否能够进行任意前瞻。 - Ira Baxter
我几天前才开始尝试使用 PEG,所以我不是专家,但我非常确定它们可以进行任意向前查找,这实际上是另一件我看到人们挑选出来的缺点。我也一直在寻找适用于 JavaScript 的 GLR 工具,但还没有找到与 PEG.js 和 Jison 相媲美的工具。 - hippietrail
@IraBaxter,您推荐使用哪种解析技术? - CMCDragonkai
1
我在使用GLR方面有非常好的经验。请查看我在Quora上的回答:http://qr.ae/RRQctF - Ira Baxter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接