Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell Parsec与Yacc/Bison/Antlr:为什么以及何时使用Parsec?_Haskell_Parsec - Fatal编程技术网

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

Haskell Parsec与Yacc/Bison/Antlr:为什么以及何时使用Parsec?,haskell,parsec,Haskell,Parsec,我是Haskell和Parsec的新手。在阅读之后,我的脑海中出现了一个问题:为什么和什么时候Parsec比其他解析器生成器(如Yacc/Bison/Antlr)更好 我的理解是,Parsec创建了一个编写解析器的良好DSL,Haskell使之非常简单和富有表现力。但是解析是一种标准/流行的技术,它应该有自己的语言,可以输出到多个目标语言。那么,我们什么时候应该使用Parsec而不是从Bison/Antlr生成Haskell代码呢 这个问题可能会超越技术,进入工业实践领域。当从头开始编写解析器时

我是Haskell和Parsec的新手。在阅读之后,我的脑海中出现了一个问题:为什么和什么时候Parsec比其他解析器生成器(如Yacc/Bison/Antlr)更好


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

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


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

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

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

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


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

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

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

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

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

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


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

“但解析是一种标准/流行的技术,它应该拥有自己的语言,可以输出到多个目标语言。”我很想知道为什么——我对这个主题的了解不够,无法真正同意或不同意,但这肯定不是一个不言而喻的说法。s/combinator/combinator library。从经典意义上讲,combinator是一个接受函数并返回函数的函数。combinator library是一个由部分,combinator函数。@sclv:谢谢。我想我修复了所有我实际谈论库作为一个整体的实例,并留下了那些我实际谈论单个combinator的实例。我非常感谢你的评论,因为我通常是一个坚持正确术语的人。有趣的是,大多数Ruby和SmalltalkParsec的端口结合了解析器对象,而不是解析器函数,当然函数只是一个只有一个方法的对象,而对象只是部分应用于
this
:-)的函数的(记录)attoparsec的解析器也是一个应用函数,但重要的是不是单子。这意味着使用应用组合符集()而不是do表示法或monad函数。@John F.Miller我不确定是否曾经有过Attoparsec的解析器不是monad的情况,但现在肯定不是这样,我非常怀疑这种情况。Parsec和Attoparsec都鼓励在可能的情况下使用Applications而不是Monad,不过。。。事实上,我刚查过,最早的版本是2008年的Hackage,比你的帖子早5年,它是单子。因此,这显然是不正确的信息。