79

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

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

  1. 阿托秒差距
  2. 秒差距

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

4

1 回答 1

148

秒差距

Parsec 适用于“面向用户”的解析器:输入量有限但错误消息很重要的事情。它不是非常快,但如果你的输入很小,这应该没关系。例如,对于几乎所有编程语言工具,我都会选择 Parsec,因为——从绝对意义上说——即使是最大的源文件也没有那么大,但错误消息确实很重要。

Parsec 可以处理不同的输入类型,这意味着您可以将它与标准String或来自某种外部词法分析器的令牌流一起使用。由于它可以使用String,它可以很好地为您处理 Unicode;内置的基本解析器喜欢digit并且letter支持 Unicode。

Parsec 还带有一个 monad 转换器,这意味着您可以将它分层放在一个 monad 堆栈中。例如,如果您想在解析期间跟踪其他状态,这可能很有用。您还可以寻求更多的幻觉效果,例如非确定性解析或其他东西 - monad 转换器的常见魔力。

阿托帕秒

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

Attoparsec 可以与ByteStrings 一起工作,它是二进制数据。这使其成为实现二进制文件格式等内容的不错选择。但是,由于这是针对二进制数据的,它不处理文本编码之类的事情;为此,您应该使用 attoparsec 模块Text

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

Attorparsec 的错误消息比 Parsec 更糟糕,并且为了性能牺牲了一些高级特性。它专门用于Textor ByteString,因此您不能将它与来自自定义词法分析器的标记一起使用。它也不是一个单子变压器。

哪一个?

最终,Parsec 和 Attoparsec 迎合了非常不同的利基市场。高级别的区别是性能:如果需要,请选择 Attoparsec;如果您不这样做,请使用 Parsec。

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

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

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

于 2013-10-06T19:54:49.547 回答