Parsec vs Yacc / Bison / Antlr:为什么以及何时使用Parsec?

我是Haskell和Parsec的新手。 在阅读第16章使用Haskell的Parsec之后,我想起了一个问题:为什么Parsec比其他parsing器生成器(比如Yacc / Bison / Antlr)更好?

我的理解是,Parsec创build了一个很好的编写parsing器的DSL,Haskell使它非常容易和expression。 但是parsing就是这样一种标准/stream行的技术,值得自己的语言输出到多种目标语言。 那么我们什么时候应该使用Parsec而不是从Bison / Antlr生成Haskell代码呢?

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

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

您列出的工具之间的主要差异之一是,ANTLR,Bison和他们的朋友是parsing器生成器 ,而Parsec是parsing器组合器库。

parsing器生成器读入语法的描述并吐出parsing器。 通常不可能现有的语法组合成一个新的语法,而且将两个现有的生成的语法分析器合并成一个新的语法分析器当然是不可能的。

parsing器组合器OTOH除了将现有的parsing器组合成新的parsing器之外什么都不做。 通常,一个parsing器组合函数库附带了一些可以parsing空string或单个字符的简单的内置parsing器,并附带一组组合器,它们携带一个或多个parsing器并返回一个新的parsing器,例如,parsing原始parsing器的序列(例如,您可以将dparsing器和oparsing器组合成一个parsing器),原始parsing器(例如0parsing器和1parsing器到0|1parsing器)的交替或多次parsing原始parsing(重复)。

这意味着,例如,您可以使用现有的Javaparsing器和现有的HTMLparsing器,并将它们合并到JSP的parsing器中。

大多数parsing器生成器不支持这个,或者只能以有限的方式支持它。 parsing器组合器 OTOH 支持这一点,没有别的。

你可能想看到这个问题以及你的问题中的链接。

哪个Haskellparsing技术是最令人愉快的使用,为什么?

在Haskell中,竞争是在Parsec(和其他parsing器组合器)和parsing器生成器Happy之间进行的。 如果我已经有一个LR语法工作,我会selectHappy。 – parsing器组合器以LLforms创build语法,从LR到LL的翻译需要付出一些努力,而组合器parsing器通常会显着变慢。 如果我没有语法,我将使用Parsec,它比Happy更灵活(function强大),而且在“Haskell”中工作的乐趣比用Happy和Alex生成代码更有趣。 如果你使用Happy进行分析,你几乎总是需要使用Alex进行分类。

对于行业惯例,决定使用Haskell来获得Parsec是很奇怪的。 对于parsing,大部分当前的语言作品至less会有一个parsing器生成器,可能像Parsec或PEG系统的端口那样更灵活。

Ira Baxter对关联问题的回答是关于一个parsing器让你只是为了写一个译者而喜欢喜马拉雅山的脚印 ,但作为译者的一部分,它只是parsing器的一个用途,所以还有很多域像ANTLR,Happy和Parsec这样相当简约的系统是令人满意的。

继斯蒂芬的回答之后,我认为Parsec最常见的select之一,如果你想坚持parsing器组合器,是attoparsec。 主要的区别在于attoparsec更多的是偏向于速度,并相应地进行权衡。 例如,如果parsing失败,Parsec会做一些logging来尝试返回有用的错误消息,而attoparsec不会达到相同的程度。 此外,我认为attoparsec专门针对一个inputstream/标记types,而Parsec从inputtypes抽象,以便它可以毫无问题地parsingString,ByteString,Text等types的stream。