13

我熟悉 fparsec 的一些基础知识,但它似乎面向文本文件或流。

是否有任何其他 F# 库可以有效地解析二进制文件?还是可以轻松修改 fparsec 以有效地处理二进制流?

4

2 回答 2

12

您可能对pickler 组合器感兴趣。这些有点像解析器组合器,但更专注于更简单的二进制格式(picklers允许您生成二进制数据并unpicklers解析它们)。Andrew Kennedy(度量单位的作者)有一篇关于这个想法(PDF)的可读性很强的文章。

我自己对这些没有太多经验,但我只是意识到它可能与你有关。这个想法在 F# 编译器中用于生成一些二进制资源(如存储在资源中的引用)。虽然,我不确定F# 编译器实现是否有任何好处(这是 F# 编译器早期的那些东西之一)。

于 2011-10-17T23:57:14.450 回答
6

使用二进制流的问题本身不是解析器问题,而是词法分析问题。词法分析器将原始数据转换为解析器可以处理的元素。

大多数解析系统在让您提供自己的词法分析器时几乎没有问题,如果是这种情况,理想情况下,您可以轻松编写适用于二进制流的兼容词法分析器。

然而,问题在于,当今大多数解析和词法分析系统本身都是由更高级别的工具创建的。而且那个工具很可能不是为处理二进制流而设计的。也就是说,您指定可用于创建后续解析器和词法分析器的二进制流的标记和语法是不切实际的。此外,对于您可能在二进制流中遇到的多字节二进制数(short、long、float 等)的高级概念,可能不支持任何支持,也不支持生成的解析器可能在它们上很好地工作如果你真的需要处理它们的实际价值,同样因为这些系统主要是为基于文本的令牌设计的,

综上所述,您可能实际上可以使用该工具的解析部分,因为解析器更多地处理由词法分析器提供给它们的抽象标记。在符号级别创建语法后,您将需要重做词法分析器以从二进制流创建问题标记以馈送到解析器。

这实际上很好,因为解析器往往比基本词法分析器复杂得多,所以工具包将为您处理大部分“困难部分”。但是您仍然需要处理创建自己的词法分析器并将其正确连接到生成的解析器。这不是一项不可逾越的任务,如果语法真的很复杂,从长远来看可能值得你付出努力。

如果这一切都很简单,那么你最好自己动手做。在我的脑海中,很难想象一个困难的二进制语法,因为二进制格式的主要卖点是它更接近机器,这与大多数解析器设计用于处理的文本相矛盾。但我不知道你的用例。

但是考虑反汇编程序的情况。这是一个简单的词法分析器,它可能能够从高层次上理解不同的指令类型(例如那些没有参数的操作数,那些将单个字节作为参数或一个字的操作数),并将其提供给解析器然后可用于将指令转换为正常汇编语法中的助记符和操作数,以及处理标签引用等。

这是一个人为的案例,因为反汇编程序通常不会将词法分析和解析阶段分开,它通常不会复杂到令人烦恼,但这是看待问题的一种方式。

附加物:

如果您有足够的信息将二进制流转换为文本以提供给引擎,那么您有足够的信息来代替创建文本,您可以创建解析器希望从词法分析器中看到的实际标记。

也就是说,您可以做的是获取您的文本格式,将其用作解析工具和语法的基础,并让它为您创建词法分析器和解析器机器,然后您可以手动测试您的解析器及其使用“文本测试”进行处理。

但是当您开始阅读二进制文件时,而不是创建文本然后进行词法分析和解析,只需创建词法分析器将创建的标记(这些应该是简单的对象),然后直接抽取解析器。这将为您节省 lex 步骤并节省一些处理时间。

于 2011-10-17T23:14:31.127 回答