C/C++ パーサー/アナライザーを作成するための優れたツール [終了]
質問
C/C++ コードの解析と分析をすぐに始めるための優れたツールは何ですか?
特に、C/C++ プリプロセッサと言語を処理するオープン ソース ツールを探しています。これらのツールは文法に lex/yacc (または flex/bison) を使用し、あまり複雑にならないことが望ましいです。最新の ANSI C/C++ 定義を処理する必要があります。
これまでに見つけたものは次のとおりですが、詳しくは見ていません(考え?)。
- CSスコープ - オールドスクールな C アナライザー。ただし、完全な解析は行っていないようです。C 関数を検索するための美化された「grep」として説明されます。
- GCC - みんなに人気のオープンソース コンパイラ。非常に複雑ですが、すべてを実行できるようです。という GCC 拡張機能を作成するための関連プロジェクトがあります。 宝石, 、ただし、GCC 4.1 (2006) 以降更新されていません。
- プーマ - 純粋なマニピュレーター。(ページより:「このプロジェクトの意図は、C/C ++ソースの分析と操作のためのクラスのライブラリを提供することです。この目的のために、PUMAはスキャン、解析、そしてもちろんC/C ++ソースの操作のためのクラスを提供します。」)。これは有望に見えますが、2001 年以来更新されていません。どうやらPUMAが組み込まれているようです。 アスペクトC++, しかし、このプロジェクトも2006年以来更新されていません。
- さまざまな C/C++ の生の文法。得られる c-c++-grammars-1.2.tar.gz, しかし、これは1997年以来メンテナンスされていません。Google で少し検索すると、出発点として役立つ他の基本的な lex/yacc 文法が見つかります。
- 他のもの?
これを C/C++ ソースを新しいおもちゃ言語に翻訳するための出発点として使用したいと考えています。
ありがとう!-マット
(2/9追加):説明だけ:C/C++ コード自体に加えて、プリプロセッサからセマンティック情報を抽出したいと考えています。「#define foo 42」が整数「42」に消えてしまうのではなく、「foo」という名前に付けられたままにしておきたいのです。残念ながら、これには、最初にプリプロセッサを実行し、C/C++ 解析ツリーのみを提供するいくつかのソリューションが除外されます)。
解決
C++ の解析は文法が決定できないため、非常に困難です。引用するには ヨッシ・クライニン:
極めて複雑な文法
「顕著に」は文字通りに解釈する必要があります。 すべての一般的な言語 持っている コンテキストフリー (または「ほぼ」文脈自由な) 文法を備えていますが、C++ には 決められない 文法。コンパイラやパーサーが好きなら、おそらくこれが何を意味するか知っているでしょう。この種のことに興味がない場合は、 簡単な例 C++ の解析に関する問題を示しています。は
AA BB(CC);
オブジェクト定義ですか、それとも関数宣言ですか?答えはコードに大きく依存していることがわかります 前に ステートメント - 「コンテキスト」。これは、C++ 文法が非常に文脈依存的であることを (直感的なレベルで) 示しています。
他のヒント
あなたの問題に応じて GCCXML それがあなたの答えかもしれません。基本的に、GCC を使用してソースを解析し、簡単に理解できる解析ツリーの XML を提供します。GCCXML を使用すると、これですべてが完了します。
Boost/Spirit フレームワークがあり、数年前にはそうなりました。 C++ パーサーを実装するというアイデアを試してみる, 、しかしそれは 完成にはほど遠い.
ISO C++ を完全かつ適切に解析することは決して簡単なことではなく、実際に関連する取り組みが数多くありました。しかし、これは本質的に複雑なジョブであり、C++ のすべてを理解して完全なコンパイラ フロントエンドを書き直さない限り、簡単に達成することはできません。 そして プリプロセッサ。「wave」と呼ばれるプリプロセッサ実装は、Spirit の人々から入手できます。
そうは言っても、あなたは見てみたいかもしれません 豚肉/オインク (elsa ベース) は、特にソース コード変換の目的で使用することを目的とした C++ パーサー ツールキットで、Mozilla プロジェクトによって大規模な静的ソース コード分析と自動コード書き換えを行うために使用されています。最も興味深い部分は次のとおりです。 C++ のほとんどをサポートしているだけでなく、プリプロセッサ自体もサポートしているということです。
一方で、実際に利用できる独自のソリューションが 1 つだけあります。EDG フロントエンド。ほぼすべての C++ 関連の作業に使用できます。
個人的には、Mozilla で使用されている elsa ベースのpork/oink スイートをチェックしてみます。それとは別に、FSF は現在、その作業を承認しています。 gcc プラグイン ランタイム ライブラリ ライセンスを使用しているため、バイナリ プラグインを使用して gcc ベースの C++ パーサーをそのような目的に簡単に利用できるようになると、状況は急速に変わると思います。
つまり、一言で言えば次のようになります。あなたがお金持ちなら:EDG、無料/オープンソースが必要な場合 今:else/oink はかなり有望ですが、時間があれば、プロジェクトに gcc を使用するとよいでしょう。
C コード専用の別のオプションは次のとおりです。 スカウト.
C++ の文法は、ある種、複雑であることで有名です。あるよ これについては Lambda に良いスレッドがあり、 しかし、要点は、C++ 文法では任意に多くの先読みが必要になる可能性があるということです。
あなたがやろうとしていることと同じようなことを考えたら、Gnu CC か、または 添え木. 。特に Gnu CC は言語生成部分をかなり徹底的に分離しているため、新しい g++ バックエンドを構築するのが最善かもしれません。
実際、PUMA と AspectC++ はどちらも今でも積極的に保守および更新されています。私は AspectC++ の使用を検討していましたが、自分自身が更新されていないことに疑問を感じていました。著者に電子メールを送ったところ、AspectC++ と PUMA は両方ともまだ開発中であるとのことでした。SVN 経由でソースコードにアクセスできます https://svn.aspectc.org/repos/ または、通常のバイナリ ビルドを次の場所から入手できます。 http://akut.aspectc.org. 。最近の多くの優れた C++ プロジェクトと同様に、作成者には Web ページのメンテナンスを続ける時間がありません。フルタイムの仕事と生活があるのなら当然です。
エルサ C++ 解析に関しては、100% 準拠ではありませんが、私が知っている他のすべてのものより断然優れています。ファンです。C++ を出力するモジュールがあるので、おもちゃプロジェクトの良い出発点になるかもしれません。
私たちのを参照してください C++ フロントエンドフル機能の C++ パーサーの場合:AST、シンボルテーブル、名前とタイプの解像度を構築します。プリプロセッサを解析して保持することもできます ディレクティブ。C++ フロントエンドは、 DMSソフトウェアリエンジニアリングツールキット, これにより、その情報を使用して任意の ソースからソースへの変換を使用したソース コードの変更。
DMS は、このようなトランスレータを実装するための理想的なエンジンです。
そうは言っても、あなたの想像上のタスクにはあまり意味がありません。違います C++を置き換えることに多くの価値を見いだし、 完全な翻訳者は膨大な量の作業を行います。 ターゲットは「おもちゃ」の言語です。そして、おそらくほとんど意味がありません 堅牢なパーサーを使用して C++ を解析する (その唯一の目的が 解析が容易な C++ の同型バージョン (待ってください、私たちは すでに堅牢なC ++です!
2012 年 5 月編集:DMS の C++ フロント エンドは、GCC3/GCC4/C++11、Microsoft VisualC 2005/2010 を処理できるようになりました。頑丈に。
2015 年 2 月編集:GCC および MS 方言で C++14 を処理できるようになりました。
2015 年 8 月編集:コードとプリプロセッサ ディレクティブの両方を統合ツリーで解析してキャプチャできるようになりました。
少し前に、c ファイルの単体テストを自動的に生成するツールを作成しようとしました。
前処理のために、ファイルを GCC 経由に置きました。出力は醜いですが、前処理されたファイルから元のコードのどこにあるかを簡単に追跡できます。ただし、ニーズに応じて他のものが必要になる場合があります。
私が使用した メーター C パーサーのベースとして。これはオープンソースであり、lex と yacc を使用します。これにより、lex と yacc を完全に理解していなくても、短時間で簡単に立ち上げて実行できるようになりました。
また、lex と yacc のソリューションでは、関数全体の機能をトレースしたり、関数全体の構造を 1 回のパスで解析したりすることができなかったため、C アプリも作成しました。短期間で維持できなくなり、放棄されました。