2011-10-17 1 views
12

私はfparsecの基本のいくつかに精通していますが、テキストファイルやストリームに対応しているようです。バイナリ(テキストではない)ファイルを解析できる既知のパーサーコンビネータライブラリはF#にありますか?

効率的にバイナリファイルを解析できる他のF#ライブラリはありますか?あるいは、バイナリストリームで効率的に動作するようにfparsecを簡単に変更できますか?

+2

私は2年後にこれについて言及したいと思いますが、私はこれを行うプロジェクトに取り組んでいます。 fparsecスタイルのコンビネータを使って書かれたmp4コンテナバイナリパーサのサンプルがあります。 https://github.com/devshorts/ParsecClone – devshorts

答えて

10

ピックラーコンビネータです。これらはパーサーコンビネータのようなものですが、より単純なバイナリ形式に焦点が当てられています(ピラーのはバイナリデータを生成し、のunpicklerを解析できます)。 Andrew Kennedy(測定単位の作成者)のquite readable article about the idea(PDF)があります。

私はこれらの経験はあまりありませんが、私はそれがあなたにとって適切かもしれないことに気付きました。このアイデアは、いくつかのバイナリリソース(リソースに格納された引用など)を生成するためにF#コンパイラで使用されます。しかし、私はF# compiler implementationが良いかどうかはわかりません(F#コンパイラの初期のものの1つです)。

+0

エキスパートのF#ブックから「pickler」という言葉を覚えていると思います... ありがとうTomas私もそれらをチェックアウトします。これは、F#コンパイラで述べた再開もIではないことをチェックするつもりでした。 – 7sharp9

+0

@Tomasあなたが提出したリンクの文書を見て、[worker /ラッパー変換](http://www.monadgarden.com/andy/papers/wrapper.pdf)を参照してください。あなたのリンクの終わりに向かってMLでpicklerを実装する方法についての議論を見てください。 –

+0

私はMonadic picklesのために行っています:-) – 7sharp9

6

バイナリストリームを扱う際の問題は、それ自体がパーサーの問題ではなく、字句問題です。レクサーは、生データを解析で処理できる要素に変換するものです。

ほとんどの構文解析システムでは、独自のレクサーを提供することに問題はほとんどなく、理想的には、バイナリストリームで動作する準拠レクサーを簡単に書くことができます。

しかし、今日の解析とレキシングシステムのほとんどは、それ自身が上位レベルのツールから作成されているという問題があります。そして、そのツールはバイナリストリームで動作するようには設計されていない可能性が高いです。つまり、後続のパーサとレクサーを作成するために使用できるバイナリストリームのトークンと文法を指定することは現実的ではありません。また、バイナリストリームで遭遇する可能性のあるマルチバイトバイナリナンバー(short、longs、floatなど)のより高いレベルの概念や、生成されたパーサがおそらくうまく機能するためのサポートはありませんシステムがテキストベースのトークンのために設計されていて、基本的なランタイムがそのテキストをマシンが使用できるものに変換する詳細を処理しているからです(例えば、アスキー文字列を実際のバイナリ整数)。

パーザはレクサーによって与えられた抽象トークンでより多く働くので、おそらく実際にはツールの解析セクションを使用することができます。シンボリック・レベルで文法を作成したら、バイナリ・ストリームから問題のトークンを作成してパーサにフィードするためにレクサーをやり直す必要があります。

パーサは基本的なレクサーよりもはるかに複雑な傾向があるので、実際には良いですから、ツールキットはあなたのために「難しい部分」の多くを処理します。しかし、あなたはまだ独自のレクサーを作成し、生成されたパーサーに適切にインターフェースする必要があります。克服できない課題でもあり、文法が本当に複雑であれば、長期的にはあなたの努力の価値があるでしょう。

ほとんどすべてが簡単な場合は、自分で手作業をする方がよいでしょう。私の頭の中では、難しいバイナリ文法を想像するのは難しいです。なぜなら、バイナリ形式の大きなセールスポイントは、それがマシンに非常に近いことです。これは、ほとんどのパーサが動作するように設計されているテキストと矛盾します。しかし、私はあなたのユースケースを知らない。

しかし、逆アセンブラの場合を考えてみましょう。これは、単純なレクサーであり、異なる命令型(引数を持たないオペランド、引数として1バイトを取るオペランド、またはワードなど)を高レベルで立てて、それをパーサーに送ることができるかもしれません命令を通常のアセンブラ構文のニーモニックとオペランドに変換し、ラベル参照などを処理するために使用できます。

逆アセンブラは通常、レキシングと構文解析のフェーズを分離しないので、通常は複雑ではありませんが、問題を見る方法の1つです。

補遺:

あなたがエンジンに供給するために、テキストにしてバイナリストリームを変換するための十分な情報を持っている場合は、あなたがあなたの代わりにテキストを作成するのではなく、あなたがそのパーサ実際のトークンを作成することができますするのに十分な情報を持っていますレクサーから見たいと思うでしょう。

あなたができることは、テキスト形式をとり、それを解析ツールと文法の基礎として使用し、レクサーとパーサのマシンを作成してから手でテストすることですあなたのパーサーとその処理は "テキストテスト"を使用します。

しかし、テキストを作成して解析するのではなく、レクサーが作成するトークン(単純なオブジェクトである必要があります)を作成し、パーサを直接ポンピングします。これにより、レックスのステップが節約され、処理時間が節約されます。

+0

詳細な回答をいただきありがとうございます。私は、低レベルの文法のサブセットを扱い、それを上向きにfparsecのようなもので処理できるブロックに構成することを前提に作業を進めるつもりでした。 つまり、(pbyte 0x45)>> = fun x - >(pbyte 0x78)などです。その後、それらのブロックを使用して多分テキストを生成し、fparsecで処理することができます。 – 7sharp9

関連する問題

 関連する問題