2009-04-22 9 views
7

私は、いくつかのCソースコードが変数命名規則に準拠していることを確認するプログラムを作成しようとしています。これを行うには、ソースコードを分析し、すべてのローカル変数とグローバル変数の型を特定する必要があります。Cプロジェクトのすべての変数の型式を確認

最終結果はほとんどの場合、Pythonプログラムになりますが、コードを解析するツールは、Pythonモジュールまたは解析が容易なレポートを生成するアプリケーションのいずれかになります。代わりに(これについては以下を参照)、コンパイラからの情報の抽出方法(レポートなどを使用して)ができます。これが役に立つ場合は、恐らくKeil ARMコンパイラになります。

私は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から情報を取得する方法は完璧です。

誰もがこれで提供できる助けに感謝します。

おかげで、

アル

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

答えて

5

ネッドBatchelderは、これらのうちvery nice summary

を書いて、プライは、Cのソースコードを解析しpycparserと呼ばれるプロジェクトで使用されました。私はこれで始めることをお勧めします。

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

編集は:ちょうどpycparserだけでもparse C type declarations古いCDECLプログラムのようにサンプルのPythonスクリプトを持っていることに気づきました。

+0

+1:これは既に完了しています - 数回以上。 –

0

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

Cのソースコードをスキャンし、対象のトークンを検出し、結果を解析する方法についてオンラインでドキュメントを探します。始めるのに適した場所はWikipedia's artricle on lexical analysisです。

2

ANTLRをチェックしてください。これはパーサージェネレータで、Pythonのバインディングを持っています。 ANTLRサイトでは、共通言語用の文法を多数提供しています。 Cの文法をダウンロードし、適切な場所にアクションを追加して、興味のある情報を収集することができます。文法の作成とデバッグのためのきれいなグラフィカルツールもあります。 (私はそれが陳腐ようだ知っているが、それは実際には非常に便利で、不快ではありません)

私はちょうど私が実際にGDBからそれを私のシンボル情報を抽出しています取得することを除いて、ソートの似た何かをしました。

2

あなたがしようとしているのは、軽量な静的解析のフォームです。 Wikipediaで指し示されているツールを見て、運が良ければよいかもしれません。

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

または、ctagsのかにcscopeは、あなたの道の80%を取得する場合、両方のソースコードが広く利用可能です。最後の20%はプログラミングの単純な問題です。 :)

3

反対側から完全に近づくのはいかがですか。あなたはすでに、C型システムのすべてのニュアンス、すなわちコンパイラ自体を完全に理解しているパーサを持っています。だから、完全なデバッグサポートでプロジェクトをコンパイルして、デバッグデータにspelunkingしてください。

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

Microsoftのデバッグフォーマットは(多少)MSDNで図書館や文書によってサポートされていますが、私のGoogleの-FUは、今日弱く、私はここにリンクするために存在を知っている記事に手を入れていませんよ。

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

KeilのWebサイトを簡単にスキャンすると、独占的なARMコンパイラを放棄し、DWARF形式のデバッグ情報を持つELFオブジェクトを使用しているARMのRealView Compilerのライセンスが得られたことがわかります。ドワーフはBFDによってサポートされるべきであり、あなたがタイプと名前が一致することを確認するために知る必要があるすべてを与えるべきです。

+0

+1 完全に同意します。私は同じアプローチをとっていましたが、ELFをDWARF形式でサポートするlibdwarfライブラリを使用しました。これは魅力的です。 – qrdl

関連する問題