我必须解析一些文件并将它们转换为一些预定义的数据类型。
Haskell 似乎为此提供了两个软件包:
这两者有什么区别,哪一个更适合根据一些规则解析文本文件?
最佳答案
秒差距
Parsec 适用于“面向用户”的解析器:输入数量有限但错误消息很重要的情况。它不是非常快,但是如果您的输入很小,这应该无关紧要。例如,我会为几乎所有的编程语言工具选择 Parsec,因为——就绝对而言——即使最大的源文件也没有那么大,但错误消息确实很重要。
Parsec 可以处理不同的输入类型,这意味着您可以将它与标准 String
或来自某种外部词法分析器的 token 流一起使用。由于它可以使用 String
,因此它可以很好地为您处理 Unicode;像 digit
和 letter
这样的内置基本解析器是 Unicode 感知的。
Parsec 还带有一个 monad 转换器,这意味着您可以将它分层放在一个 monad 堆栈中。例如,如果您想在解析期间跟踪其他状态,这可能很有用。您还可以使用更多迷幻效果,例如非确定性解析或其他东西——monad 转换器的常用魔法。
阿托帕塞克
Attoparsec 比 Parsec 快得多。当您希望获得大量输入或性能确实很重要时,您应该使用它。它非常适合网络代码(解析数据包结构)、解析大量原始数据或使用二进制文件格式等。
Attoparsec 可以处理 ByteString
s,这是二进制数据。这使它成为实现二进制文件格式等内容的不错选择。然而,由于这是针对二进制数据,它不处理文本编码之类的事情;为此,您应该对 Text
使用 attoparsec 模块。
Attoparsec 支持增量解析,而 Parsec 不支持。这对于某些应用程序(如网络代码)非常重要,但对于其他应用程序则无关紧要。
Attorparsec 的错误信息比 Parsec 更糟糕,并且为了性能牺牲了一些高级功能。它专门用于 Text
或 ByteString
,因此您不能将它与来自自定义词法分析器的标记一起使用。它也不是单子(monad)变压器。
哪一个?
最终,Parsec 和 Attoparsec 迎合了非常不同的利基市场。高层次的区别是性能:如果你需要它,选择 Attoparsec;如果你不这样做,就用 Parsec 吧。
我通常的启发是为编程语言、配置文件格式和用户输入以及几乎所有我会用正则表达式做的事情选择 Parsec。这些通常是手工生成的,因此解析器不需要扩展,但它们确实需要很好地报告错误。
另一方面,我会选择 Attoparsec 来实现网络协议(protocol)、处理二进制数据和文件格式或读取大量自动生成的数据。您处理时间限制或大量数据的事情,通常不是由人工直接编写的。
如您所见,选择实际上通常非常简单:用例不会重叠太多。很有可能,对于任何给定的应用程序使用哪一个是很清楚的。
关于haskell - haskell 中的 attoparsec 或 parsec,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19208231/