專利名稱:一種基于程序源代碼語義分析的代碼相似度檢測方法
技術(shù)領(lǐng)域:
本發(fā)明涉及計(jì)算機(jī)程序分析技術(shù)和計(jì)算機(jī)軟件的重復(fù)代碼檢測方法,具體涉及一
種語義相似的重復(fù)代碼檢測方法。
背景技術(shù):
重復(fù)代碼(也稱為克隆代碼)檢測是計(jì)算機(jī)軟件開發(fā)和維護(hù)活動中一項(xiàng)重要的任 務(wù),在源代碼剽竊檢測、軟件組件庫查詢、軟件缺陷檢測、程序理解等多個領(lǐng)域中都有廣泛 的應(yīng)用。 目前已有的重復(fù)代碼檢測方法主要可以劃分為基于文本的方法、結(jié)構(gòu)分析方法、 基于度量值的方法、基于相似子圖的方法。其中,前兩種方法只能檢測完全相同或只有很小 改動的代碼,如標(biāo)識符重命名或注釋改變。而基于度量值的方法雖然計(jì)算簡單、復(fù)雜度較 低,但檢測的準(zhǔn)確度差,且通常不會考慮函數(shù)調(diào)用的多樣化,不能識別模塊結(jié)構(gòu)不同但語義 相似的代碼片段。而由于編程語言的多樣性,同樣的功能可用多種語法結(jié)構(gòu)實(shí)現(xiàn),同一個算 法可能有多種等價的表示方式。這就導(dǎo)致了對于同一個編程任務(wù),源代碼的表達(dá)方式可以 是多種多樣的,這種現(xiàn)象稱為代碼多樣化。代碼多樣化常常出現(xiàn)在現(xiàn)實(shí)軟件系統(tǒng)中。例如, 在開發(fā)過程中沒有發(fā)現(xiàn)某個函數(shù)已經(jīng)實(shí)現(xiàn),而重新實(shí)現(xiàn)了一個語法表示不同但語義等價的 函數(shù);軟件重構(gòu)的過程中經(jīng)常進(jìn)行語義不變的轉(zhuǎn)換,如移動表達(dá)式、變量重命名、提取函數(shù) 或函數(shù)內(nèi)聯(lián)等;程序剽竊過程中常常以修改源程序加以掩飾,因此重復(fù)代碼檢測方法應(yīng)該 具有處理與識別這些代碼多樣化的功能,而實(shí)現(xiàn)上述處理和識別的功能就需要進(jìn)行語義分 析,對于語義分析,目前還沒有完善的解決方案?;谙嗨谱訄D的重復(fù)代碼檢測方法將源 代碼表示為程序依賴圖(Program D印endence Graph, PDG),基于PDG的同構(gòu)性識別相似代 碼。這種方法考慮程序的語法結(jié)構(gòu)以及數(shù)據(jù)流信息,但是仍有兩個關(guān)鍵問題沒有得到良好 解決(l)對代碼多樣化的識別能力有限,不能真正實(shí)現(xiàn)語義級別的重復(fù)代碼檢測;(2)較 高的計(jì)算復(fù)雜度。由于數(shù)據(jù)流分析的復(fù)雜度,PDG的規(guī)模有限,并且查找子圖同構(gòu)問題難點(diǎn), 計(jì)算復(fù)雜度較高。
發(fā)明內(nèi)容
本發(fā)明是為了解決現(xiàn)在的重復(fù)代碼檢測方法存在的對語法表示不同但語義相似
的代碼的相似度檢測準(zhǔn)確度低、計(jì)算復(fù)雜度高,以及無法實(shí)現(xiàn)大規(guī)模程序代碼相似度檢測
的問題,從而提出一種基于程序源代碼語義分析的代碼相似度檢測方法。 —種基于程序源代碼語義分析的代碼相似度檢測方法,它由以下步驟完成 步驟一、分別將待檢測的兩段源代碼解析為兩棵系統(tǒng)依賴圖的控制依賴樹; 步驟二、對步驟一獲得的兩棵控制依賴樹分別執(zhí)行基本代碼標(biāo)準(zhǔn)化,獲得兩棵基
本代碼標(biāo)準(zhǔn)化后的控制依賴樹; 步驟三、利用度量值方法分別提取步驟二獲得的兩棵基本代碼標(biāo)準(zhǔn)化后的控制依 賴樹的候選相似代碼控制依賴樹;
4
步驟四、判斷是否提取到候選相似代碼控制依賴樹,如果判斷結(jié)果為是,則執(zhí)行步 驟五,如果結(jié)果為否,則結(jié)束兩段源代碼的相似度檢測; 步驟五、對所述候選相似代碼控制依賴樹執(zhí)行高級代碼標(biāo)準(zhǔn)化操作; 步驟六、計(jì)算候選相似代碼控制依賴樹的結(jié)構(gòu)相似度StructureSim和候選相似
代碼控制依賴樹的語句相似度StatementSim,并根據(jù)公式 SemanticSim =入stru*StructureSim+入stat*StatementSim 計(jì)算候選相似代碼控制依賴樹的語義相似度,獲得語義相似度結(jié)果,完成代碼相 似度檢測;式中A stra為結(jié)構(gòu)相似度的權(quán)值、A stat為語句相似度的權(quán)值。
步驟二中所述基本代碼標(biāo)準(zhǔn)化的方法為采用基于系統(tǒng)依賴圖的程序標(biāo)準(zhǔn)化方法 對步驟一所述控制依賴樹進(jìn)行結(jié)構(gòu)語義等價的基本代碼標(biāo)準(zhǔn)化轉(zhuǎn)換;所述基本代碼標(biāo)準(zhǔn)化 轉(zhuǎn)換包括復(fù)合表達(dá)式的標(biāo)準(zhǔn)化轉(zhuǎn)換、表達(dá)式的標(biāo)準(zhǔn)化轉(zhuǎn)換和基本控制結(jié)構(gòu)的標(biāo)準(zhǔn)化轉(zhuǎn)換。
所述提取步驟三中利用度量值方法分別提取兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴 樹的候選相似代碼控制依賴樹的方法為 步驟A、分別在所述兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴樹上提取各模塊的規(guī)模、結(jié)
構(gòu)和復(fù)雜度特征信息,并分別統(tǒng)計(jì)各個模塊的度量向量,獲得兩段代碼的度量向量集;所述 度量向量集包括節(jié)點(diǎn)個數(shù)、運(yùn)算符個數(shù)、選擇結(jié)構(gòu)個數(shù)、循環(huán)結(jié)構(gòu)個數(shù)、賦值節(jié)點(diǎn)個數(shù)、特
殊數(shù)據(jù)類型個數(shù)、控制依賴樹中最長路徑長度、系統(tǒng)函數(shù)調(diào)用個數(shù)、遞歸調(diào)用路徑長度和控 制依賴邊個數(shù); 步驟B、將步驟A獲得兩段代碼的度量向量集,通過公式
計(jì)算兩段代碼的度量向量集的相似度sim(v,v');式中i = 1,2,3,……,10 ;n
s/附(v, v') = 1 _ J—X! — v, )/max(v,., ))2 3 10 ; 步驟C、判斷步驟B獲得的度量向量的相似度sim(v, v')是否大于預(yù)先設(shè)定的度 量向量相似度閾值Tv,如果判斷結(jié)果為是,則提取此兩段代碼做為候選相似代碼;如果判斷 結(jié)果為否,則結(jié)束兩段源代碼相似度檢測。
所述步驟五中的高級代碼標(biāo)準(zhǔn)化的方法為分別對兩棵候選相似代碼控制依賴樹 執(zhí)行標(biāo)準(zhǔn)化轉(zhuǎn)換,所述標(biāo)準(zhǔn)化轉(zhuǎn)換包括高級控制結(jié)構(gòu)標(biāo)準(zhǔn)化、消除冗余代碼、變量重命名、 語句重排列和函數(shù)調(diào)用標(biāo)準(zhǔn)化。
式
式
度,ls
所述步驟六中候選相似代碼控制依賴樹的結(jié)構(gòu)相似度StructureSim是根據(jù)公
StrcutureSim = StructureMatching(S, T)/|S| 獲得的;
所述步驟六中候選相似代碼控制依賴樹的語句相似度StatementSim是根據(jù)公
StatementSim = E value (vi)/|S|
獲得的,式中S為候選相似代碼控制依賴樹,value (vi)為S中節(jié)點(diǎn)的表達(dá)式相似 為候選相似代碼控制依賴樹S的節(jié)點(diǎn)總數(shù)。
5
有益效果本發(fā)明的代碼相似度檢測方法可以識別語義相似的重復(fù)代碼,可以應(yīng)用于大規(guī)模程序代碼的分析。本發(fā)明的方法通過將源代碼表示為改進(jìn)的系統(tǒng)依賴圖,降低了系統(tǒng)依賴圖表示的復(fù)雜度;并且根據(jù)代碼標(biāo)準(zhǔn)化,將系統(tǒng)依賴圖進(jìn)行語義不變的轉(zhuǎn)換,消除了各種代碼的多樣化,從而實(shí)現(xiàn)語義級別的重復(fù)代碼檢測;以及改進(jìn)基于度量值的方法,在代碼標(biāo)準(zhǔn)化的基礎(chǔ)上,以模塊單位計(jì)算度量值,提高度量值相似度計(jì)算的準(zhǔn)確性;結(jié)合以上兩種改進(jìn)方法,通過在計(jì)算語義相似度前引入計(jì)算復(fù)雜度較小的基于度量值的候選相似代碼"過濾"機(jī)制,縮小搜索空間,并且語義級別的匹配是基于樹的匹配,較大程度上降低了計(jì)算復(fù)雜度,能夠處理大規(guī)模程序。
圖1是本發(fā)明的方法的流程示意圖;圖2是本發(fā)明的方法所采用的基于系統(tǒng)依賴圖的程序標(biāo)準(zhǔn)化模型;圖3是具體實(shí)施方式
一中所述嵌套選擇結(jié)構(gòu)轉(zhuǎn)換成多分支結(jié)構(gòu)的轉(zhuǎn)換過程示意圖;圖4是具體實(shí)施方式
一中所述相鄰的選擇結(jié)構(gòu)的合并過程示意圖;圖5是具體實(shí)施方式
一中所述用if-else結(jié)構(gòu)替換if-conti皿e結(jié)構(gòu)的轉(zhuǎn)換過程示意圖;圖6是具體實(shí)施方式
一中所述消除if-break結(jié)構(gòu)過程示意圖;圖7是圖6的轉(zhuǎn)換結(jié)果示意圖;圖8是具體實(shí)施方式
一中所述用多分支的if、 if-else結(jié)構(gòu)替換if-return結(jié)構(gòu)的轉(zhuǎn)換過程示意圖。
具體實(shí)施例方式
具體實(shí)施方式
一、結(jié)合圖1 圖8說明本具體實(shí)施方式
,一種基于程序源代碼語義分析的代碼相似度檢測方法,它由以下步驟完成 步驟一、分別將待檢測的兩段源代碼解析為兩棵系統(tǒng)依賴圖的控制依賴樹;
步驟二、對步驟一獲得的兩棵控制依賴樹分別執(zhí)行基本代碼標(biāo)準(zhǔn)化,獲得兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴樹; 步驟三、利用度量值方法分別提取步驟二獲得的兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴樹的候選相似代碼控制依賴樹; 步驟四、判斷是否提取到候選相似代碼控制依賴樹,如果判斷結(jié)果為是,則執(zhí)行步驟五,如果結(jié)果為否,則結(jié)束兩段源代碼的相似度檢測; 步驟五、對所述候選相似代碼控制依賴樹執(zhí)行高級代碼標(biāo)準(zhǔn)化操作; 步驟六、計(jì)算候選相似代碼控制依賴樹的結(jié)構(gòu)相似度StructureSim和候選相似
代碼控制依賴樹的語句相似度StatementSim,并根據(jù)公式 SemanticSim = A stru*StructureSim+ A sta^StatementSim計(jì)算候選相似代碼控制
依賴樹的語義相似度,獲得語義相似度結(jié)果,完成代碼相似度檢測;式中、tru為結(jié)構(gòu)相似度的權(quán)值、入^t為語句相似度的權(quán)值。 步驟二中所述基本代碼標(biāo)準(zhǔn)化的方法為采用基于系統(tǒng)依賴圖的程序標(biāo)準(zhǔn)化方法對步驟一所述控制依賴樹進(jìn)行結(jié)構(gòu)語義等價的基本代碼標(biāo)準(zhǔn)化轉(zhuǎn)換;所述基本代碼標(biāo)準(zhǔn)化轉(zhuǎn)換包括復(fù)合表達(dá)式的標(biāo)準(zhǔn)化轉(zhuǎn)換、表達(dá)式的標(biāo)準(zhǔn)化轉(zhuǎn)換和基本控制結(jié)構(gòu)的標(biāo)準(zhǔn)化轉(zhuǎn)換。
所述提取步驟三中利用度量值方法分別提取兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴樹的候選相似代碼控制依賴樹的方法為
步驟A、分別在所述兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴樹上提取各模塊的規(guī)模、結(jié)
構(gòu)和復(fù)雜度特征信息,并分別統(tǒng)計(jì)各個模塊的度量向量,獲得兩段代碼的度量向量集;所述度量向量集包括節(jié)點(diǎn)個數(shù)、運(yùn)算符個數(shù)、選擇結(jié)構(gòu)個數(shù)、循環(huán)結(jié)構(gòu)個數(shù)、賦值節(jié)點(diǎn)個數(shù)、特
殊數(shù)據(jù)類型個數(shù)、控制依賴樹中最長路徑長度、系統(tǒng)函數(shù)調(diào)用個數(shù)、遞歸調(diào)用路徑長度和控制依賴邊個數(shù); 步驟B、將步驟A獲得兩段代碼的度量向量集,通過公式 s/m(v, v') = 1 — J—藝((v,. — v,')/max(v,., v/))2 計(jì)算兩段代碼的度量向量集的相似度sim(v,v');式中i = 1,2,3,……,10 ;n =
10 ; 步驟C、判斷步驟B獲得的度量向量的相似度sim(v, v')是否大于預(yù)先設(shè)定的度量向量相似度閾值Tv,如果判斷結(jié)果為是,則提取此兩段代碼做為候選相似代碼;如果判斷結(jié)果為否,則結(jié)束兩段源代碼相似度檢測。 所述步驟五中的高級代碼標(biāo)準(zhǔn)化的方法為分別對兩棵候選相似代碼控制依賴樹執(zhí)行標(biāo)準(zhǔn)化轉(zhuǎn)換,所述標(biāo)準(zhǔn)化轉(zhuǎn)換包括高級控制結(jié)構(gòu)標(biāo)準(zhǔn)化、消除冗余代碼、變量重命名、語句重排列和函數(shù)調(diào)用標(biāo)準(zhǔn)化。 所述步驟六中候選相似代碼控制依賴樹的結(jié)構(gòu)相似度StructureSim是根據(jù)公式 StrcutureSim = StructureMatching(S, T)/|S| 獲得的,式中S和T是兩棵候選相似代碼的結(jié)構(gòu)樹,StructureMatching(S, T)為
S與T的最大匹配節(jié)點(diǎn)對個數(shù),|S|為候選相似代碼的結(jié)構(gòu)樹S的節(jié)點(diǎn)總數(shù)。 所述步驟六中候選相似代碼控制依賴樹的語句相似度StatementSim是根據(jù)公
式 Statements im = E value(vi)/|S| 獲得的,式中S為候選相似代碼控制依賴樹,value (vi)為S中節(jié)點(diǎn)的表達(dá)式相似度,|S|為候選相似代碼控制依賴樹S的節(jié)點(diǎn)總數(shù)。 本發(fā)明的基本思想是首先,讀取待檢測的兩段源程序文件進(jìn)行預(yù)處理,創(chuàng)建程序的系統(tǒng)依賴圖;然后,執(zhí)行基本代碼標(biāo)準(zhǔn)化,消除對度量值計(jì)算有較大影響的代碼多樣化;接下來,基于度量值的方法提取候選相似代碼,快速過濾掉大部分不相似的代碼片段,縮小后續(xù)語義級別代碼檢索的空間;下一步,對提取的候選相似代碼執(zhí)行高級代碼標(biāo)準(zhǔn)化,消除代碼多樣化,盡量使等價的語義具有相同的表示方式;最后,通過在結(jié)構(gòu)和語句表達(dá)式級別匹配標(biāo)準(zhǔn)化的控制依賴樹,計(jì)算語義相似度,從而識別語法結(jié)構(gòu)不同而語義相似的代碼。
下面對本發(fā)明的方法做進(jìn)一步詳細(xì)說明 在步驟一中,對兩段源代碼進(jìn)行詞法分析和語法分析以及控制流、數(shù)據(jù)流分析,構(gòu)造程序的系統(tǒng)依賴圖。 這里,詞法分析將程序代碼轉(zhuǎn)換為可以進(jìn)行語法分析的token流。語法分析將生成程序的抽象語法樹表示。 然后生成系統(tǒng)依賴圖,系統(tǒng)依賴圖是程序的圖形表示。系統(tǒng)依賴圖可以分解為控制依賴子圖和數(shù)據(jù)依賴子圖??刂埔蕾囎訄D由節(jié)點(diǎn)和控制依賴邊構(gòu)成,表示程序的控制流
信息;數(shù)據(jù)依賴子圖由節(jié)點(diǎn)和數(shù)據(jù)依賴邊構(gòu)成,表示程序的數(shù)據(jù)流信息。 本發(fā)明改進(jìn)傳統(tǒng)的系統(tǒng)依賴圖表示形式。將控制依賴子圖表示為有序樹的形式,
本發(fā)明稱之為控制依賴樹。并且只在必要時,即高級代碼標(biāo)準(zhǔn)化時,對提取的候選相似代碼
分析數(shù)據(jù)依賴子圖中的數(shù)據(jù)流信息,由于候選相似代碼只占源程序的一小部分,因此可以
有效地降低系統(tǒng)依賴圖表示的復(fù)雜度,從而使之適合于分析大規(guī)模程序。 在步驟二中,在系統(tǒng)依賴圖的控制依賴子圖上執(zhí)行基本代碼標(biāo)準(zhǔn)化。 基于度量值的方法提取候選相似代碼會因代碼多樣化而導(dǎo)致度量值計(jì)算偏差,從
而產(chǎn)生漏檢。為了避免這一問題,本發(fā)明提出基于系統(tǒng)依賴圖轉(zhuǎn)換的代碼標(biāo)準(zhǔn)化方法。 基本代碼標(biāo)準(zhǔn)化根據(jù)標(biāo)準(zhǔn)化規(guī)則對控制依賴樹進(jìn)行結(jié)構(gòu)語義等價的轉(zhuǎn)換,直到任
何規(guī)則都不能應(yīng)用為止??梢韵龔?fù)合表達(dá)式多樣化、表達(dá)式多樣化以及控制結(jié)構(gòu)多樣化
等會影響度量值相似度計(jì)算的準(zhǔn)確度的代碼多樣化的問題。 本發(fā)明的程序標(biāo)準(zhǔn)化方法采用王甜甜、蘇小紅、馬培軍在中國武漢發(fā)表的《消除代碼多樣化的程序標(biāo)準(zhǔn)化》(2008,306 309, EI收錄號20091211962490)和上述三人在中國上海發(fā)表的《消除模塊程序中代碼多樣化的程序標(biāo)準(zhǔn)化》(2008,21 24, EI收錄號20091211972107, ISTP收錄號BIX53)中記錄的采用基于系統(tǒng)依賴圖(System D印endenceGraph, SDG)的程序標(biāo)準(zhǔn)化方法。這種方法改進(jìn)了傳統(tǒng)的系統(tǒng)依賴圖表示,使其充分表示程序的語法結(jié)構(gòu)與語義。并針對已有的指針分析算法不適合于程序標(biāo)準(zhǔn)化的問題,基于控制依賴樹和改進(jìn)的指向表示方法提出流敏感和上下文敏感的指針分析算法,提高指針分析和數(shù)據(jù)流分析的準(zhǔn)確性,并使得指針分析結(jié)果可直接應(yīng)用于程序標(biāo)準(zhǔn)化轉(zhuǎn)換中。最后將改進(jìn)的系統(tǒng)依賴圖、指針分析算法與程序標(biāo)準(zhǔn)化過程有機(jī)結(jié)合提出基于系統(tǒng)依賴圖的程序標(biāo)準(zhǔn)化模型,根據(jù)程序標(biāo)準(zhǔn)化轉(zhuǎn)換規(guī)則,對系統(tǒng)依賴圖進(jìn)行語義不變的轉(zhuǎn)換,從而消除代碼多樣化。 常見的代碼多樣化可以概括為以下幾種 (1)代碼格式多樣化語義等價的代碼可能具有不同的代碼格式。例如,不同個數(shù)
的注釋和空行。在解析程序時可以通過刪除注釋和空行消除這種多樣化。
(2)復(fù)合語句多樣化有些程序元素可以用一條語句表示,也可以用多條語句構(gòu)
成的語句序列表示。 (3)表達(dá)式多樣化由于各種運(yùn)算符的優(yōu)先級和結(jié)合性不同,導(dǎo)致語義等價的表達(dá)式可以用多種形式表示。
(4)控制結(jié)構(gòu)多樣化源代碼中通常含有三種控制結(jié)構(gòu),即順序、分支和循環(huán)。這
些控制結(jié)構(gòu)中有時還包含控制轉(zhuǎn)移語句,每種控制結(jié)構(gòu)可以用多種語法表示。
(5)冗余代碼程序中可能包含一些無用的語句或使用不同數(shù)目的臨時變量。
(6)函數(shù)調(diào)用多樣化實(shí)現(xiàn)一個算法,函數(shù)的模塊結(jié)構(gòu)可以是多種多樣的,函數(shù)的
個數(shù)以及函數(shù)調(diào)用語句的位置都可能不同。
(7)標(biāo)識符命名多樣化語義等價的代碼中的變量名稱可能不同。
(8)語句順序多樣化語義等價的代碼中的語句排列順序可能不同。
(9)數(shù)據(jù)結(jié)構(gòu)多樣化語義等價的代碼可能用不同的數(shù)據(jù)結(jié)構(gòu)表示,如指針與數(shù)
組表示的多樣化等。
8
基于系統(tǒng)依賴圖的程序標(biāo)準(zhǔn)化方法對這些代碼多樣化進(jìn)行處理,識別包含這些多樣化的相似代碼。
下面結(jié)合圖2具體說明基于系統(tǒng)依賴圖的程序標(biāo)準(zhǔn)化規(guī)則 圖2為基于系統(tǒng)依賴圖SDG (System D印endence Graph)的程序標(biāo)準(zhǔn)化模型,其中SDG是程序代碼的語義表示。如果待檢測的一個源代碼P與另一個源代碼P'具有相同的SDG表示,則所述兩個源代碼P與P'是語義等價的。如果它們具有相似的SDG表示,則所述兩個源代碼P與P'是語義相似的。然而,如果所述兩個源代碼P與P'語義相似,它們的SDG不一定相似。 語義等價的轉(zhuǎn)換如果一個轉(zhuǎn)換改變了代碼的計(jì)算行為卻不改變計(jì)算結(jié)果,則稱該轉(zhuǎn)換為語義等價的轉(zhuǎn)換。使用一系列語義等價的轉(zhuǎn)換可將采用相同算法且語義上等價的代碼標(biāo)準(zhǔn)化為相同的SDG。 程序標(biāo)準(zhǔn)化程序標(biāo)準(zhǔn)化是根據(jù)一系列轉(zhuǎn)換規(guī)則對SDG進(jìn)行語義等價的轉(zhuǎn)換的過程,程序標(biāo)準(zhǔn)化可以消除代碼多樣化。 首先解析源程序,將源程序表示為一種中間表示形式。為了使程序的中間表示方
式既便于程序標(biāo)準(zhǔn)化轉(zhuǎn)換,又便于在指針分析過程中利用標(biāo)準(zhǔn)化轉(zhuǎn)換結(jié)果簡化指針分析,考慮到樹結(jié)構(gòu)便于執(zhí)行指針分析與程序轉(zhuǎn)換,因此本方法提出控制依賴樹CDT(ControlD印endence Tree,)的程序中間表示形式,在表示程序語法結(jié)構(gòu)的同時充分表達(dá)程序的語義信息。 然后對CDT進(jìn)行基本標(biāo)準(zhǔn)化轉(zhuǎn)換,以消除部分代碼多樣化,生成標(biāo)準(zhǔn)化的CDT,從而簡化隨后的指針分析。 接下來,遍歷標(biāo)準(zhǔn)化的CDT,計(jì)算各個節(jié)點(diǎn)的指針別名。程序標(biāo)準(zhǔn)化轉(zhuǎn)換需要確保程序的語義不變,對指針分析的準(zhǔn)確性要求較高,因此這種標(biāo)準(zhǔn)的指針分析算法采用了流敏感和上下文敏感的分析方法。 然后,就可以利用指向信息集合執(zhí)行數(shù)據(jù)流分析,在CDT的基礎(chǔ)上創(chuàng)建數(shù)據(jù)流圖,進(jìn)一步執(zhí)行高級標(biāo)準(zhǔn)化轉(zhuǎn)換,消除代碼多樣化。最后生成的標(biāo)準(zhǔn)化SDG(由CDT和數(shù)據(jù)流圖構(gòu)成),可直接應(yīng)用于程序分析中。 基于系統(tǒng)依賴圖的程序標(biāo)準(zhǔn)化模型將系統(tǒng)依賴圖創(chuàng)建、指針分析與程序標(biāo)準(zhǔn)化過程有機(jī)結(jié)合在一起,既利用程序標(biāo)準(zhǔn)化簡化指針分析,又將指針分析結(jié)果直接應(yīng)用于程序標(biāo)準(zhǔn)化轉(zhuǎn)換中,提高程序標(biāo)準(zhǔn)化轉(zhuǎn)換的代碼多樣化消除率,從而提高程序分析的靈活性。
本標(biāo)準(zhǔn)將標(biāo)準(zhǔn)化分為兩類,其中在執(zhí)行轉(zhuǎn)換時不需要數(shù)據(jù)流與指針別名信息的標(biāo)準(zhǔn)化稱為基本標(biāo)準(zhǔn)化?;敬a標(biāo)準(zhǔn)化根據(jù)一系列標(biāo)準(zhǔn)化規(guī)則對CDT進(jìn)行結(jié)構(gòu)語義等價的轉(zhuǎn)換,直到任何規(guī)則都不能應(yīng)用為止。
所述基本代碼標(biāo)準(zhǔn)化包括
1、拆分復(fù)合語句 復(fù)合語句被拆分為等價的語句序列,消除復(fù)合語句多樣化 將表達(dá)式轉(zhuǎn)換為只引用變量而不定義變量的形式,從而消除副作用。例如while ((i = j/k) < 1) { . . } — i = j/k ;while(i < 1) { i = j/k ;} 拆分變量聲明語句。例如 int i, j int i ;int j ;
9
拆分變量聲明與初始化語句。例如 int i = 0 ;— int i ;i = 0 ; 拆分輸入/輸出語句。例如 scanf ( "% d% d", &i, &j) — scanf ( "% d", &i) ;scanf ( "% d", &j); 拆分連續(xù)的賦值語句。例如 i = j = kj = k ;i = j ; 如果數(shù)組下標(biāo)是復(fù)合表達(dá)式,則用臨時變量替換該復(fù)合表達(dá)式。例如 r = a[b[i]] t = b[i] ;n = a[t]; 如果復(fù)合表達(dá)式中含有函數(shù)調(diào)用語句,則用臨時變量替換該函數(shù)調(diào)用語句。例如 if (x+sqrt(y) >()){ } — t = sqrt (y) ;if (x+t >()){ },如果函數(shù)調(diào)用語句中的實(shí)參是復(fù)合表達(dá)式,則用臨時變量替換該復(fù)合表達(dá)式。例
如 i = fun(j+k) — t = j+k ;i = fun(t); *如果return語句返回的是復(fù)合表達(dá)式,則用臨時變量替換該復(fù)合表達(dá)式。例如 return i+j — t = i+j 5return t 5 2、表達(dá)式標(biāo)準(zhǔn)化 算術(shù)表達(dá)式標(biāo)準(zhǔn)化利用算術(shù)運(yùn)算符的分配律、交換律、恒等式等屬性,建立轉(zhuǎn)換規(guī)則,用以消除表達(dá)式多樣化。這些規(guī)則被反復(fù)調(diào)用,對表達(dá)式語法樹進(jìn)行轉(zhuǎn)換,直到任何規(guī)則都不適用于表達(dá)式。布爾表達(dá)式標(biāo)準(zhǔn)化與算術(shù)表達(dá)式標(biāo)準(zhǔn)化規(guī)則類似,只是它的轉(zhuǎn)換規(guī)則是根據(jù)布爾運(yùn)算符的屬性定義的,并且應(yīng)用于布爾表達(dá)式。如下為幾個典型的表達(dá)式標(biāo)準(zhǔn)化規(guī)則,其中Al, A2, A3為常量、變量或子表達(dá)式。 Rl :A1+(A2+A3) — (Al+A2)+A3 R2 : (Al | |A2)&&A3 — (A1&&A3) | | (A2&&A3) R3 :A2 < Al — Al > A2 宏替換是一種特殊的表達(dá)式標(biāo)準(zhǔn)化,用宏定義的常量或表達(dá)式替換宏定義符號。例如,#define PI 3. 1415area = PI承r承r ;一 area = 3. 1415承r承r ; 3、基本的控制結(jié)構(gòu)標(biāo)準(zhǔn)化 對選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)進(jìn)行轉(zhuǎn)換,消除一些控制結(jié)構(gòu)多樣化。
統(tǒng)一選擇結(jié)構(gòu)的表示形式,將各種選擇語句表示為selection結(jié)構(gòu)。
統(tǒng)一循環(huán)結(jié)構(gòu)的表示形式,將各種循環(huán)語句表示為iteration結(jié)構(gòu)。,合并相鄰的選擇結(jié)構(gòu)。如果兩個相鄰的選擇結(jié)構(gòu)滿足下列條件,則將它們合并為
一個選擇結(jié)構(gòu) (1)它們在CDT中是兄弟節(jié)點(diǎn); (2)只有一個選擇分支; (3)條件表達(dá)式是互斥的。例如 if(exp) if(exp) A A
if ( ! exp) else
B B 刪除永遠(yuǎn)得不到執(zhí)行的選擇分支。例如 if(l)A else B —A if(O)A else B — B if(e)if(e)A else B — if(e)A 刪除邏輯表達(dá)式恒為假的循環(huán)單元。例如 do A while (0) A while (0) A 空語句,從CDT中刪除該循環(huán)結(jié)構(gòu)。,通過將條件表達(dá)式進(jìn)行與操作,將嵌套選擇結(jié)構(gòu)轉(zhuǎn)換成多分支結(jié)構(gòu)。轉(zhuǎn)換過程如圖3所示。,合并相鄰的選擇結(jié)構(gòu)。如果多個相鄰的selection結(jié)構(gòu)滿足以下條件 (1)具有相同個數(shù)的選擇分支; (2)相應(yīng)分支的條件表達(dá)式相同。 則如圖4所示,將它們合并為一個選擇結(jié)構(gòu)。 在步驟三中,執(zhí)行基于度量值的候選相似代碼提取。 如果兩段代碼實(shí)現(xiàn)相同的算法,則它們通常具有相似的規(guī)模、結(jié)構(gòu)、1/0模式等程序特征,本發(fā)明改進(jìn)基于度量值的方法,提出基于度量值的候選相似代碼提取方法。在語義級別比較之前,利用效率很高的基于度量值的候選相似代碼提取方法,快速過濾掉大部分不相似的代碼片段,縮小語義級別代碼檢索的空間。由于基于度量值的方法計(jì)算簡單,復(fù)雜度低,因此本發(fā)明將其用于預(yù)處理階段,快速地篩選出可能的相似代碼,然后再對可能的相似代碼進(jìn)行更精確的基于系統(tǒng)依賴圖的語義分析,這樣,不僅有助于提高算法的效率,還能確保得到準(zhǔn)確的檢測結(jié)果。 在兩個待檢測的源代碼P與P'中提取候選相似代碼的算法主要包括兩部分首先,計(jì)算P與P'的各個模塊的度量向量,然后,計(jì)算度量向量相似度,并根據(jù)設(shè)定的度量向量相似度閾值Tv,提取候選相似代碼。 假設(shè)模塊/c尸與模塊/'cP'的度量向量分別為v(Vl, v2, v3, v4, v5, v6, v7, v8, v9,v10) , v, (Vl, , v2, , v3, , v4, , v5, , v6, , v7, , v8, , v9, , v10,),貝U v與v,的相似度計(jì)算方法如下。
由(v,v') = 1 - J—藝("- v,.)/max(巧,"'》2 (j) 如果sim(v, v' ) 〉Tv,則將函數(shù)f和f'所直接調(diào)用或間接調(diào)用的控制依賴樹子
樹構(gòu)成的集合,以及函數(shù)f和f'所直接調(diào)用或間接調(diào)用的控制依賴樹子樹構(gòu)成的集合,加
入到候選相似代碼列表中。 在步驟五中,執(zhí)行高級代碼標(biāo)準(zhǔn)化。 將需要進(jìn)行數(shù)據(jù)流分析的代碼標(biāo)準(zhǔn)化稱為高級代碼標(biāo)準(zhǔn)化。代碼標(biāo)準(zhǔn)化的目的是消除代碼多樣化,使等價的語義有相同的表示方式,從而提高代碼語義相似度計(jì)算的準(zhǔn)確性。標(biāo)準(zhǔn)化過程中進(jìn)行語義不變的轉(zhuǎn)換是由一系列替換規(guī)則限制的。為確保應(yīng)用這些規(guī)則前后,代碼具有相同的語義,因此,還需在控制依賴樹的基礎(chǔ)上進(jìn)行數(shù)據(jù)流分析,保持?jǐn)?shù)據(jù) 流依賴和控制依賴關(guān)系不變,這樣才能保持它們的語義等價。本發(fā)明將需要進(jìn)行數(shù)據(jù)流分 析的代碼標(biāo)準(zhǔn)化稱為高級代碼標(biāo)準(zhǔn)化。高級代碼標(biāo)準(zhǔn)化可以消除控制結(jié)構(gòu)多樣化、函數(shù)調(diào) 用多樣化、冗余代碼、變量名多樣化、語句順序多樣化等會影響語義相似度計(jì)算的準(zhǔn)確度的 代碼多樣化。高級代碼標(biāo)準(zhǔn)化規(guī)則保持流依賴和控制依賴不變,從而保持了它們的語義聯(lián) 系不變。高級控制結(jié)構(gòu)標(biāo)準(zhǔn)化用于消除一些控制結(jié)構(gòu)多樣化。包括
,合并相鄰的具有相同控制條件表達(dá)式的多個循環(huán)單元。例如
<formula>formula see original document page 12</formula>
'消除if-continue結(jié)構(gòu)。用if-else結(jié)構(gòu)替換if-continue結(jié)構(gòu),轉(zhuǎn)換過程如圖
提取循環(huán)體中值不變的語句。例如 <formula>formula see original document page 12</formula>
5所示。 *消除if-break結(jié)構(gòu)。通過增加控制循環(huán)條件,消除break語句。如果圖6中,表 達(dá)式e2與Bl和B2都不存在數(shù)據(jù)依賴關(guān)系,則轉(zhuǎn)換成圖7左側(cè)部分的形式,否則引入一個 中間變量var,轉(zhuǎn)換成圖7右側(cè)部分的形式。
消除if-return結(jié)構(gòu)。用多分支的if、 if-else結(jié)構(gòu)替換if-return結(jié)構(gòu),轉(zhuǎn)換 過程如圖8所示。
轉(zhuǎn)換循環(huán)語句中某些特殊的條件表達(dá)式,例如
<formula>formula see original document page 12</formula>,其中i不在A中出現(xiàn)。
2、函數(shù)調(diào)用標(biāo)準(zhǔn)化 函數(shù)調(diào)用標(biāo)準(zhǔn)化用于消除函數(shù)調(diào)用多樣化,把不含遞歸調(diào)用的模塊進(jìn)行函數(shù)內(nèi) 聯(lián),將其轉(zhuǎn)換成一個沒有函數(shù)調(diào)用語句的語義等價的程序。 函數(shù)內(nèi)聯(lián)用被調(diào)函數(shù)的函數(shù)體的拷貝替換函數(shù)調(diào)用語句,內(nèi)聯(lián)后的程序與內(nèi)聯(lián)前 的程序是語義等價的。在理論上函數(shù)內(nèi)聯(lián)展開可能導(dǎo)致程序規(guī)模的指數(shù)級增長,但是在實(shí) 際應(yīng)用中這種問題很少出現(xiàn)。本發(fā)明對子程序進(jìn)行內(nèi)聯(lián)操作,子程序的規(guī)模通常是有限的, 因此不會出現(xiàn)這種問題。
目前人們已經(jīng)提出了多種函數(shù)內(nèi)聯(lián)算法和策略,但大多是用于優(yōu)化編譯器中的, 不適合直接應(yīng)用于程序分析和程序匹配。為此,本發(fā)明提出基于函數(shù)調(diào)用樹與PDG的函數(shù) 內(nèi)聯(lián)算法。為各個子程序建立函數(shù)調(diào)用樹,因此可以通過后根序遍歷函數(shù)調(diào)用樹,確定當(dāng)前 要進(jìn)行內(nèi)聯(lián)操作的主調(diào)函數(shù)和被調(diào)函數(shù)。 函數(shù)內(nèi)聯(lián)等價于復(fù)制被調(diào)函數(shù)的PDG,并將其內(nèi)聯(lián)到主調(diào)函數(shù)的PDG中。PDG的內(nèi) 聯(lián)操作有如下幾步
(1) 將被調(diào)函數(shù)的PDG中聲明的變量重命名。
(2) 處理參數(shù)傳遞并修改節(jié)點(diǎn)間的數(shù)據(jù)依賴關(guān)系。
(3) 處理返回值傳遞并修改節(jié)點(diǎn)間的數(shù)據(jù)依賴關(guān)系。
(4) 修改節(jié)點(diǎn)間的控制依賴關(guān)系。
(5) 刪除主調(diào)函數(shù)中的函數(shù)調(diào)用節(jié)點(diǎn)、被調(diào)函數(shù)中的entry節(jié)點(diǎn)以及和它們相關(guān)
0170] 0171] 0172] 0173] 0174] 聯(lián)的邊。
0175] 經(jīng)過內(nèi)聯(lián)操作后,每個不含遞歸調(diào)用的模塊都轉(zhuǎn)換為一個不含函數(shù)調(diào)用語句與子 函數(shù)的PDG,從而消除了函數(shù)調(diào)用多樣化。
0176] 遞歸函數(shù)不進(jìn)行內(nèi)聯(lián)操作。針對同一個編程任務(wù)編寫的遞歸程序,大都具有類似 的模塊結(jié)構(gòu),只是函數(shù)名字、參數(shù)名字和順序可能有所區(qū)別,這種多樣化可通過變量重命名 和重排語句順序進(jìn)行消除。
0177] 3、消除冗余代碼
常量傳播。例如
i = 0 ; j = i ;k = j + l i = 0 ;j = 0 ;k = 1 ;
消除恒等表達(dá)式。例如刪除語句i = i。
消除公共子表達(dá)式。例如
if (i > 1) t = n-l ;
j = i/(n-l) ; if(i > 1)
0178] 0179] 0180] 0181] 0182] 0183] 0184]
0185] 0186] 0187] 0188]
6ls6 k =
i承(n-l)
消除死代碼。如果一個變j
6ls6
k = i*t ;
:沒有被任何語句引用,則刪除該變』
:的聲明語句;如
果賦值語句的左值沒有被任何語句引用,則刪除該賦值語句。例如
0189] 0190] 0191]
0192] 0193] 0194] 0195]
main
0
main
o
int
int
j = 1 ;
printf ( "% d", i)
1
printf ( "% d", i)
} 4、指針必然別名替換 由于互為別名的兩個命名對象指向同一個存儲區(qū)域,所以對同一個存儲地址的引 用方式可能因別名的存在而產(chǎn)生多樣化。例如程序int add(int x, inty){〃slreturnx+y 5〃s2〃s3main 0 {〃s4int sum = 0 ;〃s5int i = 1;//s6int* = &sum ;〃s7int氺q = &i ;〃s8int(承f) (int, int) = add ;〃s9while (*q < 11){〃sl0承p =(承f)(承p,承q);〃sll氺q =氺q+l ;〃sl2〃sl3printf ( "% d/n,,,氺p);〃sl4printf ( "% d\n,,,氺q);〃sl5 } 程序中*q與i互為別名,因此既可以通過*q也可以通過i訪問相應(yīng)的內(nèi)存地址, 賦值語句*q = *q+l ;可以等價地表示為i = i+1 ;,這就是由指針別名引入的代碼多樣化。
別名信息可以分類為兩種必然別名(Must alias)和可能別名(May alias)。必 然別名是指在程序的所有執(zhí)行中都出現(xiàn)的別名關(guān)系;可能別名是在程序的某些執(zhí)行中出現(xiàn) 的別名關(guān)系。兩個變量如果互為必然別名,則可以相互替換。而如果它們互為可能別名,則 不可進(jìn)行替換,因?yàn)樗鼈儾豢偸堑葍r的。指針變量的必然別名替換的思想是用必然別名替 換指針變量,以減少程序中由于別名對導(dǎo)致的代碼多樣化。
指針必然別名替換的算法,如程序
算法AliasesR印lacement
輸入具有指向集合的CDT 輸出替換了具有必然別名的指針變量和表達(dá)式的CDT
Begin foreach CDT中的節(jié)點(diǎn)N if N的表達(dá)式引用了指針變量pvar then if存在〈*pvar, t, D> G INN| | (pvar, t, D) G INN &&不存在(Vvar,f:D) g GENN &&不存在。;7var,/:P) g GENN then 用t替換節(jié)點(diǎn)N的表達(dá)式中的*pvar或pvar endif endif
endfor
End 檢查SDG的每個節(jié)點(diǎn),如果其對應(yīng)的語句中引用了指針變量pvar,但該指針變量 在此處未因賦值而產(chǎn)生新的別名,就分析該節(jié)點(diǎn)的入口處的別名信息集合。如果入口處的 別名信息集合中含有唯一的形如〈*pvar, t, D>或者〈pvar, t, D>的別名對,而節(jié)點(diǎn)對應(yīng)的 語句中又引用變量pvar卻沒有產(chǎn)生新的別名,則用t替換節(jié)點(diǎn)的語句中所含的*pvar或者 對程序 int add(int x, inty) { 〃sl return x+y ; 〃s2 } 〃s3 main () { 〃s4 int sum = 0 ; 〃s5 int i = 1 ; 〃s6 int*p = &sum ; 〃s7 int*q = &i ; 〃s8 int(氺f) (int, int) = add ; 〃s9 while(*q < 11) { 〃sl0 *p = (*f) (*p, *q) ; 〃sll 氺q =氺q+l ; //sl2 } 〃sl3 printf ( "% d\n,,,氺p) ; 〃sl4 printf ( "% d\n,,,氺q) ; 〃sl5 } 中的示例程序進(jìn)行別名替換,由指針分析算法分析得到s7, s8, s9分別產(chǎn)生別名
對〈*p, sum, D>, 〈*q, i, D>, 〈*f, add, D>,因此slO, sll, s12, s13, s14與s15的IN集合為
(〈氺p, sum, D>,〈氺q, i, D>,〈氺f, add, D>}。然后手丸《亍必然另U名替換,slO, sll與s14中的氺p
被sum替換。sll, s12與s15中的氺q被i替換。sll中的*f被add替換。最后s7, s8與
s9變?yōu)槲幢灰玫恼Z句而被刪除。最后得到語義等價的程序 int add(intx, int y) { return x+y 5 } main () { int sum = 0 ; int i = 1 ; while (i < 11) { sum = add (sum, i); i = i+1 ; }
15
printf ( "% d\n,,, sum); printf ( "% d\n", i); } 5、變量重命名 如果兩段代碼語義等價,則對應(yīng)的變量的類型和出現(xiàn)頻率通常是相同的。因此可 根據(jù)變量的類型以及出現(xiàn)的頻率給變量重命名。 首先,將相同類型的變量按照出現(xiàn)的頻率排序。然后,將變量重命名為的
形式,其中,第一個"ft"表示變量的類型,如,"i"表示整型,"c"表示字符型,"f'表示浮點(diǎn)
型,"F"表示FILE滯二個"#"表示特殊的類別,如,"A"表示數(shù)組,"P"表示指針,"S"表示
結(jié)構(gòu)體;第三個"#"表示該變量出現(xiàn)頻率的排序。例如,iA Ol表示一個數(shù)組變量,類型是
int類型,出現(xiàn)的頻率在所有int類型變量中排列第一。循環(huán)控制變量是特殊命名的,第一
個字符是'x'。遞歸程序的函數(shù)名的形式為recSub—Func」,其中,i為該函數(shù)被第一次調(diào)
用的順序。非遞歸函數(shù)名的形式為"Sub—Func」"其中,i為該函數(shù)在模塊中定義的順序。
最后,用新的變量名替換SDG中舊的變量名。通過變量重命名可以識別變量名字不同的但
語義相似的代碼片段。 6、重排語句順序 重排語句順序的算法如程序 算法StatementsReorde:ring 輸入模塊的各個PDG 輸出語句重排序后的PDGs Begin 后根序遍歷CDT ; foreach CDT中的節(jié)點(diǎn)N if N有兩個或兩個以上的控制依賴子節(jié)點(diǎn)then 假設(shè)SI與S2是N的子節(jié)點(diǎn) if SI是S2的左兄弟并且SI與S2間不存在數(shù)據(jù)依賴關(guān)系then if symbol (S2)的字符排序小于symbol (SI) then 交換SI與S2在CDT中的位置 endif endif endif endfor End 所示,可以消除語句排列順序的多樣化。如果兩條語句間不存在數(shù)據(jù)依賴,則它們 可以互換位置,這樣的語句被重新排序。 將SDG中的每個節(jié)點(diǎn)表示為形為"X:Y"的符號,其中"X"是該節(jié)點(diǎn)的類型(例如, "#decla:re,,, "assignment", "selection", "iteration", "entry"等),"Y,,是該節(jié)點(diǎn)的語 句或表達(dá)式,例如,"assignment :x_01 = 1"。對于PDG中兩個節(jié)點(diǎn)SI和S2,如果SI與S2 具有相同的控制依賴父節(jié)點(diǎn),S1與S2不存在數(shù)據(jù)依賴關(guān)系,并且S2的符號比SI符號按字
16符排序小,則在CDT中將S2排列在SI的前面。經(jīng)過語句重排序后各個節(jié)點(diǎn)在有序樹CDT
中的位置就唯一確定了。 在步驟六中,計(jì)算語義相似度。 在標(biāo)準(zhǔn)化的控制依賴樹的基礎(chǔ)上進(jìn)行結(jié)構(gòu)匹配和語句匹配兩個級別上的匹配。按 以下如公式計(jì)算語義相似度 SemanticSim =入stru*StructureSim+入stat*StatementSim 其中StructureSim、 StatementSim分別為結(jié)構(gòu)相似度和語句相似度,A stru、 A stat 分別為這兩個相似度的權(quán)值,滿足Astat> Astra>0, Astra+、tat = 1。不但考慮程序結(jié)構(gòu), 而且考慮具體的語句表達(dá)式,因此可以準(zhǔn)確度量程序的語義相似度。結(jié)構(gòu)匹配和語句匹配 方法如下 (1)結(jié)構(gòu)匹配 本發(fā)明給出以下兩個定義作為結(jié)構(gòu)匹配的基礎(chǔ) 定義(結(jié)構(gòu)樹)在控制依賴樹基礎(chǔ)上提取程序的循環(huán)、選擇、順序結(jié)構(gòu),生成只包 含節(jié)點(diǎn)類型及其之間的控制依賴邊的樹型結(jié)構(gòu),稱為結(jié)構(gòu)樹。 定義(匹配節(jié)點(diǎn)對)兩棵結(jié)構(gòu)樹T1、T2的節(jié)點(diǎn)對(vl, v2)是匹配節(jié)點(diǎn)對,當(dāng)且僅 當(dāng) 1) vl與v2具有相同的符號,即相同的類型。
2)vl、v2的父節(jié)點(diǎn)是匹配節(jié)點(diǎn)對。 3)假設(shè)wl與w2是匹配節(jié)點(diǎn)對,vl與wl是兄弟,v2與w2是兄弟,那么若vl在wl 前出現(xiàn),則v2在w2前出現(xiàn)。 4)vl至多能和T2中的一個節(jié)點(diǎn)匹配,v2至多能和Tl中的一個節(jié)點(diǎn)匹配。 結(jié)構(gòu)樹可充分表示程序的控制結(jié)構(gòu),因此候選相似代碼的結(jié)構(gòu)匹配相似度可由它
們的結(jié)構(gòu)樹的相似度來度量。求結(jié)構(gòu)樹S與T的最大匹配等價于求S與T的最大匹配節(jié)點(diǎn)
對集合。最后按照下式計(jì)算結(jié)構(gòu)相似度StrcutureSim。其中,StructureMatching (S, T)為
S與T的最大匹配節(jié)點(diǎn)對個數(shù),|S|為結(jié)構(gòu)樹S的節(jié)點(diǎn)總數(shù)。 StrcutureSim = StructureMatching(S, T)/|S| (2)語句匹配 結(jié)構(gòu)匹配過程中保留了類型相匹配的節(jié)點(diǎn)的信息,因此程序的語句匹配可以在程 序結(jié)構(gòu)匹配基礎(chǔ)上進(jìn)一步檢查語句、表達(dá)式的匹配情況。表達(dá)式的匹配通過遍歷兩個表達(dá) 式的抽象語法樹求得最大匹配,計(jì)算相似度,并將各語句的表達(dá)式相似度保存在源候選相 似代碼控制依賴樹S的各個節(jié)點(diǎn)中。最后,通過遍歷S獲得各個節(jié)點(diǎn)的表達(dá)式相似度value, 按照公式 StatementSim = E value (vi) / | S | 計(jì)算語句相似度StrtementS im ;其中,value (vi)為節(jié)點(diǎn)vi的求得的表達(dá)式相似 度,|S|為控制依賴樹S的節(jié)點(diǎn)總數(shù)。
權(quán)利要求
一種基于程序源代碼語義分析的代碼相似度檢測方法,其特征是它由以下步驟完成步驟一、分別將待檢測的兩段源代碼解析為兩棵系統(tǒng)依賴圖的控制依賴樹;步驟二、對步驟一獲得的兩棵控制依賴樹分別執(zhí)行基本代碼標(biāo)準(zhǔn)化,獲得兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴樹;步驟三、利用度量值方法分別提取步驟二獲得的兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴樹的候選相似代碼控制依賴樹;步驟四、判斷是否提取到候選相似代碼控制依賴樹,如果判斷結(jié)果為是,則執(zhí)行步驟五,如果結(jié)果為否,則結(jié)束兩段源代碼的相似度檢測;步驟五、對所述候選相似代碼控制依賴樹執(zhí)行高級代碼標(biāo)準(zhǔn)化操作;步驟六、計(jì)算候選相似代碼控制依賴樹的結(jié)構(gòu)相似度StructureSim和候選相似代碼控制依賴樹的語句相似度StatementSim,并根據(jù)公式SemanticSim=λstru*StructureSim+λstat*StatementSim計(jì)算候選相似代碼控制依賴樹的語義相似度,獲得語義相似度結(jié)果,完成代碼相似度檢測;式中λstru為結(jié)構(gòu)相似度的權(quán)值、λstat為語句相似度的權(quán)值。
2. 根據(jù)權(quán)利要求1所述的一種基于程序源代碼語義分析的代碼相似度檢測方法,其特 征在于步驟二中所述基本代碼標(biāo)準(zhǔn)化的方法為采用基于系統(tǒng)依賴圖的程序標(biāo)準(zhǔn)化方法對 步驟一所述控制依賴樹進(jìn)行結(jié)構(gòu)語義等價的基本代碼標(biāo)準(zhǔn)化轉(zhuǎn)換;所述基本代碼標(biāo)準(zhǔn)化轉(zhuǎn) 換包括復(fù)合表達(dá)式的標(biāo)準(zhǔn)化轉(zhuǎn)換、表達(dá)式的標(biāo)準(zhǔn)化轉(zhuǎn)換和基本控制結(jié)構(gòu)的標(biāo)準(zhǔn)化轉(zhuǎn)換。
3. 根據(jù)權(quán)利要求1所述的一種基于程序源代碼語義分析的代碼相似度檢測方法,其特 征在于提取步驟三中利用度量值方法分別提取兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴樹的候 選相似代碼控制依賴樹的方法為步驟A、分別在所述兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴樹上提取各模塊的規(guī)模、結(jié)構(gòu)和復(fù)雜度特征信息,并分別統(tǒng)計(jì)各個模塊的度量向量,獲得兩段代碼的度量向量集;所述度量 向量集包括節(jié)點(diǎn)個數(shù)、運(yùn)算符個數(shù)、選擇結(jié)構(gòu)個數(shù)、循環(huán)結(jié)構(gòu)個數(shù)、賦值節(jié)點(diǎn)個數(shù)、特殊數(shù) 據(jù)類型個數(shù)、控制依賴樹中最長路徑長度、系統(tǒng)函數(shù)調(diào)用個數(shù)、遞歸調(diào)用路徑長度和控制依 賴邊個數(shù);步驟B、將步驟A獲得兩段代碼的度量向量集,通過公式<formula>formula see original document page 2</formula>計(jì)算兩段代碼的度量向量集的相似度sim(v,v');式中i = 1,2,3,……,10 ;n = 10 ;步驟C、判斷步驟B獲得的度量向量的相似度sim(v, v')是否大于預(yù)先設(shè)定的度量向 量相似度閾值Tv,如果判斷結(jié)果為是,則提取此兩段代碼做為候選相似代碼;如果判斷結(jié)果 為否,則結(jié)束兩段源代碼相似度檢測。
4.根據(jù)權(quán)利要求1所述的一種基于程序源代碼語義分析的代碼相似度檢測方法,其特征在于步驟五中的高級代碼標(biāo)準(zhǔn)化的方法為分別對兩棵候選相似代碼控制依賴樹執(zhí)行標(biāo) 準(zhǔn)化轉(zhuǎn)換,所述標(biāo)準(zhǔn)化轉(zhuǎn)換包括高級控制結(jié)構(gòu)標(biāo)準(zhǔn)化、消除冗余代碼、變量重命名、語句重 排列和函數(shù)調(diào)用標(biāo)準(zhǔn)化。
5. 根據(jù)權(quán)利要求1所述的一種基于程序源代碼語義分析的代碼相似度檢測方法,其特 征在于步驟六中候選相似代碼控制依賴樹的結(jié)構(gòu)相似度StructureSim是根據(jù)公式StrcutureSim = StructureMatching(S, T)/|S|獲得的,式中S和T是兩棵候選相似代碼的結(jié)構(gòu)樹,StructureMatching (S, T)為S與 T的最大匹配節(jié)點(diǎn)對個數(shù),|S|為候選相似代碼的結(jié)構(gòu)樹S的節(jié)點(diǎn)總數(shù)。
6. 根據(jù)權(quán)利要求1所述的一種基于程序源代碼語義分析的代碼相似度檢測方法,其特 征在于步驟六中候選相似代碼控制依賴樹的語句相似度StatementSim是根據(jù)公式StatementSim = E value(vi)/|S|獲得的,式中S為候選相似代碼控制依賴樹,value (vi)為S中節(jié)點(diǎn)的表達(dá)式相似度, S I為候選相似代碼控制依賴樹S的節(jié)點(diǎn)總數(shù)。
全文摘要
一種基于程序源代碼語義分析的代碼相似度檢測方法,涉及計(jì)算機(jī)程序分析技術(shù)和計(jì)算機(jī)軟件的重復(fù)代碼檢測方法。它解決了現(xiàn)有的對語法表示不同但語義相似的代碼的相似度檢測準(zhǔn)確度低、計(jì)算復(fù)雜度高,以及無法實(shí)現(xiàn)大規(guī)模程序代碼相似度檢測的問題。它的方法為分別將待檢測的兩段源代碼解析為兩棵系統(tǒng)依賴圖的控制依賴樹,并分別執(zhí)行基本代碼標(biāo)準(zhǔn)化;利用度量值方法提取兩棵基本代碼標(biāo)準(zhǔn)化后的控制依賴樹的候選相似代碼控制依賴樹;對提取的候選相似代碼執(zhí)行高級代碼標(biāo)準(zhǔn)化操作;計(jì)算語義相似度,獲得相似度結(jié)果,完成代碼相似度檢測;本發(fā)明適用于源代碼剽竊檢測、軟件組件庫查詢、軟件缺陷檢測以及程序理解等場合。
文檔編號G06F17/30GK101697121SQ20091007309
公開日2010年4月21日 申請日期2009年10月26日 優(yōu)先權(quán)日2009年10月26日
發(fā)明者王宇穎, 王甜甜, 蘇小紅, 馬培軍 申請人:哈爾濱工業(yè)大學(xué);