本發(fā)明涉及一種基于文檔的庫(kù)函數(shù)的代碼模型的自動(dòng)合成方法,主要利用自然語(yǔ)言處理技術(shù)和自動(dòng)化測(cè)試技術(shù)來(lái)解決庫(kù)函數(shù)的代碼模型的自動(dòng)生成問(wèn)題,進(jìn)而提高其它程序分析技術(shù)的正確性和效率。屬于軟件工程、程序合成領(lǐng)域。
背景技術(shù):
在現(xiàn)代的程序中,類庫(kù)被廣泛使用,類庫(kù)的行為是軟件行為中不可分割的一部分,對(duì)軟件程序進(jìn)行分析的時(shí)候,這些類庫(kù)也應(yīng)該被分析。然而分析類庫(kù)是一件非常困難的事情,首先,在很多情況下,類庫(kù)的源代碼是無(wú)法獲取的。即使可以獲取源代碼,代碼通常也非常復(fù)雜,比如包含高度優(yōu)化的代碼、復(fù)雜的工程技巧,或者是由多種語(yǔ)言實(shí)現(xiàn),這一系列的原因都導(dǎo)致分析類庫(kù)源代碼非常困難。
目前有很多研究工作人工為類庫(kù)建立模型,通過(guò)對(duì)模型的分析來(lái)替代對(duì)類庫(kù)的分析。然而,人工建模不僅耗時(shí),而且容易出錯(cuò)。另外還有一些研究工作通過(guò)動(dòng)態(tài)執(zhí)行程序來(lái)跟蹤輸入輸出之間的關(guān)系,這種方法依賴于測(cè)試用例的充分度,而且輸入輸出之間的依賴關(guān)系無(wú)法反應(yīng)類庫(kù)的精確行為。
技術(shù)實(shí)現(xiàn)要素:
技術(shù)問(wèn)題:類庫(kù)的文檔中通常包含了豐富的信息,描述了類庫(kù)的行為,因此,本發(fā)明的目標(biāo)是從文檔中抽取有用信息,根據(jù)這些信息,綜合使用自然語(yǔ)言處理技術(shù)與自動(dòng)化測(cè)試技術(shù)為類庫(kù)自動(dòng)生成代碼模型。代碼模型模擬了類庫(kù)的行為,解決了程序分析過(guò)程中由于源代碼缺失或者源代碼過(guò)于復(fù)雜導(dǎo)致難以分析等問(wèn)題,有效地提高其它程序分析技術(shù)的有效性和效率。
技術(shù)方案:給定一個(gè)Java API函數(shù),本發(fā)明使用自然語(yǔ)言處理工具生成每個(gè)句子的語(yǔ)法樹,然后在語(yǔ)法樹中識(shí)別參數(shù)和程序結(jié)構(gòu)生成樹結(jié)構(gòu)形式的中間表示,接著將中間表示與預(yù)定義的一組原語(yǔ)的樹模板進(jìn)行匹配,每個(gè)原語(yǔ)是由一個(gè)樹模板以及該樹模板所對(duì)應(yīng)的代碼模板組成。在匹配過(guò)程中,本發(fā)明嘗試用若干個(gè)原語(yǔ)的樹模板對(duì)中間表示進(jìn)行覆蓋,當(dāng)找到合適的樹模板將中間表示覆蓋完全后,使用中間表示中對(duì)應(yīng)的節(jié)點(diǎn)信息來(lái)實(shí)例化樹模板中的節(jié)點(diǎn),實(shí)例化的結(jié)果是與樹模板匹配的子樹所對(duì)應(yīng)的代碼片段,將這些代碼片段組合起來(lái)生成一個(gè)代碼模型。由于自然語(yǔ)言的二義性以及參數(shù)識(shí)別過(guò)程中的不確定性等,每個(gè)句子可能對(duì)應(yīng)多個(gè)中間表示,此外,每個(gè)中間表示可能有多個(gè)覆蓋方法,因此可能生成多個(gè)候選的代碼模型,本發(fā)明使用測(cè)試技術(shù)過(guò)濾掉與原始的類庫(kù)具有行為不一致的候選模型。本方法包括以下步驟:
步驟1:從文檔中抽取類和函數(shù)的描述信息,例如函數(shù)的聲明、函數(shù)的行為描述等。
步驟2:對(duì)步驟1抽取的信息進(jìn)行等價(jià)分析、冗余信息刪除以及語(yǔ)句增強(qiáng)。
步驟3:使用自然語(yǔ)言處理工具為經(jīng)過(guò)步驟2處理的每一個(gè)自然語(yǔ)言句子生成一棵語(yǔ)法樹,這棵樹給出了每個(gè)單詞的詞性,同時(shí)標(biāo)記了不同的短語(yǔ)。
步驟4:將步驟3生成的語(yǔ)法樹進(jìn)行節(jié)點(diǎn)變換生成多個(gè)變體,不同變體表示不同的語(yǔ)義。
步驟5:識(shí)別步驟4中生成的語(yǔ)法樹中表示參數(shù)的節(jié)點(diǎn)以及從語(yǔ)法樹中識(shí)別出程序的結(jié)構(gòu),即循環(huán)結(jié)構(gòu)和分支結(jié)構(gòu),為語(yǔ)法樹生成相應(yīng)的中間表示。
步驟6:結(jié)合給定的原語(yǔ),為步驟5生成的中間表示合成對(duì)應(yīng)的代碼片段,然后將一個(gè)函數(shù)的所有中間表示對(duì)應(yīng)的代碼片段組合起來(lái)生成每一個(gè)函數(shù)的模型,然后將不同函數(shù)的模型組合起來(lái)生成類的模型。
步驟7:使用測(cè)試工具對(duì)步驟6生成的候選的代碼模型進(jìn)行測(cè)試,過(guò)濾那些與類庫(kù)具有行為不一致的候選模型。
有益效果:本發(fā)明所述的基于文檔的庫(kù)函數(shù)的代碼模型的自動(dòng)構(gòu)造方法所生成的代碼模型模擬了類庫(kù)的行為,模型的代碼實(shí)現(xiàn)更加簡(jiǎn)單,復(fù)雜性低,不會(huì)調(diào)用本地方法等,代碼模型的平均代碼行數(shù)是原始類庫(kù)中函數(shù)的1/3,而且調(diào)用函數(shù)簡(jiǎn)潔清晰。代碼模型可以有效地輔助其它程序分析技術(shù),比如庫(kù)函數(shù)的規(guī)約生成技術(shù)、靜態(tài)污點(diǎn)分析技術(shù)以及動(dòng)態(tài)切片技術(shù)等。具體而言:
(1)將生成的代碼模型應(yīng)用于靜態(tài)污點(diǎn)分析技術(shù)中,結(jié)果顯示使用代碼模型可以有效地提高靜態(tài)污點(diǎn)分析的正確性,發(fā)現(xiàn)一些使用源代碼無(wú)法發(fā)現(xiàn)的信息泄露路徑,同時(shí)還可以提高分析的效率。
(2)將生成的代碼模型應(yīng)用于動(dòng)態(tài)切片技術(shù)中,結(jié)果顯示使用代碼模型生成的切片大小遠(yuǎn)遠(yuǎn)小于使用樸素模型所生成的切片大小,而且還可以提高分析的效率,這主要得益于代碼模型提供了函數(shù)功能的簡(jiǎn)單而準(zhǔn)確的實(shí)現(xiàn),對(duì)代碼模型進(jìn)行分析時(shí)可以得到輸出與輸入之間的精確的依賴關(guān)系,而樸素模型的依賴關(guān)系過(guò)多而且很多是不準(zhǔn)確的。
附圖說(shuō)明
圖1是基于文檔的庫(kù)函數(shù)的代碼模型的自動(dòng)構(gòu)造方法的流程圖。
圖2是本發(fā)明實(shí)施例的ArrayList類中indexof方法的文檔示例圖。
圖3是本發(fā)明實(shí)施例的語(yǔ)法樹圖一。
圖4是本發(fā)明實(shí)施例的語(yǔ)法樹圖二。
圖5是本發(fā)明實(shí)施例的語(yǔ)法樹圖三。
圖6是本發(fā)明實(shí)施例的中間表示示意圖。
圖7是本發(fā)明實(shí)施例的覆蓋示意圖。
圖8是本發(fā)明實(shí)施例的代碼片段。
具體實(shí)施方式
下面結(jié)合實(shí)施例和說(shuō)明書附圖對(duì)本發(fā)明做進(jìn)一步說(shuō)明。
圖1是基于文檔的庫(kù)函數(shù)的代碼模型的自動(dòng)構(gòu)造方法的流程圖。本實(shí)施例給出了一種基于文檔的庫(kù)函數(shù)的代碼模型的自動(dòng)合成方法。包括如下步驟:1.從文檔中抽取有用信息;2.對(duì)抽取的描述語(yǔ)句進(jìn)行預(yù)處理。3.使用自然語(yǔ)言處理工具生成句子的語(yǔ)法樹;4.對(duì)步驟3中生成的語(yǔ)法樹進(jìn)行結(jié)構(gòu)上的變換生成多個(gè)語(yǔ)法樹的變體;5.對(duì)步驟4中生成的語(yǔ)法樹進(jìn)行分析,識(shí)別其中的參數(shù)、程序結(jié)構(gòu)以及操作語(yǔ)義的中間表示;6.生成候選的代碼模型;7.對(duì)步驟6中的候選模型進(jìn)行檢驗(yàn),刪除與原始的類庫(kù)具有行為不一致的候選模型。本發(fā)明綜合使用了自然語(yǔ)言處理技術(shù)與自動(dòng)化測(cè)試技術(shù),成功地為Java容器類生成了代碼模型,生成的代碼模型可以有效地提高其它程序分析技術(shù)的正確性和效率,解決了程序分析過(guò)程中由于類庫(kù)源代碼缺失或者類庫(kù)源代碼過(guò)于復(fù)雜導(dǎo)致難以分析等問(wèn)題。
本實(shí)施例通過(guò)圖2中展示的ArrayList類中indexof方法的文檔為例進(jìn)行詳細(xì)說(shuō)明。
一.從文檔中抽取信息
在具體實(shí)施中,本發(fā)明以HTML格式的Javadoc文檔作為輸入,從中抽取類的信息和函數(shù)的信息。針對(duì)類,主要提取包名和類的聲明。針對(duì)函數(shù),主要抽取(1)函數(shù)的聲明;(2)參數(shù)名以及相應(yīng)的解釋部分;(3)描述函數(shù)行為的語(yǔ)句;(4)描述函數(shù)返回值的語(yǔ)句;(5)描述函數(shù)拋出的異常以及拋出異常的條件。
二.預(yù)處理
本發(fā)明對(duì)抽取的描述語(yǔ)句進(jìn)行預(yù)處理,主要包括下面三個(gè)方面:
(1)等價(jià)分析:將詞語(yǔ)按照領(lǐng)域字典進(jìn)行等價(jià)類的劃分,以減少重復(fù)處理。例如,在函數(shù)的行為描述中,insert和add是語(yǔ)義等價(jià)的。
(2)刪除冗余信息:嘗試刪除用于解釋其它語(yǔ)句的句子。例如,圖2中以“more formally”開頭的句子是進(jìn)一步解釋其前面的句子。
(3)增強(qiáng)語(yǔ)句:在Javadoc中的返回值描述和異常描述中的語(yǔ)句往往是不完整的,本發(fā)明嘗試將這類語(yǔ)句補(bǔ)充完整。
三.為自然語(yǔ)言句子生成語(yǔ)法樹
本發(fā)明使用自然語(yǔ)言處理工具Stanford Parser為每一個(gè)經(jīng)過(guò)預(yù)處理的句子生成語(yǔ)法樹,識(shí)別出句子中單詞的詞性、短語(yǔ)結(jié)構(gòu)等。有些單詞在計(jì)算機(jī)領(lǐng)域中具有固定的詞性,但是Stanford Parser并不具備領(lǐng)域知識(shí),因此,本發(fā)明開發(fā)了一個(gè)詞性限制模塊,引導(dǎo)Stanford Parser將和計(jì)算機(jī)程序領(lǐng)域相關(guān)的詞匯標(biāo)記為期望的詞性。針對(duì)圖2中的句子“Returns the index of the first occurrence of the specified element in this list,or-1if this list does not contain the element”,Stanford Parser將為其生成圖3所示的語(yǔ)法樹。
四.變換語(yǔ)法樹結(jié)構(gòu)生成多個(gè)變體
本發(fā)明將Stanford Parser生成的語(yǔ)法樹進(jìn)行結(jié)構(gòu)的變換生成不同的變體,每個(gè)變體表示不同的語(yǔ)義。
為了解決自然語(yǔ)言的模糊性,當(dāng)用戶指定一個(gè)數(shù)值K時(shí),Stanford Parser返回K棵不同語(yǔ)義的語(yǔ)法樹。如果將K的值設(shè)置的很大來(lái)提高生成正確語(yǔ)法樹的概率,那么將花費(fèi)大量的時(shí)間來(lái)分析語(yǔ)法樹,會(huì)帶來(lái)性能問(wèn)題。而且,即使K的值很大,也無(wú)法保證一定可以生成正確的語(yǔ)法樹。
本發(fā)明所分析的句子屬于一類特定的領(lǐng)域,通過(guò)對(duì)語(yǔ)法樹進(jìn)行結(jié)構(gòu)上的變換可以得到表達(dá)正確語(yǔ)義的語(yǔ)法樹。當(dāng)句子中出現(xiàn)“,or”或者“,and”時(shí),往往會(huì)出現(xiàn)歧義。針對(duì)這種情況,本發(fā)明通過(guò)將概率最高的語(yǔ)法樹中的“,or”或者“,and”以及所有的右兄弟節(jié)點(diǎn)向上移動(dòng)或者向下移動(dòng)若干次來(lái)生成正確的語(yǔ)法樹。針對(duì)圖3中的語(yǔ)法樹,本發(fā)明將通過(guò)將“,”、“or”以及“-1if this list does not contain the element”節(jié)點(diǎn)向上移動(dòng)五次可以得到圖4所示的語(yǔ)法樹,圖4中的語(yǔ)法樹是這個(gè)句子真正想要表達(dá)的語(yǔ)義。
五.生成中間表示
本發(fā)明將根據(jù)領(lǐng)域知識(shí)在語(yǔ)法樹中識(shí)別出參數(shù)和程序結(jié)構(gòu)來(lái)構(gòu)造樹結(jié)構(gòu)形式的中間表示。
(1)識(shí)別參數(shù)
文檔對(duì)參數(shù)的描述并不是雜亂無(wú)章的,而是有規(guī)律可循的。因此,本發(fā)明根據(jù)規(guī)則在句子中識(shí)別出參數(shù)的載體。鑒于自然語(yǔ)言的這種模糊性,當(dāng)系統(tǒng)無(wú)法確定單詞或者詞組是否描述的是參數(shù)時(shí),系統(tǒng)將分兩種情況進(jìn)行建模,一種情況將描述視為參數(shù),另一種情況認(rèn)為描述的并非參數(shù),由最后一步的模型過(guò)濾器排除錯(cuò)誤的情況。針對(duì)圖4中的語(yǔ)法樹,本發(fā)明將“the specified element”與參數(shù)o關(guān)聯(lián)起來(lái),而本發(fā)明在這一步中無(wú)法確定“the element”是否描述的是參數(shù)o,因此,本發(fā)明將兩種可能的情況均視為候選。
在Javadoc中,當(dāng)出現(xiàn)詞組“this WORD”,而“WORD”又是當(dāng)前所處理的類的名字或者類名的縮寫時(shí),本發(fā)明將給這棵子樹添加“this”標(biāo)簽。這個(gè)標(biāo)簽代表這個(gè)操作的對(duì)象是執(zhí)行該操作的實(shí)例。例如,在圖4中出現(xiàn)的“this list”,它表示操作是針對(duì)類java.util.ArrayList的對(duì)象的。
經(jīng)過(guò)參數(shù)的識(shí)別之后,本發(fā)明將圖4中的語(yǔ)法樹變換為圖5中的語(yǔ)法樹。
(2)識(shí)別程序結(jié)構(gòu)
在缺省情況下,本發(fā)明將默認(rèn)程序語(yǔ)句是按照順序依次執(zhí)行的,因此,本發(fā)明只在語(yǔ)法樹中識(shí)別循環(huán)結(jié)構(gòu)和分支結(jié)構(gòu)。
針對(duì)循環(huán)結(jié)構(gòu),在自然語(yǔ)言中,復(fù)數(shù)名詞以及用each修飾的單數(shù)名詞往往表示句子所描述的行為將被重復(fù)執(zhí)行多次,因此需要一個(gè)循環(huán)結(jié)構(gòu)。但有些時(shí)候,循環(huán)并沒(méi)有這么明顯。例如,“the first occurrence of”這個(gè)短語(yǔ)暗示了循環(huán)迭代的順序,這時(shí)也需要一個(gè)循環(huán)結(jié)構(gòu),本發(fā)明將在語(yǔ)法樹的節(jié)點(diǎn)中添加“l(fā)tr”(left to right)標(biāo)簽,同時(shí)將表示“the first occurrence of”的子樹刪除。
對(duì)于分支結(jié)構(gòu)而言,單詞“if”和“when”表示一個(gè)if分支,“otherwise”表示一個(gè)else分支。本發(fā)明將添加相應(yīng)的標(biāo)簽(“if”和“else”)到對(duì)應(yīng)的子樹并刪除中間表示。針對(duì)圖5中的語(yǔ)法樹,本發(fā)明將點(diǎn)中并刪除表示“if”的節(jié)點(diǎn),生成圖6中所示的“-1tag:if”節(jié)點(diǎn)。需要注意的是,本發(fā)明同時(shí)仔細(xì)判斷了條件描述是肯定的還是否定的從而決定if條件。圖5中的“contain”是被“does not”修飾的,這表示該if分支中包含的行為是在“contain”行為結(jié)果的相反情況下觸發(fā)的,在這種情況下,本發(fā)明刪除表示“does not”的子樹并在表示“contain”的樹節(jié)點(diǎn)中添加標(biāo)簽“-”,如圖6中的“contain:-”節(jié)點(diǎn)。
經(jīng)過(guò)程序結(jié)構(gòu)的識(shí)別之后,本發(fā)明根據(jù)圖5中所示的語(yǔ)法樹生成圖6中的中間表示。
六.生成候選的代碼模型
本發(fā)明在中間表示中識(shí)別操作語(yǔ)義生成候選的代碼模型。本發(fā)明定義了一些原語(yǔ),每個(gè)原語(yǔ)包含一個(gè)樹模板和樹模板對(duì)應(yīng)的代碼模板。本發(fā)明從中間表示的根節(jié)點(diǎn)開始,使用樹模板對(duì)中間表示進(jìn)行覆蓋,當(dāng)中間表示被覆蓋完全后,本發(fā)明將這些樹模板對(duì)應(yīng)的代碼模型進(jìn)行實(shí)例化來(lái)生成中間表示對(duì)應(yīng)的代碼片段。針對(duì)圖6中的中間表示,本發(fā)明將為其生成圖7所示的覆蓋和圖8所示的代碼片段。當(dāng)生成了每個(gè)中間表示的代碼片段之后,本發(fā)明將每個(gè)函數(shù)的文檔中所有句子的中間表示的代碼片段進(jìn)行組合生成函數(shù)的代碼模型,接著將各個(gè)函數(shù)的代碼模型進(jìn)行組合生成類的代碼模型。一個(gè)句子可能有多個(gè)中間表示,因此,本發(fā)明可能為一個(gè)函數(shù)生成多個(gè)代碼模型,同樣地,也可能為一個(gè)類生成多個(gè)代碼模型。
七.刪除錯(cuò)誤的候選模型
并不是所有的語(yǔ)法樹都表示了正確的語(yǔ)義,因此,本發(fā)明將使用測(cè)試技術(shù)來(lái)過(guò)濾掉錯(cuò)誤的代碼模型。對(duì)于任意的候選類模型,本發(fā)明首先對(duì)其進(jìn)行編譯并使用Randoop工具為其生成單元測(cè)試用例,這些測(cè)試用例體現(xiàn)了候選類模型的行為。然后,在原始的JDK類庫(kù)上運(yùn)行這些測(cè)試用例。如果有一個(gè)測(cè)試用例失敗,這就意味著候選的類模型和原始的類庫(kù)存在行為不一致,那么本發(fā)明就將該候選類模型舍棄。如果某個(gè)候選的類模型的測(cè)試用例全部通過(guò),那么本發(fā)明認(rèn)為該候選是所期望的類庫(kù)的代碼模型。
本發(fā)明已以較佳實(shí)施例公開如上,但它們并不是用來(lái)限定本發(fā)明,凡不脫離本發(fā)明之精神和范圍內(nèi),自當(dāng)可作各種變化或潤(rùn)飾,因此本發(fā)明的保護(hù)范圍應(yīng)當(dāng)以本申請(qǐng)的權(quán)利要求保護(hù)范圍所界定的為準(zhǔn)。