Parsec适用于“面向用户”的解析器: 输入量有限但错误消息很重要的情况。它并不是特别快,但如果输入较小,则速度不会成问题。例如,我会选择Parsec用于几乎所有的编程语言工具,因为即使最大的源文件在绝对意义上也不是非常大,但错误消息确实很重要。
Parsec可以处理不同类型的输入,这意味着您可以将其与标准的String
或来自某种外部词法分析器的标记流一起使用。由于它可以使用String
,因此它可以完美地为您处理Unicode; 像digit
和letter
之类的内置基本解析器已经支持Unicode。
Parsec还带有一个Monad Transformer,这意味着您可以将其层叠在一个Monad堆栈中。例如,如果您想在解析过程中跟踪附加状态,则可能会很有用。您还可以尝试更多的效果,如非确定性解析等 - Monad Transformers的惯常魔力。
Attoparsec比Parsec快得多。当您需要处理大量输入或性能真正重要时,应该使用它。它非常适用于像网络代码(解析数据包结构)、解析大量原始数据或处理二进制文件格式等方面。
Attoparsec可以处理ByteString
,这是一种二进制数据。这使得它成为实现二进制文件格式之类的东西的好选择。然而,由于这是针对二进制数据的,因此它不会处理文本编码; 对此,您应该使用Text
的attoparsec模块。
Attoparsec支持增量解析,而Parsec不支持。这对于某些应用程序(例如网络代码)非常重要,但对于其他应用程序则无关紧要。
Attorparsec的错误信息比Parsec更糟糕,并且为了提高性能而牺牲了一些高级特性。它专门针对
最终,Parsec和Attoparsec适用于非常不同的领域。高层次的区别在于性能:如果需要,则选择Attoparsec;如果不需要,则选择Parsec。
我的通常启发式规则是:选择Parsec进行编程语言、配置文件格式和用户输入以及几乎任何我原本会使用正则表达式处理的内容。这些通常是手工制作的东西,因此解析器不需要扩展,但需要报告错误信息。
另一方面,我会选择Attoparsec来实现网络协议、处理二进制数据和文件格式或读取大量自动生成的数据。处理时间约束或大量数据的情况下,通常不是由人直接编写的。
如您所见,选择其实常常很简单:使用情况并不重叠。很可能,在任何给定的应用程序中,将很清楚应该使用哪一个。
attoparsec
更快,但parsec
可能已默认安装,因此更方便。 - sanityincuu-parsinglib
和polyparse
。 - John L