【问题标题】:Limitations of PEG grammar & parser generators? [closed]PEG 语法和解析器生成器的局限性? [关闭]
【发布时间】:2009-12-06 23:32:42
【问题描述】:

我非常喜欢使用 YARD:

http://www.ootl.org/yard/

http://code.google.com/p/yardparser/

http://www.codeproject.com/KB/recipes/yard-tokenizer.aspx

我能够构建功能齐全的计算器。我正在评估 YARD 来做 PHP 解析器。请就 PEG 语法和解析器生成器的限制提出建议。非常感谢!

【问题讨论】:

  • 如果解析PHP,可以推荐使用phc吗?

标签: parser-generator yard peg php-parser


【解决方案1】:

我认为 PEG 的最大“问题”是它们不适合正常的语法分类,因为它们以完全不同的方式运行。正常语法是“倒退”的,因为它们描述了所有可能生成的句子(程序)。 PEG 描述了如何解析——它们从另一端来解决问题。

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

【讨论】:

  • 感谢 DrPizza!我读到 PEG 无法在上下文敏感部分解析 Python 和 C++。不确定这是不是真的。我正在尝试编写 PHP 解析器,发现与 Bison/Yacc 相比,PEG 解决方案非常容易。
  • 大多数解析器无法正确处理上下文相关的语法,而无需某种黑客攻击(例如,对于解析 C,您需要让解析器反馈到词法分析器,以便它为类型名称分配正确的符号类型,这样它们就不会被视为常规标识符)。 PEG 很有趣,因为它们可以直接表达 C 和 C++ 使用的消歧规则(我不了解 Python)。具体来说,“如果它看起来像一个声明,那就是”。他们可以通过对规则进行排序来做到这一点,以便在声明规则之前尝试声明规则。
  • 排序规则没有帮助,如果解析的含义是由其他信息决定的。 C++ 臭名昭著地允许“xy;”作为语句,有两种解释:声明或算术运算。没有规则排序可以帮助您确定这是什么。您需要上下文信息。 C 和 C++ 解析器经常通过构建符号表来解决这个问题。知道 x 是一种类型可以解决问题。但是如果 x 或 y 的定义出现在 *after 语句之后,那么即使这个 hack 也不起作用。安全的赌注是 GLR 解析器,它只需提取两个解析以稍后解析。
  • 啊,是的,当然。一如既往的解决方案是让动作与规则相关联; Boost 的 Spirit2 解析器框架使用 PEG 作为其底层模型,我相信它允许适当的操作——每个成功的类型声明都应该将其标识符添加到类型名称表中。结合 PEG 排序(声明规则在表达式规则之前尝试),PEG 将做正确的事情。不幸的是,Spirit2 的源代码是我们对 Boost 期望的通常难以理解的东西。
  • 顺便说一句,PEG 的真正价值在于设计自己的语言;使用 PEG 确保该语言是明确可解析的,而不是传统的语言设计方法,即要么不关心解析(并提出像 C 和 C++ 这样可恶的语法),要么设计一种语法,然后对其进行测试,直到它最终成为您的工具(传统上是 yacc)可以实际解析的东西。通过进行基本操作解析(而不是句子生成),PEG 使语言设计的这一方面变得更加容易。
【解决方案2】:

PEG 语法的主要限制是它们根本不处理歧义。

当然,这也是他们的强项,因为处理歧义是使用 CFG(上下文无关语法)工具最令人沮丧的部分之一。

使用 PEG,您可以通过将您想要匹配的规则排在另一个可能匹配不明确但您不想要的规则之前,明确地处理歧义。

问题在于,您甚至不总是知道语言或语法中的一些或什至任何歧义,而 PEG 生成器,至少我尝试过的那些,不要分析语法以找出歧义帮助您找到它们,然后设计和订购您的规则以正确处理它们。

像 yacc 和 bison 这样的 CFG 解析器生成器会分析您的语法并报告所有歧义。不幸的是,他们经常以一种很难理解的非常神秘的方式报告它们。当然,通常很难修复语法来处理它们。但至少你会意识到它们的存在。

使用 PEG 语法,您可以很高兴地对概念语法中的歧义一无所知,因为一旦将其设为 PEG,它就不再有歧义,它只有匹配的规则,也许默默无法达到的规则也会匹配,如果他们有更高的优先级。这些可能不会出现在您的测试中,但可能会在发布后出现。

使用 CFG 语法,您不得不在开发过程中处理歧义,但这并不容易。


如果我没有说清楚,这里是 Joshua Haberman 在 Lambda the Ultimate 编程语言博客上的六年讨论:PEGs and Packrat Parsing are not the answer em>。

【讨论】:

  • 一旦你把它做成 PEG,它就不再有歧义了。诚然,您可以将 PEG 对您施加的力量(“这个优先于那个”)作为 the 答案。但在许多情况下,特别是为了支持表达性,语言最好是模棱两可的,并使用代码中的非上下文无关信息来解决这种歧义。虽然我不会声称 C++ 无处不在的歧义一定会有所帮助,但如果您切换到 GLR,您也可能会很高兴地对解析过程中的歧义一无所知。 (PEG 是否进行任意前瞻?)见stackoverflow.com/a/1004737/120163
  • 我也不确定 PEG 是否会进行任意前瞻。
  • 我几天前才开始玩 PEG,所以我不是专家,但我很确定他们是任意前瞻,这实际上是我看到人们挑选出来的另一件事作为反对的另一个标记他们。我也一直在寻找适用于 JavaScript 的 GLR 工具,但还没有找到与 PEG.js 和 Jison 相提并论的工具。
  • @IraBaxter 你推荐什么类型的解析技术?
  • 我对 GLR 有过很好的体验。在 Quora 上查看我的回答:qr.ae/RRQctF
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
  • 2012-03-01
  • 2011-10-23
  • 2013-01-05
  • 1970-01-01
相关资源
最近更新 更多