類似のソースコードプログラム(C、C++、Go、または [〜#〜] gcc [〜#〜] でコンパイルされたもの)の抽象構文ツリーの形状を比較するはどうすればよいでしょうか。 ..)?
ソースコードの盗作検出はこのような手法を使用すると思いますが、どのように呼び出されるのかわかりません...
たとえば、ASTを比較するために統合を使用できますが、ブール値の回答しか得られません。数値の「距離」またはある種の数値ベクトル(たとえば、後で機械学習や分類アルゴリズム、またはその他のビッグデータのことを説明するため)を提供するいくつかの手法を探しています。
大量のソースコードセットでのビッグデータや機械学習アプローチへの言及も歓迎します。
(このように広範またはあいまいな質問で申し訳ありません。使用する用語がわかりません)
2つのASTまたはプログラムを単純に比較したくありません。大量のプログラムセット(Debianディストリビューションのソースコードの半分など)を処理し、その中に同様のルーチンを見つけたいと思っています。私はすでに [〜#〜] melt [〜#〜] を使用してGCCの内部表現(Gimple)で作業したいので、それを活用して、いくつかのメトリックを格納します(どのメトリックですか? 循環的複雑度) はおそらく十分ではありません)例えばいくつかのデータベースとそれらを比較して処理します...
補遺: [〜#〜] moss [〜#〜] システムと紙について発見されましたが、構文の形にはまったく関心がないようです。 ツリー編集距離 も調べます。
ほかにも見つかりました(JérémieSalvucciに感謝) Michel Chilowiczの博士論文(フランス語、2010年11月)がソースコードの類似点を探す に掲載されました
1つのアプローチは、ソースをXMLにコンパイルしてから、ソースの2つのビットがどれほど異なるかを調べることです。たとえば、Java=世界では、静的分析ツール pmd は、警告するものを探すためのアプローチとしてこれを行います。
_class Example {
void bar() {
while (baz)
buz.doSomething();
}
}
_
「コンパイル」されて:
_CompilationUnit
TypeDeclaration
ClassDeclaration:(package private)
UnmodifiedClassDeclaration(Example)
ClassBody
ClassBodyDeclaration
MethodDeclaration:(package private)
ResultType
MethodDeclarator(bar)
FormalParameters
Block
BlockStatement
Statement
WhileStatement
Expression
PrimaryExpression
PrimaryPrefix
Name:baz
Statement
StatementExpression:null
PrimaryExpression
PrimaryPrefix
Name:buz.doSomething
PrimarySuffix
Arguments
_
その点は、「このコードとそのコードの違いは、この名前が異なることです」と言ってコードを比較することになります。上記は実際にはxmlであるため、これは、存在する任意の数のxml比較ツールで実行できます。または、数値を求めていた場合、 ツリー編集距離 アルゴリズムを適用できます(関連 SO質問 )。
別のアプローチは、コード形状の「署名」を調べることです。 署名調査 はワードカニンガムによって行われました
その伝説は少し読みにくいです:
14m
_は14のメソッドを意味します294L
_は294行です。.
_は空白行ではありません'
_はコメントです|
_(緑)は、1行のif
ステートメントです。(.)
_(緑)はif
ブロック内の単一のステートメントです[(.)]
(茶色)は、ループ内のif
内の単一ステートメントです。{.}
_は、単一のステートメントを持つメソッドです。[.]
_(赤)はループ内の単一ステートメントです([.])
_(濃い赤)は、ifブロック内のループ内の単一ステートメントです。2つのコードセットを比較すると、非常に限られた言語で2つの文字列間の編集距離が調べられます。