41

我是 Haskell 和 Parsec 的新手。读完第 16 章 Using Parsec of Real World Haskell后,我的脑海中出现了一个问题:为什么 Parsec 比 Yacc/Bison/Antlr 等其他解析器生成器更好?

我的理解是 Parsec 创建了一个很好的编写解析器的 DSL,而 Haskell 使它变得非常简单和富有表现力。但是解析是一种标准/流行的技术,值得拥有自己的语言,可以输出到多种目标语言。那么我们什么时候应该使用 Parsec 而不是从 Bison/Antlr 生成 Haskell 代码呢?

这个问题可能会超越技术,进入行业实践领域。从头开始编写解析器时,与 Bison/Antlr 或类似的东西相比,使用 Haskell/Parsec 有什么好处?

顺便说一句:我的问题与这个问题非常相似,但在那里没有得到令人满意的回答。

4

3 回答 3

55

您列出的工具之间的主要区别之一是 ANTLR、Bison 和他们的朋友是解析器生成器,而 Parsec 是解析器组合库。

解析器生成器读入语法描述并输出解析器。一般不可能现有的语法组合成一个新的语法,当然也不可能将两个现有的生成解析器组合成一个新的解析器。

解析器组合器 OTOH只是将现有解析器组合成新的解析器。通常,解析器组合器库附带几个可以解析空字符串或单个字符的简单内置解析器,并且它附带一组组合器,它们采用一个或多个解析器并返回一个新的解析器,例如,解析原始解析器的序列(例如,您可以将d解析器和o解析器组合成do解析器),原始解析器的交替(例如,0解析器和1解析器到0|1解析器)或多次解析原始解析(重复)。

这意味着,例如,您可以采用现有的 Java 解析器和现有的 HTML 解析器,并将它们组合成 JSP 解析器。

大多数解析器生成器不支持这一点,或者仅以有限的方式支持它。解析器组合器 OTOH支持此功能,不支持其他功能。

于 2011-02-20T14:03:55.310 回答
9

您可能希望看到这个问题以及问题中的链接问题。

哪种 Haskell 解析技术使用起来最愉快,为什么?

在 Haskell 中,Parsec(和其他解析器组合器)和解析器生成器 Happy 之间存在竞争。如果我已经有一个 LR 语法可以使用,我会选择 Happy - 解析器组合器采用 LL 形式的语法,从 LR 到 LL 的翻译需要一些努力,而组合器解析器通常会慢得多。如果我没有语法,我将使用 Parsec,它比 Happy 更灵活(强大),并且在“在 Haskell 中”工作比使用 Happy 和 Alex 生成代码更有趣。如果您使用 Happy 进行解析,您几乎总是需要使用 Alex 进行词法分析。

对于行业实践,决定使用 Haskell 只是为了获得 Parsec 是很奇怪的。对于解析,目前大多数语言都至少有一个解析器生成器,可能还有更灵活的东西,比如 Parsec 的端口或 PEG 系统。

Ira Baxter 对相关问题的回答是关于解析器让您仅在喜马拉雅山的立足点编写翻译器的问题,但成为翻译器的一部分只是解析器的用途之一,因此仍有许多领域像 ANTLR、Happy 和 Parsec 这样的极简系统是令人满意的。

于 2011-02-20T09:18:03.393 回答
6

继斯蒂芬的回答之后,我认为如果您想坚持使用解析器组合器,最常见的 Parsec 替代方案之一是 attoparsec。主要区别在于 attoparsec 的编写更偏向于速度,并相应地进行权衡。例如,如果解析失败,Parsec 会进行一些记账以尝试返回有用的错误消息,而 attoparsec 并没有达到同样的程度。另外,我认为 attoparsec 专门用于一种输入流/令牌类型,而 Parsec 从输入类型中抽象出来,以便它可以毫无问题地解析 String、ByteString、Text 等类型的流。

于 2011-02-20T10:12:02.817 回答