On Detection of Gapped Code Clones using Gap Locations

Download Report

Transcript On Detection of Gapped Code Clones using Gap Locations

開発保守支援を目指した
コードクローンの抽出手法
- 支援環境Geminiへの実装 -
植田 泰士
井上研究室
背景 (1/2)

2
ソースコード中に類似したコード片があ
るとき、それらをコードクローンという
背景 (2/2)

コードクローンはソフトウェア保守を困難にする



コードクローンにバグが存在する場合,すべてのコードクローンに
ついて修正を行わなければならない
機能追加も同様
コードクローン検出ツールCCFinder[1]と,そのコードク
ローン分析支援環境Gemini[2]を開発

CCFinder
• トークン単位でのコードクローンを検出
• 入力はソースファイル,
出力(テキストベース)はクローンペアの位置情報
• 最小一致トークン数

Gemini
• GUIベースの分析環境
• コードクローン検出ツールとしてCCFinderを使用
[1] T. Kamiya, S. Kusumoto, and K. Inoue, “CCFinder: A multi-linguistic token-based code clone detection system for large scale source code”,
IEEE Transactions on Software Engineering, 28(7):654-670, 2002.
[2] Y. Ueda, T. Kamiya, S. Kusumoto and K. Inoue, “Gemini: Maintenance Support Environment Based on Code Clone Analysis”,
Proc. Of the 8th IEEE International Symposium on Software Metrics, 67-76, 2002.
If (a > b)
{
b++;
a=1;
}
CCFinder/Gemini (1/5)

CCFinderが検出するコードクローン


‘コピーとペースト’による再利用
Exact クローン
Parameterized クローン
識別子名の変更
If (a > b)
{
b++;
a=1;
}
4
Exactクローン
If (i > j)
{
j++;
i=0;
}
Parameterized
クローン
CCFinder/Gemini (2/5)

最小一致トークン数


CCFinderは最小一致トークン数より
短いコードクローンは検出しない
短いコードクローンは,非常に多く存在する
(例)14万行: 30トークン以上 約20,000クローンペア
10トークン以上 約4,000,000 クローンペア
1. static void foo() throws RESyntaxException
1. static void goo(String [] a) throws RESyntaxException
2. {
2. {
14 トークン
3. String a[] = new String [] {"123,400", "abc"};
3. RE exp = new RE(“[0-9,]+”);
4. org.apache.regexp.RE pat =
4. int sum =最小一致トークン数を
0;
5.
new org.apache.regexp.RE("[0-9,]+");
5. int i = 0; 20トークンに定める
10トークンに定める
6. int sum = 0;
6.
while
(i
<
a.length)
27 トークン
と...
7. for (int i = 0; i < a.length; ++i)
7. {
8. {
8.
if (exp.match(a[i]))
9.
if (pat.match(a[i])){
9.
sum += parseNumber(exp.getParen(0));
13
トークン
10.
sum += Sample.parseNumber(pat.getParen(0));}
10.
i++;
11. }
11. }
12. System.out.println("sum = " + sum);
12. System.out.println("sum = " + sum);
13. }
13. }
CCFinder/Gemini (3/5)

Gemini概要
a b c a b c a d e c

a b c a b c a d e c


GUIベースの分析環境
コードクローン検出ツールとして
CCFinderを使用
インタラクティブな分析環境を提供
• クローン散布図ビュー
• マウス操作によるクローン選択
• メトリクスグラフビュー
• メトリクス値によるクローン選択
• ソースコードビュー
a, b, c, ... : トークン
6
: 一致箇所
CCFinder/Gemini (4/5)

これまでの適用

フリーソフトウェア
•
•
•
•

JDK libraries (Java, 570 KLOC)
Linux, FreeBSD (C, 1.6 + 1.3 MLOC)
FreeBSD, OpenBSD,NetBSD (C)
Qt (C++,240KLOC)
商用ソフトウェア
• NTTデータ, 日立, 日立GP, NASDA, NECソフト,
ASTEC, SRA, 大和コンピュータ, …



7
学生演習プログラム
ソフトウェア著作権訴訟
21世紀COEプロジェクト ソフトウェア工学工房
If (a > b)
{
b++;
a=1;
}

CCFinder/Gemini (5/5)
実際のコピーとペーストによる再利用が行われ
If (a > b)
If (a > b)
If (a > b)
{
{
{
る場合,部分的な変更が加えられることが多い
b++;
b++;
b++;
‘コピーとペースト’による再利用
識別子名の変更a=1;
}
挿入
If (a > b)
{
b++;
a=1;
}
If (i > j)
{
j++;
i=0;
}
Ngクローン (Non-gapped clone)
Parameterized
8
Exactクローン
クローン
If (i > j)
{
i = i / 2;
j++;
i=0;
}
a=1;
a=1;
}
}
削除
If (i > j)
{
i=0;
}
ギャップ
Gappedクローン
修正
If (i > j)
{
j = j + 1;
i=0;
}
研究の目的

Gappedクローン検出手法を提案する

適用実験を行い本手法の有効性を確認する
9
Gappedクローン検出
- 概要 (1/2)

前提


個々のGappedクローン発見問題をNgクローン(Exactクローン,
Parameterizedクローン)の組合せ決定問題としてとらえる
Ngクローンの組合せ爆発


複数のNgクローンが互いに重なり合い密集していた場合, ある
ひとつのNgクローンから次のNgクローンへの連結先が多数存
在するため,組合せ爆発が起こる
Ngクローンの組合せ数
15
3
高い計算コスト 105
10
Gappedクローン検出
- 概要 (2/2)

アプローチ

マン・マシン共同作業
• 全NgクローンをNgクローン連結集合に分割
• クローン散布図を用いて連結集合を視覚化
→ ユーザはどのあたりにGappedクローンが
存在するのか識別できる
• 連結集合内に含まれるGappedクローンをインタラク
ティブに参照
11
Gappedクローン検出
ファイル Y
- 検出手順
ファイル X

入力例
A B C E F B C D E B C D
 ファイルXのコード列:
A
“ABCDCDEFBCDG”
B
 ファイルYのコード列:
C
“ABCEFBCDEBCD”
D
• “A”, “B”, “C” … はソースコード中
C
の任意粒度の要素
D
ソースファイル
Ngクローン位置検出
Ngクローン
ギャップ位置検出
ギャップ
E
Ngクローンと
ギャップの結合情報
視覚化
F
B
Gap-and-clone 散布図
C
D
G
ソースコード分析
12
Gappedクローン検出
- 検出手順
ソースファイル
Ngクローン位置検出
Ngクローン
上限ギャップ長
ギャップ
ギャップ位置検出
Source files
ギャップ
Ngクローンと
ギャップの結合情報
視覚化
Gap-and-clone 散布図
ソースコード分析
13
Gappedクローン検出
ファイル Y
- 検出手順
A B C E F B C D E B C D
A
ソースファイル
Ngクローン位置検出
B
ファイル X
C
Ngクローン
D
ギャップ位置検出
C
D
ギャップ
E
Ngクローンと
ギャップの結合情報
視覚化
F
B
Gap-and-clone 散布図
C
D
G
ソースコード分析
14
Gappedクローン検出
ファイル Y
- 検出手順
A B C
A
E
F B C
D
E
B
C D
ソースファイル
Ngクローン位置検出
B
ファイル X
C
Ngクローン
D
ギャップ位置検出
C
D
ギャップ
Ngクローンと
ギャップの結合情報
E
視覚化
F
B
Gap-and-clone 散布図
C
D
G
ソースコード分析
15
Gappedクローン検出
- 実装

支援環境Geminiへ実装
 Geminiにおけるクローン散布図上で,ユーザはマ
ウス操作によりクローンを選択し,実際のソース
コードを参照することができる
Ngクローン
連結集合
16
適用実験概要
 適用対象

大阪大学のプログラミング演習で作成されたプロ
グラム
• C言語で記述されたコンパイラ
• 3つの課題で構成されている
課題1: 構文解析器の作成,
課題2: 意味解析器の作成,
課題3: コンパイラの作成
 分析内容

17
どのようなGappedクローンがみつかるのか
課題2内
課題3内
void sentence()
void sentence()
{
{
A
if ((tok_name == SIDENTIFIER)||
||
(tok_name == SWRITELN) ||
(tok_name == SBEGIN))
basic_sen();
分析
if ((tok_name == SIDENTIFIER) ||
(tok_name == SREADLN)
||
(tok_name == SWRITELN)
||
Ngクローン最小一致トークン数:20 トークン
(tok_name == SBEGIN))
basic_sen();
{
B1
scan();
if (expression() != TBOOLEAN) error(4);
else if (tok_name == SIF)
 Ngクローン最小一致トークン数:10 トークン
ギャップ上限長: 10 トークン
B2
 ある学生の3課題に
おける関数
“sentence()”の間で比較
40 トークン
連結集合最小長: 20 トークン
{
if (tok_name != STHEN) syntax_error();
scan();
if (expression() != TBOOLEAN) error(4);
multi_sentence();
if (tok_name == SELSE)
{
課題3内
llt=lt; llf=lf; lp=p; lpf=pf;
else if (tok_name == SIF)
scan();
課題2内
int llt,llf,lp,lpf;
課題1内
(tok_name == SREADLN)
in Ex.3
課題1内
fprintf(outfile,"\tPOP\tGR2\t;%d\n",tok_line);
fprintf(outfile,"\tCPA\tGR2,TRUE\n",sub);
scan();
fprintf(outfile,"\tJNZ\tLF%d\n\n",llf);
multi_sentence();
課題2内
lf++;lt++;
}
B3
}
if (tok_name != STHEN) syntax_error();
else if (tok_name == SWHILE)
scan();
B4
{
scan();
45 トークン
multi_sentence();
fprintf(outfile,"\tJMP\tLT%d\n",llt);
if (expression() != TBOOLEAN) error(4);
fprintf(outfile,"LF%d\n\n",llf);
if (tok_name != SDO) syntax_error();
scan();
if (tok_name == SELSE)
sentence();
27 トークン
{
}
scan();
else syntax_error();
multi_sentence();
}
50 トークン
}
fprintf(outfile,"LT%d\n",llt);
}
{
課題3内
else if (tok_name == SWHILE)
scan();
fprintf(outfile,"LOOP%d\n",lp);
p++;
if (expression() != TBOOLEAN) error(4);
fprintf(outfile,"\tPOP\tGR2\t;%d\n",tok_line);
fprintf(outfile,"\tCPA\tGR2,TRUE\n",sub);
fprintf(outfile,"\tJNZ\tLOOF%d\n\n",lpf);
pf++;
if (tok_name != SDO) syntax_error();
scan();
sentence();
18
fprintf(outfile,"\tJMP\tLOOP%d\n",lp);
fprintf(outfile,"LOOF%d\n\n",lpf);
}
else syntax_error();
A
18 トークン
14 トークン
B
12 トークン
14 トークン
まとめと今後の課題

開発保守支援を目指したコードクローンの抽出手
法の提案と実装を行った


適用実験により本手法の有効性を確認した


不一致部分を含んだコードクローンの検出
個々では短くて検出されないような短い
いくつかのNgクローンで構成された
Gappedクローンを見つけることができた
今後の課題として,実際のソフトウェア開発保守作
業への適用,大規模なソフトウェアへの適用が考
えられる
19
20
Web page of CCFinder/Gemini is available at
http://sel.ist.osaka-u.ac.jp/cdtools/index.html.en
21
既存のコードクローン検出手法
(1/2)
Bakerの手法

行単位でソースコードを比較してコードク
ローンを検出する
Baxterらの手法

C言語のソースファイルを入力,構文解
析して,解析木(の部分木)を比較する
[Baker1995] B. S. Baker: “On finding Duplication and Near-Duplication in Large Software System,” Proc. Second IEEE
Working Conf. Reverse Eng., pp. 86-95, Tronto, Canada (Jul., 1995).
[Baxter1998] I. D. Baxter, A. Yahin, L. Moura, M. Sant’Anna, and L. Bier: “Clone Detection Using Abstract Syntax Trees,”
Proc. of ICSM ’98, pp. 368-377, Bethesda, Maryland (Nov., 1998).
22
既存のコードクローン検出手法
(2/2)

Merloらの手法

手続き(メソッドや関数)の特徴メトリクス
を比較して,計測値が似ていればコード
クローンであると判定する
[Balazinska1999] M. Balazinska, E. Merlo, M. Dagenais, B. Lague, and K.A. Kontogiannis, "Measuring Clone Based
Reengineering Opportunities", Proc. 6th IEEE Int'l Symposium on Software Metrics (METRICS '99), pp. 292-303, Boca
Raton, Florida, Nov. 1999.
23
Differences between our
method and homology analysis
in genome informatics
G
G

Alignment analysis



Dynamic programming
• O(mn) (m, n : length of
sequences)
The optimal alignment is not our
interest.
Homology search


BLAST, FASTA
We have no query sequence for
search and want to detect all
gapped clones.
24
F
V
D
K
Y
D
5
-2
-5
1
-7
-5
-5
7
-6
-7
GK Y
-1
-2
-2
-2
-7
G
1
0
-4
4
-7
-7
-7
-7
-7
A L
G F G S L
A L
G G V S V G
A L
G F G
A L
G
D
F V D
Y G
S L
Y G
G V S V
G
The difference between ‘diff’
and clone detection tools

Diff finds the longest common sub-string.


Given a code portion, diff does not report
two or more same code portions (clones).
Clone detection tool finds all the same or
similar code portions.
25
Computation cost of
our method

Non-gapped clone detection (in CCFinder):
O(n + m)
n: length of source code
 m: number of non-gapped clones


Gap identification: O(m)


Identification of gaps combined with each
non-gapped clones : O(1)
Total: O(n+m)
26
クローンが生じる理由







27
コピーとペースト
定型処理
コーディングスタイル
意図的な繰り返し
プログラミング言語に適切な機能がない
ため
コード生成ツール
偶然
Related work

Baxter et al.[3]




Extract clone pairs of statements, declarations, or sequences
of them from C source files.
Parse source code to build an abstract syntax tree (AST) and
compare its sub-trees by characterization metrics (hash
functions).
Its computation complexity is O(n), where n is the number of
the sub-tree of the source files.
The hash function enables one to do parameterized matching,
to detect gapped clones, and to identify clones of code portions
in which some statements are reordered.
[3] I. D. Baxter, A. Yahin, L. Moura, M. Sant’Anna, and L. Bier,
“Clone Detection Using Abstract Syntax Trees,”
Proc. of ICSM ’98, pp. 368-377, Bethesda, Maryland, 1998.
28
Snapshots of
clone class metric graph
RAD
Filtering mode : ON
29
LEN
POP
DFL
Clone class metrics



LEN (C ): Length of token sequence of each element in clone class C
POP (C ): Number of elements in clone class C
DFL (C ): Estimation of how many tokens would be removed
from source files when all code fragments of clone
class C are replaced with caller statements of a new
identical routine
new sub routine
caller statements

RAD (C ): Distribution in the file system of elements in clone class C
30
Definitions of DFL and RAD

DFL(C )

DFL(C) = LEN(C) ×POP(C) - 5×POP(C) + LEN(C)
• LEN(C) ×POP(C) : the target code size for restructuring
• 5×POP(C) : the code size of new caller statements
• LEN(C) : the code size of new identical routine

RAD (C )

Distribution in the file system of elements in clone class C
• RAD(C) = 0 : C is enclosed within a single file.
• RAD(C) = 1 : C is enclosed within a single directory.
• RAD(C) = n : C is enclosed within a directory tree of n layers.
31
Analysis using clone class metrics

Example of analysis issue

Finding clones that are appropriate for refactoring.
• Clones having high DFL
• Clones having high POP and low RAD
• It may be easy and meaningful to merge clones into one
routine because of their density.

Finding portions that are not reliable.
• Clones having high LEN
• Modules having larger code clones are less maintainable
than modules having smaller code clones [4].
[4] Akito Monden, Daikai Nakae, Toshihiro Kamiya, Shin-ichi Sato, Ken-ichi Matsumoto,
“Software Quality Analysis by Code Clones in Industrial Legacy Software”,
Proc. Of the 8th IEEE International Symposium on Software Metrics, 87-96, 2002.
32
Suffix-tree

1.
2.
3.
Suffix tree is a tree that satisfies the following
xyxyz% 1
conditions.
A leaf node represents the starting
position of sub-string.
A path from root node to a leaf node
represents a sub-string.
First characters of labels
of all the edges from one node
are different from each other.
xyz% 2
y
x
xyz%
→ A common path means
a clone
1 2 3 4 5 6 7
x x y x y z %
1 x *
2 x * *
3 y
*
4 x * *
*
5 y
*
*
633 z
*
7 %
*
y
z%
3
4
z%
5
z%
6
%
7
1 2 3 4 5 6 7
x x y x y z%
Example of
transformation rules in Java




All identifiers defined by user are transformed to same tokens.
Unique identifier is inserted at each end of the top-level definitions
and declarations.
 Prevents detecting clones that begin at the middle of class
definition and end at the middle of another one.
”java. lang. Math. PI” is transformed to ”Math. PI”.
 By using import sentence, a class is referred to with either full
package name or a shorter name
” new int[] {1, 2, 3} ” is transformed to ” new int[] {$} ”
 Eliminates table initialization code.
34
The output of
CCFinder

Output of CCFinder
Object file ID
( file 0 in Group 0 )
#version: ccfinder 3.1
#langspec: JAVA
#option: -b 30,1
#option: -k +
#option: -r abcdfikmnprsv
#option: -c wfg
#begin{file description}
0.0 52 C:\Gemini.java
0.1 94 C:\GeneralManager.java
:
:
#end{file description}
Location of a clone pair
( Lines 53 - 63
in file 0.1 and
Lines 542 - 553 in file 1.10
are identical or similar to each other)
 It is difficult to analyze
source code by only this
text-based information of
the location of clone pairs.
35
#begin{clone}
0.1 53,9 63,13 1.10 542,9 553,13 35
0.1 53,9 63,13 1.10 624,9 633,13 35
0.2 124,9 152,31 0.2 154,9 216,51 42
:
:
#end{clone}
Gapped code clone detection
- Algorithm (1/5)
Source files

Step1: Non-gapped clone detection

Detect non-gapped clones from input source files.
Non-gapped clone detection
• Set the minimum length of clone (threshold1).

Sort the list of the detected non-gapped clones for
effective identification of gap locations in Step2.
• Make a clone pair which
appears previously in the file
appear previously also in the
sorted list.
• When the detected result is
one of comparison among three
or more files, a set of non-gapped
clones can be divided into
subsets defined by the
combination
of two files.
36
Non-gapped clones
Gap identification
Non-gapped
clone ID
Pos. in file X
in file Y
Matched
Gaps Pos.Correspondences
(ABCDCDEFBCDG)
subsequence
(ABCEFBCDEBCD)
c1
1–3
1–3
“ABC”
c2
2–4
Visualization
6–8
“BCD”
c3
2–4
10 – 12
“BCD”
c4
5–5
3–3
“C”
c5
5–6
11 – 12
“CD”
c6
5–6
7–9
“CDE”
c7
7 – 11
c8
9 – 10
2-3
“BC”
c9
9 – 11
10 - 12
“BCD”
Gap-and-clone scatter plot
–8
“EFBCD”
Source 4code
investigation
Gapped code clone detection
- Algorithm (2/5)

Step2: Gap identification

Source files
Generate gap locations from sorted list of non-gapped
clones.
Non-gapped clone detection
• Gap location is a kind of the combination of the two nongapped clones.
• (c1, c6) = ((1-3, 1-3), (5-6, 7-9))  g1= (4-4, 4-6)
• The length of each gap is the length of longer unmatched
subsequence.
• Set the upper limit of the length of each gap (threshold2).
 The overall time complexity of
Step237is O(n) (n:number of nongapped clones)
Gap identification
Gaps
• Use the facts for optimizations
• non-gapped clones are stored as
the sorted result.
• The number of gaps connected
from each non-gapped clone can
be considered up to a certain
constant.
Non-gapped clones
Gap ID
Correspondences
Pos. in file X
(ABCDCDEFBCDG)
Pos. in file Y
(ABCEFBCDEBCD)
Length
in longer
g1
4–4
4–6
3
g2
4–4
4 – 10
7
Visualization
Gap-and-clone
scatter 3plot
–
g3
4–6
g4
4–8
g5
–
g6
5–8
9
4
g7
8–8
–
1
4–9
6
– 10 investigation
2
Source9code
Gapped code clone detection
- Algorithm (3/5)
Source files

Step3-1: Visualization – gap-and-clone scatter plot

Draw gaps on the scatter plot of non-gapped clone to
visualize gapped clones in a pseudo way.
Non-gapped clone detection
File Y
1
1
A
2
B
3
C
4
D
5
C
File X
6
D
7
E
8
F
9
B
2
3
4
5
6
7
8
A B
C
E
F B
C
D E B
12 G
10 11 12
Non-gapped clones
C D
Gap identification
c1
c2
c3
Gaps
Correspondences
g1
g5
g3
c5
Visualization
c6
Gap-and-clone scatter plot
g7
c8
c7
c9
10 C
11 D
9
38
Gapped
clone ID
Path
Subsequence in file X
(ABCDCDEFBCDG)
Subsequence in file Y
(ABCEFBCDEBCD)
gc1
c1 g1 c5 g7 c7
“ABC-CDE--CD”
Source
code“ABC---CDEBCD”
investigation
gc2
c1 g3 c6
“ABC---EFBCD”
“ABCEFBCD”
gc3
c2 g5 c4
“BCDCD”
“BCDCD”
File Y
Gapped code clone detection
- Algorithm (4/5)
1

Step3-2: Visualization – filtering
Remove non-gapped clones and
gaps that do not contribute to
make a long gapped clone.
• Introduce the length of each
entanglement (“eSize”) of nongapped clones and gaps.
• eSize = max (eSizeX,
eSizeY)
eSizeX = eEndX – eStartX
eSizeY = eEndY – eStartY
• “eSize” means the maximum
length of gapped clone
included in the entanglement.
• Set the minimum “eSize” for
display
(threshold3).
39
File X

1
A
2
B
3
C
4
D
5
C
6
D
7
E
8
F
9
B
10 C
11 D
2
3
4
5
6
7
8
9
10 11 12
A B
C
E
F B
C
D E B
C D
c1
c2
Source files
c3
g1
g5
g3
c5
Non-gapped
c6 clone detection
g7
Non-gapped clones
c8
c7
c9
Gap identification
12 G
Gaps
Correspondences
Visualization
Gap-and-clone scatter plot
Source code investigation
Gapped code clone detection
- Algorithm (5/5)
Source files

Step4: Source code investigation


Investigate source files with gap-and-clone
scatter plot.
Change parameters.
• Threshold1: Minimum size of non-gapped clones
in non-gapped clone detection
• Threshold2: Maximum size of gaps in
identification of gap locations.
• Threshold3: Minimum size of entanglement of
non-gapped clones and gaps in gap-and-clone
scatter plot.
• Theshold1 and threshold2 greatly affect
computation time.
• Small threshold1 makes O(m2) non-gapped clone
pairs detected from size-m source code.
40
• Large threshold2 makes O(n2) gaps detected from n
clone pairs.
Non-gapped clone detection
Non-gapped clones
Gap identification
Gaps
Correspondences
Visualization
Gap-and-clone scatter plot
Source code investigation
(Frequency of non-gapped clones)
(Frequency of non-gapped clones)
Analysis - Usefulness of gap-
1500
and-clone scatter plot
1000

1500
1000
Compared the scatter plots of non-gapped clones to the gap-and-clone
500
scatter plot
500
Shown up as long
Three programs (Ex.1: 2267 tokens, Ex.2: 4394 tokens and Ex.3:
gapped5738
clones
tokens) of a student S are arranged on both of the vertical and horizontal
0
axes.
0 10
20
30
40
0
(Tokens)
10
30 boundary
40
 0 The
grid 20represents
lines 50
between sub-exercises.

(Tokens)
Ex.1
Ex.2
Ex.3
Ex.1
Ex.2
Ex.1
Ex.3
Ex.1
Ex.1
Ex.1
Ex.2
Ex.2
Ex.2
Ex.3
Ex.3
Ex.3
41
Threshold1 = 10
Threshold1 = 30
Ex.2
Threshold1 = 10
Threshold2 = 10
Threshold3 = 30
Ex.3
50
The analysis of comparison among
students (non-gapped clones only)

The corresponding code

A (2 students)
• Similar code fragments
were from source code of
sample compiler described
in textbook.

B (4 students)
• Many code fragments were
similar even with respect to
name of variables or
comments.
42
B
A
CCFinder/Gemini (1/4)

コードクローン検出手順
throws
{{{ String
static
throws
RESyntaxException
String
void
foofoo()
throws$RESyntaxException
RESyntaxException
String aaa {
1. static
throws
RESyntaxException
static
$void
(( (( )) ))throws
{ $ $
static void
$ $$foo
]{] {{${ "123,400"
,
]]] == a[]
new
$$[] { "123,400",
new
$$ =
$String
[ [][ String
$String
2. [[[String
new
"abc", "orange 100" };
"abc"
,
"orange
100"
}
;
org
.
apache
.
regexp
} ;
3. org.apache.regexp.RE
pat = new org.apache.regexp.RE("[0-9,]+");
RE
pat
$$ pat
$$ == new
new
4. .intRE
sum
=new
0; org . apache . regexp
. RE
int
sum
RE (( "[0-9,]+"
"[0-9,]+" ) ; int
int
sum
$ sum
$ === $000
5. for$$ (int $i$ = 0; i) < ;a.length;
++i)
;;; for
for (( int
int
$$ i$$i == 0$0 ;; i$ii <<<
6. a$ if. (pat.match(a[i]))
;++
pat
length
; ++
++
pat
$$ ;; ++
$$ ii) ))if ififif( ((($ pat
$ . length
7. ... match
sum
+=
Sample.parseNumber(pat.getParen(0));
sum
match
sum
$$ (( (( $$ aa [[ [[ $$ ii ] ]] ) ))) ) ))) $sum
8. +=
System.out.println("sum
" + sum);
((( 000
pat
getParen
Sample
parseNumber
pat$ ..=
. getParen
getParen
+=
$$ .. $.$. parseNumber
(( $$ . $ ((( (pat
+= Sample
9. } )) )) ;; System
println
"sum
System
out
println
"sum==="""
$$ .. .$$. out
. .$. println
( $ ((( "sum
static
String
+++ sum
void
goo
String
sum
static void
void
goo
String
$$ void
)))) ;;;; goo(String
}}}} static
$ $goo
10. static
[](a)((( $throws
RESyntaxException {
static
[[[ exp
]] )) =throws
RESyntaxException
RE
exp
RESyntaxException
RE exp
exp ===
throws
$RE("[0-9,]+");
{ $ $ = {{{ RE
throws
11. a$a$RE
newRESyntaxException
RE
(( "[0-9,]+"
int
RE
"[0-9,]+"
int sum
sum$ === 000
new
$$ sum
$$= 0;
)) ; )) $;; $int
=sum
new
12. new
int
for
for
$$ i$$i === 0$0 ;; i$ii <<<
for (( int
13. ;;; for
(intint
i = 0; i < a.length; ++i)
;++
a$a$ ... length
exp
length
; ++
++
exp
$$ ;; ++
$$ ii) ))if ififif( ((($ exp
14. . match
if (exp.match(a[i]))
sum
sum
.. match
$$ (( (( $$ aa [[ [[ $$ ii ] ]] ) ))) ) ))) $sum
15. +=
sum
+=
parseNumber(exp.getParen(0));
getParen
() 0) )(( )00 )) ))
$$$ .. parseNumber
$$ (( ( $$exp. ((. $exp
( .. $ getParen
parseNumber
exp
getParen
+= parseNumber
16. ;;; System.out.println("sum
sum);
==="""" +++
System
"sum
sum
$$ .. $.$. out
.. .$$. println
( $ (((+ "sum
$ =
System
out
println
"sum
+ sum
sum
17. }))) ;;; }}
ソースファイル
字句解析
トークン列
変換処理
変換後トークン列
検出処理
変換後トークン列上での
コードクローン
整形処理
43
クローンペア位置情報
Gappedクローン検出の背景
(2/2)

Gappedクローンを識別することが困難な理由


CCFinderが検出できるのはNgクローンのみ
Gappedクローンは複数の相対的に短いNgクローンとして検出される
• CCFinderは最小一致トークン数より短いコードクローンは検出しない
→ 個々の一致箇所が短ければ検出されない
• 一般に, 最小一致トークン数が短く設定されると,膨大な数のコードクロー
ンが検出される
1. static void foo() throws RESyntaxException
1. static void goo(String [] a) throws RESyntaxException
2. {
2. {
14 トークン
3. String a[] = new String [] {"123,400", "abc"};
3. RE exp = new RE(“[0-9,]+”);
4. org.apache.regexp.RE pat =
4. int sum =最小一致トークン数を
0;
5.
new org.apache.regexp.RE("[0-9,]+");
5. int i = 0; 20トークンに定める
6. int sum = 0;
6. while (i < a.length)と...
27 トークン
7. for (int i = 0; i < a.length; ++i)
7. {
8. {
8.
if (exp.match(a[i]))
9.
if (pat.match(a[i])){
9.
sum += parseNumber(exp.getParen(0));
13 トークン
10.
sum += Sample.parseNumber(pat.getParen(0));}
10.
i++;
11. }
11. }
12. System.out.println("sum = " + sum);
12. System.out.println("sum = " + sum);
30
トークン以上のクローンペア
10
13. }
13. }トークン以上のクローンペア
44
(クローンペア数:1208)
(クローンペア数:26984)