28

要学习如何编写和解析上下文无关语法,我想选择一个工具。对于 Haskell,有两个大选项:Happy,它从语法描述生成解析器和 *Parsec,它允许您直接在 Haskell 中编写解析器。

两种方法的(缺点)优点是什么?

4

5 回答 5

25

外部与内部 DSL

Happy 的解析器规范格式是外部 DSL,而使用 Parsec,您可以在定义解析器时使用 Haskell 的全部功能。这意味着您可以编写函数来生成解析器,使用 Template Haskell 等等。

优先规则

使用 Happy,您可以使用优先级来简化语法,而使用 Parsec,您必须自己正确嵌套语法规则。因此,在 Parsec 中更改运算符的优先级要繁琐得多。

静态检查

Happy 会在编译时警告您语法中的歧义。(虽然它不能很好地告诉您它们在哪里。)使用 Parsec,您不会收到任何警告,直到您的解析器在运行时失败。

于 2011-09-01T13:18:08.103 回答
4

这是传统的决定:我是使用 lex/yacc(快乐)还是我自己编写(主要是递归下降)解析器,只是 parsec 库就像一个 DSL 来做正确的事。

如果有使用 yacc/lex 方法的经验,那么使用 happy 将是一个更小的学习曲线。

于 2011-09-01T11:06:55.993 回答
2

在我看来,Parsec 隐藏了大部分令人讨厌的语法细节,让您更直观地编写解析器。如果您想首先学习这些东西,请使用像 Happy 这样的解析器生成器(或者甚至尝试自己实现一个)。

于 2011-09-01T11:13:36.647 回答
1

我习惯了乌得勒支大学的解析器组合库uu-parsinglib。一个人可以免费进行纠错和排列,还有 parsec 拥有的东西。我也喜欢它,因为我实现的语法看起来像 EBNF 语法,没有那么多单子的东西,而且很容易阅读。

于 2011-09-12T13:36:29.860 回答
1

天真的解析器组合器不允许语法规则中的左递归,我还没有找到一个库。

Happy 确实允许语言规范中的完整 BNF,以及一些有用的人员,例如优先级规则。因此,对于复杂的情况,Happy 和解析器生成器通常要好得多。但是,对于具有 LL(k) 可解析语法的简单、愚蠢的语言,我会使用解析器组合器库,因为它对维护者更友好。

于 2012-08-09T16:01:37.770 回答