我必须解析一些文件,并将它们转换为一些预定义的数据类型。
Haskell似乎为此提供了两个软件包:
两者之间有什么区别,哪一个更适合根据某些规则解析文本文件?
uu-parsinglib
and polyparse
。
Answers:
Parsec对于“面向用户”的解析器非常有用:输入有限但错误消息很重要的事情。它的速度不是很快,但是如果您输入的内容很少,那就没关系了。例如,实际上,我会选择Parsec作为所有编程语言工具,因为就绝对而言,即使最大的源文件也没有那么大,但错误消息确实很重要。
Parsec可以在不同的输入类型上工作,这意味着您可以将其与标准String
或来自某种外部词法分析器的令牌流一起使用。由于可以使用String
,它可以为您完美地处理Unicode。内置的基本解析器(例如digit
和)letter
可识别Unicode。
Parsec还附带了monad变压器,这意味着您可以将其堆叠在monad堆栈中。例如,如果您想在解析期间跟踪其他状态,这可能会很有用。您还可以使用更多不确定的效果,例如非确定性解析或其他一些东西,这些通常是monad变压器的魔术。
Attoparsec比Parsec快得多。当您期望获得大量输入或性能确实很重要时,应使用它。这对网络代码(解析数据包结构),解析大量原始数据或使用二进制文件格式等功能非常有用。
Attoparsec可以使用ByteString
s,它们是二进制数据。这是实现诸如二进制文件格式之类的好选择。但是,由于这是针对二进制数据的,因此它无法处理诸如文本编码之类的事情;为此,您应该将attoparsec模块用于Text
。
Attoparsec支持增量解析,而Parsec不支持。这对于某些应用程序(例如网络代码)非常重要,但对于其他应用程序则无关紧要。
Attorparsec的错误消息比Parsec差,并且牺牲了一些高级功能来提高性能。它专用于Text
或ByteString
,因此您不能将其与来自自定义词法分析器的标记一起使用。它也不是monad变压器。
最终,Parsec和Attoparsec迎合了截然不同的壁ni。最高的区别在于性能:如果需要,请选择Attoparsec;如果不这样做,请使用Parsec。
我通常的试探方法是选择Parsec作为编程语言,配置文件格式和用户输入,以及我使用正则表达式所做的几乎所有事情。这些通常是手工制作的,因此解析器不需要扩展,但确实需要很好地报告错误。
另一方面,我会选择Attoparsec来实现网络协议,处理二进制数据和文件格式或读取大量自动生成的数据。您在处理时间限制或大量数据的情况下,通常不是人类直接写的东西。
如您所见,选择实际上通常很简单:用例不会有太多重叠。很可能会很清楚地在任何给定应用程序中使用哪个。
attoparsec
速度更快,但parsec
可能默认情况下已安装,因此可能更方便。