7

一部のCソースコードが変数の命名規則に準拠していることを確認するプログラムを作成しようとしています。これを行うには、ソースコードを分析し、すべてのローカル変数とグローバル変数のタイプを特定する必要があります。

最終結果はほぼ確実にPythonプログラムになりますが、コードを分析するためのツールは、Pythonモジュールか、解析しやすいレポートを生成するアプリケーションのいずれかです。あるいは(これについては以下で詳しく説明します)、コンパイラーから情報を抽出する方法(レポートなど)である可能性があります。それが役立つ場合は、おそらく、KeilARMコンパイラになります。

私はctagsを試してきましたが、これはすべてのtypedefやマクロ定義などを見つけるのに非常に便利ですが、特に定義が複数の行にまたがっている場合は、変数のタイプを直接見つける方法はありません(そうならないことを願っています!)。

例としては、次のものがあります。

static volatile u8 var1; // should be flagged as static and volatile and a u8 (typedef of unsigned 8-bit integer)
volatile   /* comments */   
    static /* inserted just to make life */
        u8 /* difficult! */   var2 =
        (u8) 72
           ; // likewise (nasty syntax, but technically valid C)
const uint_16t *pointer1;  // flagged as a pointer to a constant uint_16t
int * const pointer2; // flagged as a constant pointer to an int
const char * const pointer3; // flagged as a constant pointer to a constant char
static MyTypedefTYPE var3; // flagged as a MyTypedefTYPE variable
u8 var4, var5, var6 = 72;
int *array1[SOME_LENGTH]; // flagged as an array of pointers to integers
char array2[FIRST_DIM][72]; // flagged as an array of arrays of type char

などなどなど

また、それらがローカル変数であるかグローバル/ファイルスコープ変数(ctagsで実行可能)であるかを識別する必要があります。ローカルである場合は、宣言されている関数の名前が理想的です。

また、関数でも同様のことを行いたいと思います。戻り型、静的かどうか、すべての引数の型と名前を識別します。

残念ながら、これはC構文ではかなり困難です。これは、パラメーターの順序にある​​程度の柔軟性があり、パラメーター間に許可される空白の量に多くの柔軟性があるためです。いくつかの凝った正規表現を使って作業をしましたが、適用できるさまざまな状況が非常に多く、正規表現がすぐに管理できなくなるため、理想からはほど遠いものです。コンパイラーが(動作するために!)これを実行できる必要があると思わずにはいられないので、この情報を抽出できるかどうか疑問に思いました。Keilコンパイラは、コンパイルされたソースファイルごとに「.crf」ファイルを生成するようで、これにはそのファイルで宣言されたすべての変数が含まれているように見えますが、これはバイナリ形式であり、私はできます。このファイルを解析する方法に関する情報を見つけてください。あるいは、ctagsから情報を取得する方法が最適です。

誰もがこれで提供できるどんな助けでもありがたいです。

ありがとう、

アル

4

5 に答える 5

5

構文を記述するために使用できる Python パーサー パッケージが多数あり、その構文を解析するための Python コードを生成します。

Ned Batchelder は非常に素晴らしい要約を書きました

そのうち、Ply はC ソース コードを解析するpycparserというプロジェクトで使用されました。これから始めることをお勧めします。

これらの他のパーサー プロジェクトの中には、サンプルの C パーサーもある場合があります。

編集: pycparser には、古い cdecl プログラムのようにC 型宣言を解析するためのサンプル Python スクリプトさえあることに気付きました。

于 2009-04-22T18:17:02.200 に答える
3

完全に反対側からアプローチしてはどうでしょうか。C 型システムのすべてのニュアンスを完全に理解するパーサー、つまりコンパイラー自体が既にあります。したがって、完全なデバッグ サポートを使用してプロジェクトをコンパイルし、デバッグ データを詳しく調べます。

binutilsでサポートされている形式に基づくシステムの場合、必要な詳細のほとんどはBFDライブラリで学習できます。

Microsoft のデバッグ形式は、MSDN のライブラリとドキュメントで (ある程度) サポートされていますが、現在、私の Google 機能は弱く、存在することを知っている記事をここにリンクするつもりはありません。

Keil 8051 コンパイラ (ここでは ARM コンパイラは使用していません) は Intel OMF または OMF2 形式を使用し、デバッグ シンボルがデバッガまたは「Intel 互換エミュレータ」用であることを文書化しています。Keil C51 で使用されているOMFの仕様はKeilから入手できるので、他のコンパイラでも同様の仕様が入手できると思います。

Keil の Web サイトをざっと見てみると、DWARF 形式のデバッグ情報を持つ ELF オブジェクトを使用しているように見える ARM の RealView Compiler のライセンスを優先して、彼らが独自の ARM コンパイラを放棄したことが示されているようです。Dwarf は BFD によってサポートされている必要があり、型と名前が一致することを確認するために知っておく必要があるすべてを提供する必要があります。

于 2009-04-22T22:20:22.380 に答える
2

ANTLRをチェックしてください。Python のバインディングを備えたパーサー ジェネレーターです。ANTLR サイトには、C を含む一般的な言語の文法が多数用意されています。C の文法をダウンロードし、適切な場所にアクションを追加して、関心のある情報を収集することができます。文法を作成およびデバッグするためのきちんとしたグラフィカル ツールもあります。(それはばかげているように思えますが、実際には非常に便利で不快ではありません)

シンボル情報を取得する以外は、似たようなことをしましたが、実際にはGDBから抽出しています。

于 2009-04-22T18:22:03.000 に答える
2

あなたがやろうとしているのは、静的分析の軽量形式です。ウィキペディアで指摘されているツールを見ると、運がいいかもしれません。

自分で C コードを解析するのは、私には間違った方向に思えます。そこには狂気が潜んでいます。あなたが主張するなら、[f]lex と yacc (bison) は、あなたのコンパイラー・ライターによって使用される可能性が高いツールです。

または、ctags または cscope の 80% を達成できれば、両方のソース コードが広く利用可能になります。最後の 20% はプログラミングの簡単な問題です。:)

于 2009-04-22T18:41:45.760 に答える
0

数年前に取り組んでいたプロジェクトで同様のことをしました。Cコンパイラの前半を書くことになりました。その見通しに驚かないでください。特に特定のトークン (この場合は変数定義) のみを探している場合は特に、思ったよりもはるかに簡単です。

C ソース コードをスキャンし、対象のトークンを検出し、結果を解析する方法については、オンラインでドキュメントを参照してください。出発点としては、ウィキペディアの字句解析に関する記事を参照してください

于 2009-04-22T18:21:51.003 に答える