在F#中是否有任何已知的解析器组合库可以解析二进制(而不是文本)文件?

7sh*_*rp9 13 binary f# parsing parser-combinators fparsec

我熟悉fpar​​sec的一些基础知识,但它似乎是面向文本文件或流.

还有其他F#库可以有效地解析二进制文件吗?或者可以轻松修改fparsec以便有效地使用二进制流?

Tom*_*cek 12

您可能对pickler combinators感兴趣.这些有点像解析器组合器,但更侧重于更简单的二进制格式(pickler允许您生成二进制数据,unpickler解析它们).Andrew Kennedy(测量单位的作者)有一篇关于这个想法(PDF)的可读文章.

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


Wil*_*ung 6

使用二进制流的问题本身并不是解析器问题,这是一个棘手的问题.词法分析器将原始数据转换为解析可以处理的元素.

大多数解析系统都没有问题让你提供自己的词法分析器,如果是这样的话,你可以理想地编写一个适用于你的二进制流的兼容词法分析器.

然而,问题是今天的大多数解析和lexing系统本身都是从更高级别的工具创建的.而这个工具很可能不适用于二进制流.也就是说,指定可用于创建后续解析器和词法分析器的二进制流的标记和语法是不切实际的.此外,对于您可能在二进制流中遇到的多字节二进制数(short,long,float等)的更高级概念,也可能没有任何支持,生成的解析器也可能无法正常工作如果你真的需要处理它们的实际值,那么再次因为系统主要是为基于文本的标记设计的,而底层运行时处理转换该文本的细节,这是机器可以使用的东西(例如ascii数字到实际的序列)二进制整数).

总而言之,您可能实际上可以使用该工具的解析部分,因为解析器更多地处理由词法分析器提供它们的抽象令牌.一旦创建了语法,在符号级别,您将需要重做词法分析器以从二进制流创建问题标记以输入解析器.

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

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

但考虑一下反汇编的情况.这是一个简单的词法分析器,它可以在不同的指令类型(例如那些没有参数的操作数,那些将单个字节作为参数或单词的操作数)置于高级别,并将其提供给解析器然后可以使用普通汇编语法将指令转换为其助记符和操作数,以及处理标签引用等.

这是一个人为设计的案例,因为反汇编程序通常不会分离lexing和解析阶段,它通常不够复杂,但它是查看问题的一种方法.

附加物:

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

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

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