4

我正在研究编译器的构造,当然我也在研究这些概念的实际实现。其中一个例子是 Babel 的解析器:Babylon。

我浏览了巴比伦的代码,它似乎使用了一个自上而下的解析器和嵌入的即席语义规则。源代码

我期待 Babel 使用 LR 解析器的成员,并且可能是一个定义文件,其中语法产生与语义规则耦合在一起。为什么?嗯,主要是因为许多其他现实世界的语言使用 lr 解析器生成器,例如 Yacc、Bison 等,它们为您提供了这个精确的接口,并且似乎是一种更清晰、更易于维护的方式来表示这些规则,甚至当您考虑到 Babel 处于 Javascript 标准的边缘,一直在实现新事物。

我还构建了自上而下和自下而上(lr)解析器,我看不出两者之间的实现难度差异很大(两者同样困难:))

那么,为什么 Babel 的解析器使用自上而下的即席语法定向翻译,而不是我认为的更结构化的方法?这背后的设计决策是什么?我错过了什么?

谢谢!

4

1 回答 1

11

我觉得你真的在问两个(或三个)问题,所以我将分别解决

一般来说,不同的解析方法的优缺点是什么

自上而下与自下而上

对于手写解析器,情况实际上非常清楚:自顶向下解析器更容易编写和维护,以至于我什至从未见过手写的自底向上解析器。

对于解析器生成器,情况不太清楚。两种类型的解析器生成器都存在(例如 yacc 和 bison 是自下而上的,ANTLR 和 JavaCC 是自上而下的)。两者都有其优点和缺点,我认为没有理由说一种方法明显优于另一种方法。

事实上,我会说在自上而下和自下而上的解析之间做出决定通常是没有意义的。手写解析器时,请始终使用前者。使用解析器生成器时,您应该简单地选择功能最适合您的项目的工具,而不是根据它是生成自下而上的解析器还是自顶向下的解析器。

手写解析器与解析器生成器

手写解析器的原因有很多。这些还取决于哪些解析器生成器甚至可用于该语言。解析器生成器经常遇到的一个缺点是它们很难为语法错误生成好的错误消息。

另一个可能的问题是,对于非上下文无关语言,您可能需要一些肮脏的技巧来使用解析器生成器来实现它们,或者根本不可能。

这些因素如何特别适用于巴比伦

手写解析器与解析器生成器

JavaScript 语法相当复杂,有很多特殊情况来解决歧义。使用解析器生成器时可能需要大量的 hack,并且对于 JavaScript 可用的解析器生成器可能根本不可能。

我还要说,可用于 JavaScript 的解析器生成器可能还没有为生产做好准备,在项目首次创建时甚至更少。

自上而下与自下而上

正如我所说,我从未见过手写的自底向上解析器。因此,一旦您决定使用手写解析器,编写自上而下解析器的决定就很容易了。

于 2017-10-17T12:40:16.523 回答