代码之家  ›  专栏  ›  技术社区  ›  Sibi

haskell中的attoparsec或parsec

  •  79
  • Sibi  · 技术社区  · 11 年前

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

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

    1. attoparsec
    2. parsec

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

    1 回复  |  直到 6 年前
        1
  •  148
  •   Tikhon Jelvis    11 年前

    分析

    Parsec适合“面向用户”的解析器:输入量有限,但错误消息很重要。它不是很快,但如果你有小的输入,这应该无关紧要。例如,对于几乎任何编程语言工具,我都会选择Parsec,因为从绝对意义上讲,即使是最大的源文件也不是 那个 大但错误的消息真的很重要。

    Parsec可以处理不同的输入类型,这意味着您可以将其与标准一起使用 String 或者使用来自某种外部lexer的令牌流 一串 ,它可以很好地处理Unicode;内置的基本解析器 digit letter 支持Unicode。

    Parsec还附带了一个monad转换器,这意味着您可以将其分层到monad堆栈中。例如,如果您想在解析过程中跟踪其他状态,这可能会很有用。你也可以选择更令人眼花缭乱的效果,比如非确定性解析,或者其他什么——monad transformer的常见魔力。

    Attoparsec公司

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

    Attoparsec可以使用 ByteString s、 它们是 二进制的 数据这使得它成为实现二进制文件格式之类的东西的一个很好的选择。然而,由于这是针对二进制数据的,所以它不处理诸如文本编码之类的事情;为此,您应该使用attoparsec模块 Text .

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

    Attorparsec的错误消息比Parsec更糟糕,并且为了性能牺牲了一些高级功能。它专门用于 文本 字节字符串 ,所以您不能将它与来自自定义lexer的令牌一起使用。它也不是monad转换器。

    哪一个?

    最终,Parsec和Attoparsec迎合了截然不同的利基市场。高级差异在于性能:如果您需要,请选择Attoparsec;如果你不这样做,就用Parsec吧。

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

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

    正如您所看到的,选择通常非常简单:用例不会有太多重叠。很有可能,在任何给定的应用程序中使用哪一个都非常清楚。