一种面向Java源代码克隆检测的方法技术

技术编号:20763781 阅读:20 留言:0更新日期:2019-04-03 14:16
本发明专利技术公开了一种面向Java源代码克隆检测的方法,包括以下步骤:S1:提取Java源代码中的类作为最小提取单位;S2:对Java类中的函数名及变量名进行统一替换;S3:对Java源代码中的类进行比对,并输出比对结果。本发明专利技术的不仅能够高效地检测出整个代码文件或者代码片段的完全一样的复用或代码片段除了空格、注释外,其他完全相同代码简单克隆。同时,进一步针对改变、增加或删除程序语句,但代码的文本内容大部分相同的java源程序代码克隆进行检测,并输出准确的结果。

【技术实现步骤摘要】
一种面向Java源代码克隆检测的方法
本专利技术涉及计算机
,具体涉及一种面向Java源代码克隆检测的方法。
技术介绍
两个代码片段之间当且仅当他们是相似的序列时,称他们之间存在克隆关系。根据克隆关系可以定义克隆对和克隆类:满足克隆关系的一对代码片段被称作克隆对。克隆类是一个由克隆对组成的最大集合,在这个集合里存在克隆程度不同的代码片段。克隆程度由低到高分为:完全相同的代码克隆,仅修改了注释、布局和变量名等以外其余均相同的代码克隆,以及改变、增加或删除了程序语句,但代码的文本内容近似的代码克隆。代码克隆在软件系统中很普遍。即使是业界公认的高质量系统如XWindowsSystem仍有19%的代码克隆存在,Linux的核心部分有15-25%左右的代码克隆。一般软件系统中的代码克隆的比例更高,有些甚至高达38%。检测源代码中含有的克隆代码由三个主要步骤组成:中间形式生成,原型克隆检测和克隆报告生成。源代码是为编译器以及软件维护人员而编写的,其中含有大量与克隆代码检测无关的信息。克隆代码检测一般无法对源代码直接进行操作,必须要从源代码中抽出只与克隆代码检测有关的信息,生成便于进行克隆检测的中间形式。原型克隆检测对源程序的中间形式进行分析,检测出具有相同的中间形式的程序段。由于这一过程的结果只是在中间形式上的相同,而不一定是最后所要求的代码克隆,我们称之为原型克隆。通过对这些原型克隆的分析和剪接处理,克隆报告生成把原型克隆还原成有意义的源代码克隆对,输出具有良好可读性的克隆报告。把原型克隆还原成源代码的克隆需要中间形式和源代码之间的对应关系,因此,中间形式生成过程还需要生成一个程序格式信息表格,用于纪录中间形式和源代码之间的对应关系。克隆代码检测方法取决于采用什么样的中间形式来表示程序源代码。对于基于文本的克隆检测方法没有考虑程序的语法语义等结构信息,检测的准确率较低。而基于抽象语法树的构建语法树的代价较高,且对语法树进行相似性匹配时也要付出较高的时空代价,不适用于大型的系统软件。基于程序依赖图的方法时空代价比基于树形结构的更高,难以应用于大型软件系统。此外,基于度量值的方法只能进行固定颗粒度的检测,检测的准确性低。基于Token的方法检测速度较快并且不依赖于开发语言,但是却很难检测复杂代码克隆。
技术实现思路
本专利技术所要解决的技术问题是现有技术中各种克隆检测方法的通用性和准确性较差,目的在于提供一种面向Java源代码克隆检测的方法,解决上述问题。本专利技术通过下述技术方案实现:一种面向Java源代码克隆检测的方法,包括以下步骤:S1:提取Java源代码中的类作为最小提取单位;S2:对Java类中的函数名及变量名进行统一替换;S3:对Java源代码中的类进行比对,并输出比对结果。现有技术中,对于基于文本的克隆检测方法没有考虑程序的语法语义等结构信息,检测的准确率较低。而基于抽象语法树的构建语法树的代价较高,且对语法树进行相似性匹配时也要付出较高的时空代价,不适用于大型的系统软件。基于程序依赖图的方法时空代价比基于树形结构的更高,难以应用于大型软件系统。此外,基于度量值的方法只能进行固定颗粒度的检测,检测的准确性低。基于Token的方法检测速度较快并且不依赖于开发语言,但是却很难检测复杂代码克隆。本专利技术应用时,提取Java源代码中的类作为最小提取单位,并对Java类中的函数名及变量名进行统一替换,使得在对不同的代码进行克隆检测时,即使类中函数名称和变量名称发生更改,也可以实现类的准确的对比,再通过类对整段代码进行克隆检测可以有效的提高克隆检测的准确度,这种方式针对整个代码文件或者代码片段的完全一样的复用或代码片段除了空格、注释外,其他完全相同代码简单克隆尤其高效。本专利技术通过设置上述步骤,实现了对Java源代码克隆的高效检测,相比于现有技术代价低廉并且效率大幅提高。进一步的,步骤S2包括以下子步骤:扫描每一个Java类,并将Java类中表示变量名的终结符统一替换为字面量;定义用于扩展或自定义标记类型的字段。本专利技术应用时,为屏蔽java源程序中变量名的不同对克隆代码检测带来的影响,扫描每个java类,将java类中表示变量名的终结符[id]、[number]、[stringlit]等基本类型统一替换为字面量x,并且自定义[tokens]段用于扩展或自定义标记类型。进一步的,步骤S1包括以下子步骤:定义一个类的根非结束符,并以根非结束符为根节点建立解析树;所述解析树中的父节点均由该父节点对应的多个排序的子节点构成;所述解析树的父节点均为非结束符;所述解析树的叶节点均为结束符;将所述根非结束符表示为所有叶节点的序列。本专利技术应用时,为了进一步针对改变、增加或删除程序语句,但代码的文本内容大部分相同的java源程序代码克隆进行检测,本专利技术对类文件进行解析,并生成解析树,按照上述方法相当于自上而下对每个非结束符进行定义,一直到每个非结束符都被表示为一系列的结束符。这样就可以从java源程序中提取出每个java类,并保留java类在源代码中起始行与结束行的位置信息并生成相应的解析树。进一步的,步骤S3包括以下子步骤:设置差异率阈值K;对于待比较类C1,记其序列为S1,序列长度为M1;对于待比较类C2,记其序列为S2,序列长度为M2;当M1在区间[M2,(1+K)M2]内时,即认为C1和C2可能存在克隆关系,并记录C1和C2为预选克隆类。本专利技术应用时,为了判断两个待比较的类是否存在克隆关系,需要引入一个参数来判定,这个参数就是差异率阈值K。两个待比较类的代码规模差异如果过大,则它们必然不能构成代码克隆。因此对于待比较类C1,记其代码序列长度为M1,设当前克隆类的差异率阈值为K,则对于与C1进行比较的类C2,设其代码序列长度为M2,只有当M1在区间[M2,(1+K)M2]里时,C2才可能与C1存在克隆关系,构成克隆类。进一步的,步骤S3还包括以下子步骤:当C1和C2为预选克隆类时,提取S1和S2的最长公共子序列S,并记最长公共子序列S的长度为M;得出S1中独有的子序列长度M1′,得出S2中独有的子序列长度M2′;通过M1和M1′得出S1的差异率R1,通过M2和M2′得出S2的差异率R2;当R1和R2均低于K时,判定C1和C2互为克隆类。本专利技术应用时,对程序源代码进行转换与处理后生成的序列进行相似度检测。为了进一步针对改变、增加或删除程序语句,但代码的文本内容大部分相同的java源程序代码克隆进行检测,本专利技术创造性的采用了最长公共子序列的方式对两个类进行检测,一般来说最长公共子序列在一个类中的占比越高,说明两个类就越相似,这种方式对于代码部分顺序发生变化的克隆检测尤其有效。进一步的,M1′根据下式得出:M1′=M1-M;式中,M1′为S1中独有的子序列长度;M1为S1序列长度;M为S1和S2的最长公共子序列长度;M2′根据下式得出:M2′=M2-M;式中,M2′为S2中独有的子序列长度;M2为S2序列长度;M为S1和S2的最长公共子序列长度。进一步的,所述R1根据下式得出:R1=(M1′/M1)×100%;式中M1′为S1中独有的子序列长度;M1为S1序列长度;所述R2根据下式得出:R2=(M2′/M2)×100%;式中M2′本文档来自技高网
...

【技术保护点】
1.一种面向Java源代码克隆检测的方法,其特征在于,包括以下步骤:S1:提取Java源代码中的类作为最小提取单位;S2:对Java类中的函数名及变量名进行统一替换;S3:对Java源代码中的类进行比对,并输出比对结果。

【技术特征摘要】
1.一种面向Java源代码克隆检测的方法,其特征在于,包括以下步骤:S1:提取Java源代码中的类作为最小提取单位;S2:对Java类中的函数名及变量名进行统一替换;S3:对Java源代码中的类进行比对,并输出比对结果。2.根据权利要求1所述的一种面向Java源代码克隆检测的方法,其特征在于,步骤S2包括以下子步骤:扫描每一个Java类,并将Java类中表示变量名的终结符统一替换为字面量;定义用于扩展或自定义标记类型的字段。3.根据权利要求1所述的一种面向Java源代码克隆检测的方法,其特征在于,步骤S1包括以下子步骤:定义一个类的根非结束符,并以根非结束符为根节点建立解析树;所述解析树中的父节点均由该父节点对应的多个排序的子节点构成;所述解析树的父节点均为非结束符;所述解析树的叶节点均为结束符;将所述根非结束符表示为所有叶节点的序列。4.根据权利要求3所述的一种面向Java源代码克隆检测的方法,其特征在于,步骤S3包括以下子步骤:设置差异率阈值K;对于待比较类C1,记其序列为S1,序列长度为M1;对于待比较类C2,记其序列为S2,序列长度为M2;当M2在区间[M2,(1+K)M2]内时,即认为C1和C2可能存在克隆关系,并记录C1和C2为预选克隆类。5.根据权利要求4所述的一种面向Java源代码克隆检测的方法,其特征在于,步骤S3还包括以下子步骤:当C1和C2为预选克隆类时,提取S1和S2的最长公共子序列S,并记最长公共子序列S的长度为M;得出S1中独有的子序列长度M1′,得出S2中独有的子序列长度M2′;通过M1和M1′得出S1的差异率R1,通过M2和M2′得出S2的差异率R2;当R1和R2...

【专利技术属性】
技术研发人员:张凌浩桂盛霖常晓青刘元生梁晖辉王胜唐超王海张颉甘炜
申请(专利权)人:国网四川省电力公司电力科学研究院
类型:发明
国别省市:四川,51

网友询问留言 已有0条评论
  • 还没有人留言评论。发表了对其他浏览者有用的留言会获得科技券。

1