本發(fā)明涉及函數注釋自動生成技術,特別涉及文本處理技術和數據挖掘中信息采集領域的web數據爬取技術,提出了一種基于數據挖掘的源代碼注釋自動生成方法。
背景技術:
注釋是為了提高源碼可讀性而編寫的對應源代碼的自然語言文本描述,主要目的是為了輔助程序員進行代碼理解,提高軟件系統的可維護性。優(yōu)秀的軟件項目需要有高質量的代碼和準確、全面的注釋及文檔。由于目前大部分開源項目軟件周期短,例如Linux內核作為優(yōu)秀的開源項目,其應用和影響都非常廣泛,但其注釋的覆蓋程度遠不能滿足學習及初級開發(fā)人員的需求。同時目前大部分開源軟件版本更新迅速,而且版本更新有越來越快的趨勢,對應的注釋不能隨版本更迭及時更新。因此,開源軟件的代碼和注釋之間存在注釋覆蓋低等數量方面的問題,同時也存在由于版本更新導致注釋信息更新滯后而不準確、不完整等質量方面的問題。然而互聯網上相關開源軟件的開發(fā)和維護的公開信息龐大且繁雜、良莠不齊、難于區(qū)分,對于學習和開發(fā)輔助作用有限且資料的搜集和甄別工作量較大。
源代碼注釋一般由有經驗的程序員手工編寫,人工注釋的困難促進了自動注釋方法的研究。目前自動注釋技術的研究多致力于利用源碼語義自動生成自然語言注釋,其多數針對面向對象語言,涉及語法分析、語義分析等十分復雜的技術,還有一些技術致力于構建復雜的模型,技術難度大,實現困難。
技術實現要素:
針對上述問題,本發(fā)明的目的在于提供一種基于數據挖掘的源代碼注釋自動生成方法。通過這種方法可以快捷的自動生成Linux內核函數的整體注釋,注釋涉及函數功能、設計場景、使用方式、或針對不同版本的特性。所述方法填補了linux內核自動注釋技術的空白,為Linux內核學習和開發(fā)人員提供更多的參考信息,有效降低初級開發(fā)人員的工作量和難度。
為了實現上述目的,本發(fā)明采用以下技術方案:
一種基于數據挖掘的源代碼注釋自動生成方法,包括以下步驟:
1)分別從三種數據源中爬取與Linux內核函數相關的描述信息,所述三種數據源為Stack Overflow網站、Linux kernel郵件和Linuxkernel Commit-log;
2)對步驟1)中得到的描述信息進行預處理,獲取可能作為注釋的文本,所述預處理包括文本格式處理及剔除無關Linux內核描述的噪聲信息;
3)概括函數注釋自然文本關鍵的特性作為提取規(guī)則,對步驟2)預處理后獲取到的文本進行提取,自動生成函數整體注釋。
進一步地,步驟1)中使用數據挖掘信息采集領域的web數據爬取技術分別從三種數據源中爬取與Linux內核函數相關的描述信息。web數據爬取指根據URL下載網頁內容,針對不同網頁的HTML結構特征,利用正則表達式或者其他的方式進行文本分析,提取所需的目標文本。
進一步地,步驟1)包括:從Stack Overflow網站獲取編程人員對指定函數討論的信息、從Linux kernel郵件獲取內核開發(fā)人員的開發(fā)過程郵件信息、從Linux kernel Commit-log獲取開發(fā)人員提交代碼的Commit-log信息,將全部數據分類存儲于數據庫。
進一步地,從Stack Overflow網站獲取編程人員對指定函數討論的信息的具體步驟如下:
1-1-1)在Stack Overflow網站的搜索頁面輸入“Linux+目標函數名稱”搜索,得到目標函數話題列表的URL,爬取此頁的HTML文件內容;
1-1-2)對步驟1-1-1)爬取的HTML文件內容進行解析,獲取該網頁中多個問題的URL鏈接并爬取其子HTML文件內容;
1-1-3)對步驟1-1-2)爬取的多個問題的子HTML文件內容,提取出網頁中的問題標題、問題標號、投票數、問題描述和答案分類存儲于數據庫中。
進一步地,按照時間段分隔的郵件服務器http://lkml.iu.edu/hypermail/linux/kernel進行郵件的爬取,從Linux kernel郵件獲取內核開發(fā)人員的開發(fā)過程郵件信息,具體步驟如下:
1-2-1)選取某一時間段為目標,得到的該時間段郵件列表的URL,爬取此頁的HTML文件;
1-2-2)對步驟1-2-1)爬取的HTML文件進行解析,獲取該時間段內的所有郵件的URL鏈接并爬取其HTML文件;
1-2-3)對步驟1-2-2)爬取的所有郵件的HTML文件,提取出網頁中郵件的標題和正文(即Body-of-Message標簽中的內容)存儲于數據庫中。
進一步地,從Linux kernel Commit-log獲取開發(fā)人員提交代碼的Commit-log信息的具體步驟如下:
1-3-1)根據用戶指定的起始版本獲取第一個要爬取的show頁面的URL;
1-3-2)爬取show頁面的HTML文檔,解析HTML文檔獲取commit log正文與標題存入數據庫,并拼接next頁面的URL;
1-3-3)在標題中查找終止版本的標識,如果找到則結束爬取,否則返回步驟1-3-2)繼續(xù)next頁面。
進一步地,步驟2)中所述文本格式處理包括:將從三種數據源中爬取的描述信息以空行為分隔符,將文本分成備選注釋段落并去除HTML標簽。
進一步地,步驟2)中分別針對三種數據源形成三種對應的過濾規(guī)則,從步驟1)中得到的描述信息中剔除無關Linux內核描述的噪聲信息。
進一步地,針對Stack Overflow網站形成的過濾規(guī)則為:如果問題的投票小于1,刪除問題及對應答案的所有段落;如果問題的投票大于1,刪除對應答案中小于1的答案的所有段落;針對Linux kernel郵件形成的過濾規(guī)則為:以關鍵字"+"、"WARING"、"ERROR"、"#good"、"#bad"為條件剔除郵件中包含調用棧信息、告警、錯誤、補丁等的段落;針對Linux kernel Commit-log形成的過濾規(guī)則為:對于Commit-log正文以關鍵字"==="、"Fix"、"Signed-off-by"為條件剔除commit-log特有的無關函數注釋的內容。
進一步地,從步驟1)中得到的描述信息中剔除無關Linux內核描述的噪聲信息包括:按照針對Stack Overflow網站形成的過濾規(guī)則,剔除從Stack Overflow網站爬取的描述信息中投票小于1的段落;按照針對Linux kernel郵件形成的過濾規(guī)則,剔除郵件特有的不適注釋的段落;按照針對Linux kernel Commit-log形成的過濾規(guī)則剔除Commit-log特有的不適注釋的段落。
進一步地,步驟3)中所述提取規(guī)則具體包括:
提取規(guī)則1:對函數進行注釋說明的文字,通常包含如下關鍵字中的一個或幾個:
"函數名字+()"、"function"、"methord"、"return"、"call"、"execute"、"invoke";
提取規(guī)則2:對于函數的描述性語言中包含如下關鍵字的句子,一般不能作為函數的注釋性文本:
no,not,error,bug,difficult,difficulty,problem,problems,fix,shouldn’t,doesn’t,can’t,couldn’t,don’t,isn’t,aren’t,wouldn’t,fail,why,what,null,bad,wrong,missing,lack,probably,likely,perhaps,think,may,maybe,unfortunately,unluckily。
進一步地,步驟3)具體包括:
3-1)按提取規(guī)則1提取段落。
3-2)將提取得到的段落分成句子。
3-3)按提取規(guī)則2過濾句子,如有剩余,自動生成的函數注釋。
本發(fā)明提出的新方法涉及從三種各具特色的數據源提取文本,自動生成Linux內核函數注釋,同理也可擴展形成其他開源軟件的注釋自動生成方法。所述方法以三種不同特性的資源:Stack Overflow網站、Linux kernel郵件、Linux kernel Commit-log為數據源(下文簡稱三種資源)自動生成注釋。其中,StackOverflow是知名的編程問題問答網站,從中獲取的信息能夠在函數功能、設計場景、使用方式等多維度對函數進行注釋說明;Linux內核郵件數據量巨大,每天可以達到200至400封,并且能夠提供可靠、權威的信息;Linux內核Commit-log以版本的更迭為組織方式,其信息具有版本特性。注釋自動生成的方式采取在研究大量注釋的基礎上,總結函數注釋一般規(guī)則進行提取。以這三種數據為源提取的注釋能夠豐富傳統函數注釋,提供多維度的信息且關注版本的更迭,能夠以相對小的代價提供可讀性好且相對可靠的函數注釋信息。為學習和開發(fā)者提供更多的參考信息,提升學習和開發(fā)效率。所述方法不需要進行代價較高的源碼分析、復雜的模型構建,即可快速實現函數注釋的自動生成,并支持持續(xù)的linux內核版本的更新中增量注釋的自動生成。
附圖說明
圖1是基于數據挖掘的的源代碼注釋自動生成方法的整體流程圖。
圖2是數據獲取與存儲的流程圖。
圖3是數據預處理的流程圖。
圖4是按規(guī)則生成注釋的流程圖。
具體實施方式
本發(fā)明的基于數據挖掘的的源代碼注釋自動生成方法,包括三部分。如圖1所示,第一部分是數據獲取與存儲,第二部分是數據預處理,第三部分按規(guī)則生成注釋。具體描述如下:
1)數據的獲取與存儲
對于三種資源的不同數據特征,為獲取所需目標文本,需要根據各自的特性制定不同的爬取策略。
1a)問答網站Stack Overflow
Stack Overflow是針對編程問題的專業(yè)問答網站,用戶可以在網站提交問題、瀏覽問題、搜索相關問答內容。問題的內容涉及廣泛,常包括函數的用法、設計背景等多個方面。本方法以Linux內核函數為關鍵字進行搜索,可以得到關于函數的功能、設計場景、使用等不同方面的問題和答案。這些問題和答案將作為生成注釋的原材料存入數據庫中。具體步驟如下:
i.在Stack Overflow網站的搜索頁面輸入“Linux+目標函數名稱”搜索,得到目標函數話題列表的URL,爬取此頁的HTML文件內容;
ii.對i步驟獲取的HTML頁面進行解析,獲取該網頁中多個問題的URL鏈接并爬取子HTML文件內容;
iii.對ii步驟爬取的多個問題的HTML頁面,提取出網頁中的問題標題、問題標號、投票數、問題描述和答案分類存于數據庫中。
1b)Linux kernel郵件
Linux開發(fā)過程中的郵件按照不同的方式存于多個不同的服務器中,Linux kernel郵件是Linux內核開發(fā)人員的官方交流平臺,郵件內容常包括補丁的提交、審查、版本發(fā)布、技術交流等內容,每日的數據量非常龐大。本方法選取按照時間段分隔的郵件服務器http://lkml.iu.edu/hypermail/linux/kernel進行郵件的爬取。具體步驟如下:
i.選取某一時間段為目標,得到的該時間段郵件列表的URL,爬取此頁的HTML文件;
ii.對i步驟獲取的HTML進行解析,獲取該時間段內的所有郵件的URL鏈接并爬取HTML文件;
iii.對ii步驟爬取的郵件HTML頁面,提取出網頁中郵件正文即Body-of-Message標簽中的內容存于數據庫中。
1c)Linux kernel Commit-log
Linux kernel Commit-log是記錄Linux內核開發(fā)人員每一次對內核代碼提交的日志,通常包括兩類補丁代碼和對應的新特性代碼說明、Bug修復代碼說明等,其內容隨內核版本的演進在持續(xù)的同步更新。存放于代碼庫中的Commit-log信息對應于不同的版本,本方法爬取任意兩個版本之間的Commit-log信息為生成對應版本的函數注釋提供原材料。具體步驟如下:
i.根據起始版本獲取第一個要爬取show頁面URL;
ii.爬取show頁面HTML,解析HTML文檔獲取commit log正文與標題存入數據庫,并拼接next頁面的URL;
iii.在標題中查找終止版本的標識,如果找到則結束爬取,否則返回步驟ii繼續(xù)next頁面。
2)數據預處理
不同的數據源包含不同樣式的信息和不同的組織形式,所述方法首先將三種資源爬取的數據庫內容文本以空行為分隔符,將文本分成備選注釋段落并去除HTML標簽。然后在研究各數據源特性的基礎上,對Stack Overflow網站數據、Linux kernel郵件數據和Linux kernel Commit-log數據制定特有的三種過濾規(guī)則,利用過濾規(guī)則剔除無關Linux內核函數描述的噪聲信息。
2a)Stack Overflow網站數據
過濾規(guī)則1:如果問題的投票小于1,刪除問題及對應答案的所有段落;如果問題的投票大于1,刪除對應答案中小于1的答案的所有段落。
2b)Linux kernel郵件數據
過濾規(guī)則2:以關鍵字"+"、"WARING"、"ERROR"、"#good"、"#bad"為條件剔除郵件中常包含的調用棧信息、告警、錯誤、補丁等段落。
2c)Linux kernel Commit-log數據
過濾規(guī)則3:對于Commit-log正文以關鍵字"==="、"Fix"、"Signed-off-by"為條件剔除commit-log特有的無關函數注釋的內容;
3)按規(guī)則生成注釋
所述方法在研究大量函數注釋的基礎上,概括人工函數注釋自然文本關鍵的特性,以此特性制定生成函數注釋的兩種提取規(guī)則。具體包括:
3a)提取規(guī)則1:對函數進行注釋說明的文字,通常包含如下關鍵字中的一個或幾個:
"函數名字+()"、"function"、"methord"、"return"、"call"、"execute"、"invoke";
3b)提取規(guī)則2:對于函數的描述性語言中包含如下關鍵字的句子,一般不能作為函數的注釋性文本:
no,not,error,bug,difficult,difficulty,problem,problems,fix,shouldn’t,doesn’t,can’t,couldn’t,don’t,isn’t,aren’t,wouldn’t,fail,why,what,null,bad,wrong,missing,lack,probably,likely,perhaps,think,may,maybe,unfortunately,unluckily。
本發(fā)明方案的具體的步驟如下:
1)數據獲取與存儲,圖2是數據獲取與存儲流程圖,包括:
1a)進入注釋自動生成系統,選擇生成注釋的數據源。
1b)如果選擇Stack Overflow,則進入1c);選擇Linux kernel郵件,則進入1d);選擇Linux kernle Commit-log則進入1e)。
1c)按照對問答網站Stack Overflow制定的爬取策略,爬取指定函數討論的信息并存儲,進入1f)。
1d)按照對Linux kernel郵件制定的爬取策略,爬取郵件信息并存儲,進入1f)。
1e)按照對Linux kernel Commit-log制定的爬取策略,爬取Commit-log信息并存儲,進入1f)。
1f)進行數據預處理。
2)數據預處理,圖3是數據預處理流程圖,包括:
2a)進入數據預處理,以空行為分隔將數據分成段落,進入2b)。
2b)剔除數據中的HTML標簽,進入2c)。
2c)判斷數據源類型,如果是Stack Overflow網站數據源,則進入2d);如果是Linux kernel郵件數據源,則進入2e);如果是Linux kernle Commit-log數據源,則進入2f)。
2d)按照過濾規(guī)則1,剔除Stack Overflow數據中投票小于1的段落,進入2g)。
2e)按照過濾規(guī)則2,剔除郵件特有的不適注釋的段落,進入2g)。
2f)按照過濾規(guī)則3,剔除Commit-log特有的不適注釋的段落,進入2g)。
2g)進行注釋提取。
3)按規(guī)則生成注釋,圖4是按規(guī)則生成注釋流程圖,包括:
3a)進入注釋提取,按提取規(guī)則1提取段落,如果能提取出段落,進入3b),否則進入3e)。
3b)將段落分成句子,則進入3c)。
3c)按提取規(guī)則2過濾句子。如果剩余句子,進入3d),否則進入3e)。
3d)展示自動生成的函數注釋并存儲,進入3e)。
3e)結束。
下面通過實施例對本發(fā)明作進一步的說明,但不以任何方式限制本發(fā)明的范圍。
實施例1
本實施例設定如下使用場景:
使用Stack Overflow網站數據源,應用本方法自動生成對fork()函數的注釋。
1)進入注釋自動生成系統,選取Stack Overflow數據源,對關鍵字"linux fork()"進行搜索,爬取所得網頁的內容,獲取15個話題的對應文本。其中一個話題內容如下:
問題標號:12881111
問題標題:Output offock()calls
問題描述:
What would be the output offollowing fork()call?
fork(){
fork();
fork();
fork()&&fork()||fork();
fork();
Print(“Saikacollection\n”);
Can anyone help me in getting the answer to this code as well as some explanations as i am newto OS?I have found several questions on fork()on SO,but couldn’t figure out.
問題投票數:1
回答1:On succeed execution of a fork()call,new child is created.The process creating the child is called parent process.Fork()call returns pid(process identifier)ofthe child to parent.Fork()returns 0to the child process.
回答1投票:16
回答2:If you want new process to be more independent,you might take a look at exec-*family of funcitons(POSIX)-so you can fork,and then immediately replace the fork process(you can do it,since newly forked process is controlled by you);Or possibly have a look at popen()as well.
回答2投票:0
2)對爬取的數據進行預處理,刪除投票小于一的回答段落,得到文本如下:
文本1:What would be the output offollowing fork()call?
fork(){
fork();
fork();
fork()&&fork()||fork();
fork();
Print(“Saikacollection\n”);
Can anyone help me in getting the answer to this code as well as some explanations as i am newto OS?I have found several questions on fork()on SO,but couldn’t figure out.
文本2:On succeed execution of a fork()call,new child is created.The process creating the child is called parent process.Fork()call returns pid(process identifier)ofthe child to parent.Fork()returns 0to the child process.
3)經過規(guī)則1的應用,上述步驟中的兩段文本將被提取出來作為注釋的備選段落;經過規(guī)則2的應用,文本1中的句子將被濾除,生成注釋如下:
On succeed execution of a fork()call,new child is created.The process creating the child is called parent process.Fork()call returns pid(process identifier)of the child to parent.Fork()returns 0to the child process.
該注釋對fork函數的功能、返回值進行了比較全面的描述。
實施例2
本實施例設定如下使用場景:
使用Linux內核郵件為數據源,選取2016年7月16至7月23一段時間的郵件,應用本方法自動生成函數注釋。
1)進入注釋自動生成系統,選取Linux內核郵件為數據源,爬取該段時間內4493封郵郵件。其中一封標題和正文文本如下:
標題:timer_list:print_tickdevice():calculate->min_delta_ns dynamically
正文:print_tickdevice(),assembling the per-tick device sections in/proc/timer_list,is the last user ofstruct clock_event_device's->min_delta_ns member.
In order to make this one fully obsolete while retaining userspace ABI,calculate the displayed value of'min_delta_ns'on the fly from->min_delta_ticks_adjusted.
Signed-off-by:Nicolai Stange<nicstange@xxxxxxxxx>
---
kernel/time/timer_list.c|5+++--
1file changed,3insertions(+),2deletions(-)
...
2)其中一封郵件經過預處理后得到兩段文本,如下:
文本1:print_tickdevice(),assembling the per-tick device sections in/proc/timer_list,is the last user of struct clock_event_device's->min_delta_ns member.
文本2:In order to make this one fully obsolete while retaining userspace ABI,calculate the displayed value of'min_delta_ns'on the fly from->min_delta_ticks_adjusted.
3)經過規(guī)則1的應用,上述步驟中的文本1將被提取出來作為注釋的備選段落;經過規(guī)則2的應用,生成的自動注釋如下:
print_tickdevice(),assembling the per-tick device sections in/proc/timer_list,is the last user of struct clock_event_device's->min_delta_ns member.
該注釋說明了print_tickdevice()函數的功能和該函數使用了何種數據。
實施例3
本實施例設定如下使用場景:
使用Linux內核Commit-log作為數據源,選取v4.8-rc3與v4.8-rc2兩個版本之間的log信息,應用本方自動生成函數注釋。
1)進入注釋自動生成系統,選取Linux kernel Commit-log為數據源,共爬取136個Commit-log信息。其中一個Commit-log標題和正文的文本如下:
標題:dm raid:enhance attempt_restore_of_faulty_devices()to support more devices
正文:dm raid:enhance attempt_restore_of_faulty_devices()to support more devices
attempt_restore_of_faulty_devices()is limited to 64when it should support the new maximum of 253when identifying any failed devices.It clears any revivable devices via an MD personality hot remove and add cylce to allow for their recovery.
Address by using existing functions to retrieve and update all failed devices'bitfield members in the dm raid superblocks on all RAID devices and check for any devices to clear in it.
Whilst on it,don't call attempt_restore_of_faulty_devices()for any MD personality not providing disk hot add/remove methods(i.e.raid0now),because such personalities don't support reviving offailed disks.
Signed-off-by:Heinz Mauelshagen<heinzm@redhat.com>
Signed-off-by:Mike Snitzer<snitzer@redhat.com>
...
2)上述Commit-log預處理后得到四段文本:
文本1:dmraid:enhance attempt_restore_of_faulty_devices()to support more devices
文本2:attempt_restore_of_faulty_devices()is limited to 64when it should support the new maximum of 253when identifying any failed devices.It clears any revivable devices via an MD personality hot remove and add cylce to allow for their recovery.
文本3:Address by using existing functions to retrieve and update all failed devices'bitfield members in the dm raid superblocks on allRAID devices and check for any devices to clear in it.
文本:4:Whilst on it,don't call attempt_restore_of_faulty_devices()for any MD personality not providing disk hot add/remove methods(i.e.raid0now),because such personalities don't support reviving offailed disks.
3)經過規(guī)則1的應用,上述步驟中的文本1、2、3、4將被提取出來作為注釋的備選段落;經過規(guī)則2的應用,文本4中的句子將被濾除,生成的自動注釋如下:
dm raid:enhance attempt_restore_of_faulty_devices()to support more devices
attempt_restore_of_faulty_devices()is limited to 64when it should support the new maximum of 253when identifying any failed devices.It clears any revivable devices via an MD personality hot remove and add cylce to allow for their recovery.
Address by using existing functions to retrieve and update all failed devices'bitfield members in the dm raid superblocks on all RAID devices and check for any devices to clear in it.
該注釋說明了attempt_restore_of_faulty_devices()函數在v4.8-rc2升級到v4.8-rc3與版本之后會支持更多的設備。
以上實施例僅用以說明本發(fā)明的技術方案而非對其進行限制,本領域的普通技術人員可以對本發(fā)明的技術方案進行修改或者等同替換,而不脫離本發(fā)明的精神和范圍,本發(fā)明的保護范圍應以權利要求所述為準。