2

私は現在、2 つのファイルを比較し、その違いを報告するツールに取り組んでいます。2 つのメソッドを比較し、同一かどうかを報告する機能を実装したいと考えています (変数名の変更は無視します)。私が考えたことは、すべての変数名を (x0,x1 ..) または類似のものに正規化することです。次に、順序が同じになるようにメソッドを並べ替えます (アルファベット順?)。それらのチェックサムを取得し、2 つを比較します。

私の質問:

C / C++ ファイルの変数名を正規化するにはどうすればよいですか? または、機能を実装する方法について他にアイデアはありますか?

よろしく

4

3 に答える 3

1

反復可能で安定した順序付けを考え出すことができれば、上記のように「トークン」(変数名) を「interned フォーム」にマップできます。

これは、トークンがどのように解決されるかを理解しようとするものではなく、2 つのソース ファイルに同じパターンで存在するだけです。「トークン」は、C/C++ 予約語以外のすべてであり、深刻な解析/字句解析は必要ありません。

これが完了したら、コメントと空白を正規の形式に変換できます。

これは私にとってほとんど役に立ちませんが、問題を 99.9% 以上解決できると信じています。

もちろん、それらも処理する必要があるマクロがある場合は..必要に応じて、C プリプロセッサを実行してそれを満たすことができますか?

お役に立てれば。

于 2013-05-07T10:26:39.493 に答える
0

確かに、これは名前を正規化することではなく、2 つのメソッドがクラス内の同じものに対して同じことを行うかどうかを判断することです。これは、ソース コードを解析し、そこからある種のデータ構造 [おそらく「ツリー」] を構築することを意味します。ツリーを取得すると、そのような名前は無意味になります。たとえば、クラス メンバー変数への OFFSET が参照しているものや、クラス内のどの仮想関数を追跡する必要がある場合があります。

これはまったく些細なことだとは思いません (コードを C++ コードの小さなサブセットに制限しない限り)。何かを同じことをさせるには非常に多くの異なる方法があり、ほんのわずかな違いがすべてを台無しにしてしまうからです。最も洗練されたツール。例えば

class A
{
   private:
     int arr[10];
     ...
   public:
     int sum()
     {
        int r = 0;
        for(i = 0; i < 10; i++)
            r += arr[i];
        return r;
     }
}


class B
{
   private:
     int arr[10];
     ...
   public:
     int sum()
     {
        int r = 0;
        int *p = arr;
        for(i = 0; i < 10; i++)
            r += *p++;
        return r;
     }
     .... 
}

これら 2 つの関数は同じことを行います。

于 2013-05-07T10:13:12.023 に答える
0

コンパイル中にgccが生成する一時ツリー表現の使用についてはどうですか.gccには一時ファイルを保持するためのコマンドラインスイッチがあります:

gcc -save-temps <file>

このコードはやや簡略化され、名前は統一されています。問題は、元のファイルの違いを特定することです。最適化を使用しないでください。

于 2013-05-16T17:21:47.153 に答える