haskell中的attoparsec或parsec


76

我必须解析一些文件,并将它们转换为一些预定义的数据类型。

Haskell似乎为此提供了两个软件包:

  1. 阿托帕塞
  2. 差距

两者之间有什么区别,哪一个更适合根据某些规则解析文本文件?


它们大致相等。attoparsec速度更快,但parsec可能默认情况下已安装,因此可能更方便。
sanityinc

1
用于模块Data.Attoparsec.ByteString文档具有秒差距和Attoparsec之间的比较:hackage.haskell.org/package/attoparsec-0.10.4.0/docs/...
danidiaz

6
我只想提及Haskell提供了两个以上的包来进行解析,但是您缺少了几个非常好的包,尤其是uu-parsingliband polyparse
约翰·L

@JohnL谢谢,不知道。
2013年

Answers:


140

差距

Parsec对于“面向用户”的解析器非常有用:输入有限但错误消息很重要的事情。它的速度不是很快,但是如果您输入的内容很少,那就没关系了。例如,实际上,我会选择Parsec作为所有编程语言工具,因为就绝对而言,即使最大的源文件也没有那么大,但错误消息确实很重要。

Parsec可以在不同的输入类型上工作,这意味着您可以将其与标准String或来自某种外部词法分析器的令牌流一起使用。由于可以使用String,它可以为您完美地处理Unicode。内置的基本解析器(例如digit和)letter可识别Unicode。

Parsec还附带了monad变压器,这意味着您可以将其堆叠在monad堆栈中。例如,如果您想在解析期间跟踪其他状态,这可能会很有用。您还可以使用更多不确定的效果,例如非确定性解析或其他一些东西,这些通常是monad变压器的魔术。

阿托帕塞克

Attoparsec比Parsec快得多。当您期望获得大量输入或性能确实很重要时,应使用它。这对网络代码(解析数据包结构),解析大量原始数据或使用二进制文件格式等功能非常有用。

Attoparsec可以使用ByteStrings,它们是二进制数据。这是实现诸如二进制文件格式之类的好选择。但是,由于这是针对二进制数据的,因此它无法处理诸如文本编码之类的事情;为此,您应该将attoparsec模块用于Text

Attoparsec支持增量解析,而Parsec不支持。这对于某些应用程序(例如网络代码)非常重要,但对于其他应用程序则无关紧要。

Attorparsec的错误消息比Parsec差,并且牺牲了一些高级功能来提高性能。它专用于TextByteString,因此您不能将其与来自自定义词法分析器的标记一起使用。它也不是monad变压器。

哪一个?

最终,Parsec和Attoparsec迎合了截然不同的壁ni。最高的区别在于性能:如果需要,请选择Attoparsec;如果不这样做,请使用Parsec。

我通常的试探方法是选择Parsec作为编程语言,配置文件格式和用户输入,以及我使用正则表达式所做的几乎所有事情。这些通常是手工制作的,因此解析器不需要扩展,但确实需要很好地报告错误。

另一方面,我会选择Attoparsec来实现网络协议,处理二进制数据和文件格式或读取大量自动生成的数据。您在处理时间限制或大量数据的情况下,通常不是人类直接写的东西。

如您所见,选择实际上通常很简单:用例不会有太多重叠。很可能会很清楚地在任何给定应用程序中使用哪个。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.