要学习如何编写和解析无上下文语法,我想选择一个工具。对于Haskell,有两个很大的选项:Happy,它从语法描述中生成解析器,以及* Parsec,它允许您直接在Haskell中编写解析器。
这两种方法的(dis)优势是什么?
答案 0 :(得分:23)
外部与内部DSL
Happy的解析器规范格式是外部DSL,而Parsec在定义解析器时可以使用Haskell的全部功能。这意味着您可以编写函数来生成解析器,使用Template Haskell等。
优先规则
使用Happy,您可以使用precedences来简化语法,而使用Parsec,您必须自己正确地嵌套语法规则。因此,在Parsec中更改运算符的优先级会更加繁琐。
静态检查
Happy会在编译时警告你语法的模糊性。 (虽然告诉你他们在哪里并不是很好。)使用Parsec,在解析器在运行时失败之前,你不会收到任何警告。
答案 1 :(得分:4)
这是传统的决定:我使用lex / yacc(happy)还是编写自己的(主要是递归下降)解析器,只是说parsec库就像DSL一样正确。
如果有人对yacc / lex方法有经验,那么使用happy将是一个较小的学习曲线。
答案 2 :(得分:1)
在我看来,Parsec隐藏了大部分讨厌的语法细节,让你更直观地编写解析器。如果你想在第一时间学习这些东西,请使用像Happy这样的解析器生成器(或者甚至尝试自己实现)。
答案 3 :(得分:1)
我已经习惯了来自乌得勒支大学的解析器组合库uu-parsinglib。一个人可以免费纠错和排列,以及parsec所拥有的东西。我也喜欢它,因为我实现的语法看起来像一个EBNF语法,没有太多的monadic东西,而且很容易阅读。
答案 4 :(得分:0)
天真的解析器组合器不允许在语法规则中使用左递归,而且我没有找到可以执行的库。
Happy确实允许语言规范中的完整BNF,以及一些有用的人员,如优先级规则。因此,对于复杂的情况,Happy和解析器生成器通常要好得多。但是,对于具有LL(k)可解析语法的简单,愚蠢的语言,我会使用解析器组合器库作为更多维护者友好。