haskell中的attoparsec或parsec

问题描述 投票:67回答:1

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

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

  1. attoparsec
  2. parsec

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

haskell parsec attoparsec
1个回答
124
投票

Parsec

Parsec适用于“面向用户”的解析器:您有大量输入但错误消息很重要的事情。它的速度并不快,但如果你输入的数量很少,那就不重要了。例如,我会选择Parsec用于几乎所有编程语言工具,因为 - 从绝对意义上说 - 即使是最大的源文件也不是那么大但错误消息确实很重要。

Parsec可以处理不同的输入类型,这意味着您可以使用标准的String或来自某种外部词法分析器的标记流。由于它可以使用String,它可以很好地处理Unicode;像digitletter这样的内置基本解析器是支持Unicode的。

Parsec还带有monad变换器,这意味着你可以将它叠加在monad堆栈中。例如,如果要在解析期间跟踪其他状态,这可能很有用。你也可以去寻找更多的幻觉效果,比如非确定性的解析,或者其他东西 - 通常是monad变换器的魔力。

Attoparsec

Attoparsec比Parsec快得多。当您希望获得大量输入或性能时,您应该使用它。它非常适合网络代码(解析数据包结构),解析大量原始数据或使用二进制文件格式等。

Attoparsec可以使用ByteStrings,它是二进制数据。这使它成为实现二进制文件格式等的好选择。但是,由于这是针对二进制数据的,因此它不处理文本编码等问题;为此,你应该使用attoparsec模块为Text

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

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

Which One?

最终,Parsec和Attoparsec迎合了不同的利基。高级差异是性能:如果需要,请选择Attoparsec;如果你不这样做,那就去Parsec吧。

我通常的启发式方法是选择Parsec用于编程语言,配置文件格式和用户输入,以及几乎任何我用regex做的事情。这些通常是手工生成的,因此解析器不需要扩展,但它们确实需要很好地报告错误。

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

如您所见,选择实际上通常非常简单:用例不会非常重叠。可能很清楚,哪一个用于任何给定的应用程序。

© www.soinside.com 2019 - 2024. All rights reserved.