質問
文法を含むファイルから C++ でパーサーを作成する最良の方法は何ですか?
解決
他のヒント
それは文法に大きく依存します。私は再帰降下パーサーを好む傾向があり、通常は手動で作成されます (ただし、文法の記述から生成することは可能です)。
パーサー ジェネレーターを使用する場合、実際には 2 つの適切な選択肢があります。ビャックとアントラー。yacc と (適度に) 互換性のあるものが必要な場合は、Byacc が (断然) 最良の選択です。既存のコードも経験もなく、yacc と互換性のあるものを使用することを好む最初から始める場合は、ほぼ間違いなく Antlr が最善の策です。
せっかく話題になったので、Bisonについても少しお話します。私はバイソンを疫病のように避けたいと思います。「1 つを捨てる計画を立てる」というブルックス氏のアドバイスがここにも当てはまります。Robert Corbett (Byacc の著者) は、パーサー ジェネレーターへの最初の試みとして Bison を作成しました。残念ながら、彼はそれを捨てずに GNU に渡しました。マーケティングが優れた技術に勝るという典型的なケースでは、Bison は広く使用されています (よく知らない人からも推奨されています) が、Byacc は比較的知られていません。
編集:あまりやりたくないのですが、話題にもなったのでBoost.spiritについてもコメントしておきます。これはテンプレート メタ プログラミングの最もクールな例かもしれませんが、本格的に使用することはお勧めできない問題がいくつかあります。
- コンパイル時間は耐え難いものになる可能性があります。10 分かかることはよくありますが、より大規模で複雑な文法ではさらに時間がかかることがあります (コンパイラーがクラッシュしないと仮定すると)。
- 少しでも間違いを犯すと、事実上解読が不可能な非常に長いエラー メッセージが生成される可能性があり、頻繁に生成されます。いずれにしても、テンプレートを多用したコードからのエラー メッセージは悪質であることで知られており、Spirit は他の何よりもシステムにストレスを与えます。
私を信じて:Spirit のようなものが書けるという事実は、印象的と驚くべきのちょうど境界線上にあります。しかし、私は、自分が扱っている文法が正しいと確信できる場合にのみそれを使います (そしてこれからもずっと残り続けるでしょう)。 とても 小さくてシンプル。
あなたは LexとYaccのまで見たことがありますか?リンクされたドキュメントのセクション5から引用します:
C ++パーサを作るために、私の好ましい方法 レックスは、プレーンCを生成することです ファイル、およびYACCはCを生成させるために++ コード。次に、あなたをリンクすると アプリケーションは、いくつかのに遭遇することがあり 問題C ++コードであるため デフォルトでは、Cを見つけることができません 機能は、あなたがそれを語っていない限り、その これらの機能は、 "C" のexternされます。
私が使用してきましたバイソンに、ちょうど私のレベルのための例を見つけました。もちろん、それははるかに行うことができ、それをシンプルな電卓を作成することができました。
電卓は、例えば1 + 2 * 3を取って、構文木を構築しました。ドキュメントはしかし、ツリーを構築する方法について説明していなかった、それが動作するように私には少し時間がかかりました。
私は再び起こった場合、それは良いとよくサポートに見えたとして私は「ANTLR」に見えると思います。
マーティンます。
パーサを作成するための最良の方法は、lexとyaccのを使用することです。