私はfparsecの基本のいくつかに精通していますが、テキストファイルまたはストリームを対象としているようです。
バイナリファイルを効率的に解析できる他のF#ライブラリはありますか?または、fparsecを簡単に変更して、バイナリストリームで効率的に動作するようにすることはできますか?
私はfparsecの基本のいくつかに精通していますが、テキストファイルまたはストリームを対象としているようです。
バイナリファイルを効率的に解析できる他のF#ライブラリはありますか?または、fparsecを簡単に変更して、バイナリストリームで効率的に動作するようにすることはできますか?
あなたはピッカーコンビネータに興味があるかもしれません。これらはパーサーコンビネーターに少し似ていますが、より単純なバイナリ形式に重点を置いています(ピッカーを使用すると、バイナリデータを生成し、アンピッカーがそれらを解析できます)。Andrew Kennedy(測定単位の作成者)によるアイデア(PDF)に関する非常に読みやすい記事があります。
私自身はこれらの経験はあまりありませんが、あなたに関係があるかもしれないことに気づきました。このアイデアは、F#コンパイラで、いくつかのバイナリリソース(リソースに格納されている引用符など)を生成するために使用されます。ただし、F#コンパイラの実装が適切かどうかはわかりません(F#コンパイラの初期の頃からの実装の1つです)。
バイナリストリームの操作に関する問題は、それ自体がパーサーの問題ではなく、字句解析の問題です。レクサーは、生データを解析で処理できる要素に変換するものです。
ほとんどの解析システムには、独自のレクサーを提供できる問題がほとんどありません。その場合、理想的には、バイナリストリームで機能する準拠レクサーを簡単に作成できます。
ただし、問題は、今日のほとんどの構文解析および字句解析システム自体が、より高いレベルのツールから作成されていることです。そして、そのツールは、バイナリストリームで動作するように設計されていない可能性があります。つまり、後続のパーサーとレクサーを作成するために使用できるバイナリストリームのトークンと文法を指定することは実用的ではありません。また、バイナリストリームで遭遇する可能性のあるマルチバイト2進数(shorts、longs、floatなど)の高レベルの概念や、生成されたパーサーがそれらに対してうまく機能する可能性があるため、サポートがまったくない可能性があります。システムは主にテキストベースのトークン用に設計されているため、実際に実際の値で作業する必要がある場合は、
とはいえ、パーサーはレクサーによってフィードされる抽象トークンでより多くの作業を行うため、おそらく実際にツールの解析セクションを使用できます。シンボリックレベルで文法を作成したら、レクサーをやり直して、バイナリストリームから問題のトークンを作成し、パーサーにフィードする必要があります。
パーサーは基本的なレクサーよりもはるかに複雑になる傾向があるため、これは実際には良いことです。そのため、ツールキットは「難しい部分」の多くを処理します。ただし、独自のレクサーを作成し、生成されたパーサーに適切にインターフェースする必要があります。克服できないタスクではありません。文法が非常に複雑な場合は、長期的には努力する価値があります。
それがすべてほとんど単純であるならば、あなたはそれを自分で手でやったほうがよいでしょう。バイナリ形式の主なセールスポイントは、ほとんどのパーサーが動作するように設計されているテキストと矛盾するマシンにはるかに近いことであるため、私の頭の中で難しいバイナリ文法を想像するのは難しいです。しかし、私はあなたのユースケースを知りません。
しかし、逆アセンブラの場合を考えてみましょう。これは、さまざまな命令タイプ(引数のないオペランド、引数として1バイトを使用するオペランド、またはワードなど)を高レベルで理解し、それをパーサーにフィードできる単純なレクサーです。次に、通常のアセンブラ構文で命令をニーモニックとオペランドに変換したり、ラベル参照などを処理したりするために使用できます。
逆アセンブラは通常、字句解析フェーズと構文解析フェーズを分離しないため、これは不自然なケースです。通常、煩わしいほど複雑ではありませんが、問題を調べる1つの方法です。
補遺:
バイナリストリームをテキストに変換してエンジンにフィードするのに十分な情報がある場合は、テキストを作成する代わりに、パーサーがレクサーから見たい実際のトークンを作成するのに十分な情報があります。
とは言うものの、あなたができることは、テキスト形式を取り、それを構文解析ツールと文法の基礎として使用し、それがあなたのためにレクサーとパーサーマシンを作成するようにすることです。そして、手で、あなたはあなたのパーサーとその「テキストテスト」を使用した処理。
ただし、バイナリの読み取りに取り掛かるときは、テキストを作成して字句解析および解析するのではなく、字句解析プログラムが作成するトークンを作成し(これらは単純なオブジェクトである必要があります)、パーサーを直接ポンピングします。これにより、lexステップが節約され、処理時間が節約されます。