2012-02-02 5 views
0

現在、私はソースコード剽窃検出プロジェクトを行っています。実際に入力ファイル(souceコードファイル)の属性のさまざまな側面を使用して、学生割り当ての間違いを検出しています。例えば、私は今、各ソースコードファイルを表すために(識別子/変数の数、使用されたメソッドの数、コードの行数)とその他の属性を使用します。検出のためのJavaソースコードの属性

しかし、使用する変数の数を数えようとすると、変数が使用されているかどうかを調べる方法があります。学生は意図的に盗作をカバーするためにいくつかの識別子を入れることができるからです。しかし、これを解決しようとすると、私はこれを本当に厳しいものにしました。これを行うための1つのアプローチは、識別子の検索を処理するためにJavaの正規表現を使用することですが、それらを見つけた後、使用方法をチェックする方法に固執します。 (さらに、その後、Javaメソッドが呼び出されるかどうかを調べる必要があります)。したがって、独自のバージョンの正規表現を書くことは非常に複雑になる可能性があります。

私はいくつかのIDEでnetbeansのように知っていますが、エディタは変数が使用されているかどうかを即座に知り、それに下線を付けることができます。ですから、変数の使用状況をチェックする良い方法があるのだろうかと思います。

変数のチェック方法については、どのような提案も良いでしょう。これがそうのような変数の作成と一致する必要があります

(\w+)\s+<?varname>(\w+)\s*(=[\w\s\(\,)]+)?;

:頭に浮かぶ

+0

私の教授は私自身の正規表現やコンパイラを書くのはあまりにも素朴で、いくつかの "コンパイラコンパイラ"を見るように言ったが、私はグーグルで、lexとyaccを見つけた。コンパイラの設計について多くの知識がなければ、読んだ後に失われました。 – Alex

答えて

1

この種のコード解析を行うためには、パーサー/コンパイラツールを調べる必要があります。変数が単なる名前を検索して使用されているかどうかは判断できません。正しい文脈も検索しなければなりません。

私は、Javaベースの言語解析ツールであるANTLRを調べることをお勧めします。それは利用可能なJava構文を解析するための定義を持っていますhere。数時間で実装できる問題の簡単な解決策を見つけることは期待しないでください。

もう1つのJavaベースのツールはJavaCCです。これらのツールの使い方を示すサンプルコードをお探しの場合は、PMDをご覧ください。JavaCCで構築されたパーサーを使用してJavaコードを分析します。

もう1つの可能性は、コード解析をサポートするIDE用のプラグインを書くことです - コード構造にアクセスするためのインターフェイスがもっと簡単になるでしょう。すでに述べたように、あなたのプラグインによって呼び出されます。

はい、おそらく、いくつかの正規表現であなたのやり方をハックすることもできます。あなたがこれをしたいのかどうかは、あなたのツールがどれほど正確であるかによって決まります。ソースコードを解析せずに、変数名の出現が実際にその変数の使用法であるかどうかを判断することは、ヒューリスティックな推測にすぎません。

1

まず最初はそうのような何かを行うことです物事はそれほど複雑にするために

int x = 1; 
double y; 
Foo foo = new Foo(); 
Foo foo = new Foo(a,b,c); 

、それはあるかもしれません引用符で囲まれていない;をすべて;\nに置き換えることをお勧めします。これにより、1行に1つのステートメントがあることを確認する必要があります。

変数の作成にマッチさせる以外に、正規表現では変数の名前をvarnameというグループに入れます。この名前はmatcherというオブジェクト(String varName = matcher.group("varname");)からアクセスできます。

[^=]+\s*=\s*.*?x.*;

これは、このようなint y = x;Foo foo = x + y;

のように文字列に一致する必要があります:変数が使用されている場合は、その変数が、等号の右側にあるので、同じようかどうかを確認することができます表示するには

しかし、変数は、メソッドのパラメータとして使用することができますので、あなたはそのような何かを行うことができます。

.*?\(.*?x.*?\).*?;

これはMATCますそのような時間文字列: foo(x);foo(a,b,c,x);Foo foo = new Foo(a,v,x,y).createNewFoo();Foo foo = new Foo(a,v,x,y).SOMECONSTANT;

これは、与えられた正規表現で、xはあなたを介して抽出することができるようになります実際の変数名に置き換える必要がありますだけでサンプル変数名であることに留意すべきです最初の正規表現の使用。

this正規表現のチュートリアルをOracleから参照してください。

0

IDEは、変数の発生を2つのカテゴリに分類します。特定の変数への代入とそれを簡単に使用します。代入は、正規表現を使用して簡単に認識する必要があります。他のすべての発生は、その変数を使用するだけでコード内になければなりません。

関連する問題