一种基于抽象语法树的重复代码检测方法及装置的制造方法

文档序号:10612721阅读:207来源:国知局
一种基于抽象语法树的重复代码检测方法及装置的制造方法
【专利摘要】本发明公开了一种基于抽象语法树的重复代码检测方法及装置。该重复代码检测方法包括:对待检测代码和样本代码分别构建抽象语法树;将两棵抽象语法树的子树根据根节点类型分别进行分类;将根节点类型相同的两棵抽象语法树的子树进行对比,判断是否存在公共子树;当存在公共子树时,获取公共子树对应的代码,判定该代码即为重复代码。通过本发明的方法可以完全避免空格、换行、缩进、注释等无关信息对相似性判定的影响,快速检测出重复代码。
【专利说明】
一种基于抽象语法树的重复代码检测方法及装置
技术领域
[0001]本发明涉及软件应用技术领域,尤其涉及一种基于抽象语法树的重复代码检测方法及装置。
【背景技术】
[0002]在一个大的软件系统中添加新功能或者做维护时,在程序中引入重复代码是非常普遍的。因为在这样的情况下,开发人员对代码的结构不是很熟悉,为了减少在程序中引入新的BUG,通常通过拷贝的形式,把实现类似功能的代码段稍作修改,甚至原封不动地进行复制,通过代码的复用来满足当前的系统设计需求。
[0003]代码复用导致最终的软件产品中存在很多相似的代码片段(称为“重复代码”)。有研究显示,典型的软件系统包括多达7%到23%的重复代码。在软件的维护和演化过程中,重复代码往往带来一些负面影响:例如,如果一个代码片段出现缺陷,那么需要检查所有相似的重复代码片段,以防止相同缺陷的出现,这就势必为维护增加了额外的工作量。重复代码的存在对于后续系统维护是非常大的隐患。此外,在程序理解、代码质量分析、代码压缩(如移动应用中)、恶意代码检测等常见场景中,也都需要识别和抽取软件代码中的若干相似片段。
[0004]然而代码中经常存在空格、换行、缩进、注释等无关信息,这些信息在不同的场景中可能有非常大的区别,例如,一段代码有时出于可读性的原因会增加大量的缩进、空白与注释,但有时为了节省空间而会删除所有的空白与注释。而空白与注释等无关信息,致使重复代码检测的准确性不高。
[0005]基于上述可知,如何避免无关信息的干扰,实现程序中重复代码的快速检测,属于目前软件应用领域亟需解决的一大技术问题。

【发明内容】

[0006]为了解决重复代码检测过程中,空白和注释等无关信息降低检测准确性的问题,本发明提供一种基于抽象语法树的重复代码检测方法及装置。
[0007]为实现上述发明目的,本发明采用下述的技术方案:
[0008]依据本发明的一个方面,提供一种基于抽象语法树的重复代码检测方法,包括:
[0009]对待检测代码和样本代码分别构建抽象语法树;
[0010]将两棵抽象语法树的子树根据根节点类型分别进行分类;
[0011]将根节点类型相同的所述两棵抽象语法树的子树进行对比,判断是否存在公共子树;
[0012]当存在公共子树时,获取所述公共子树对应的代码,判定所述代码为重复代码。
[0013]进一步地,所述将两棵抽象语法树的子树根据根节点类型分别进行分类,包括;
[0014]获取所述两个抽象语法树的所有子树的节点数;
[0015]判断每棵子树的节点数与预设数量阈值的大小:当某棵子树的节点数大于预设阈值时,则将该子树放入对应的根节点类型集合中;否则,不对该子树进行分类。
[0016]进一步地,所述将根节点类型相同的所述两棵抽象语法树的子树进行对比,判断是否存在公共子树,包括:
[0017]获取待对比的两棵子树中的相同节点的节点数;
[0018]计算所述节点数占所述两棵子树所有节点和的比值;
[0019]当所述比值大于预设比例阈值时,则判定所述两棵子树为一对公共子树。
[0020]进一步地,所述将根节点类型相同的所述两棵抽象语法树的子树进行对比前,包括:
[0021]判断是否需要忽略低语义信息;其中,所述低语义信息包括字符串值、变量值、变量名以及变量顺序中的任一种或多种;
[0022]当需要时,则利用统一标识对所述两棵抽象语法树中的低语义信息进行替换。
[0023]进一步地,所述方法还包括:
[0024]当所述两棵抽象语法树中存在多对公共子树时,判断所述多对公共子树中位于同一棵抽象语法树的多棵子树间是否存在包含关系;
[0025]若存在,则选取集合最大的一棵子树作为该棵抽象语法树的公共子树。
[0026]依据本发明的另一方面,提供一种基于抽象语法树的重复代码检测装置,包括:
[0027]构建单元,用于对待检测代码和样本代码分别构建抽象语法树;
[0028]分类单元,用于将两棵抽象语法树的子树根据根节点类型分别进行分类;
[0029]判断单元,用于将根节点类型相同的所述两棵抽象语法树的子树进行对比,判断是否存在公共子树;
[0030]获取单元,用于当存在公共子树时,获取所述公共子树对应的代码,判定所述代码即为重复代码。
[0031]进一步地,所述分类单元具体用于;
[0032]获取所述两个抽象语法树的所有子树的节点数;
[0033]判断每棵子树的节点数与预设数量阈值的大小:当某棵子树的节点数大于预设阈值时,则将该所述子树放入对应的根节点类型集合中;否则,不对该子树进行分类。
[0034]进一步地,所述判断单元具体用于:
[0035]获取待对比的两棵子树中的相同节点的节点数;
[0036]计算所述节点数占所述两棵子树所有节点和的比值;
[0037]当所述比值大于预设比例阈值时,则判定所述两棵子树为一对公共子树。
[0038]进一步地,所述装置还包括过滤单元,具体用于:
[0039]将根节点类型相同的所述两棵抽象语法树的子树进行对比前,判断是否需要过滤低语义信息;其中,所述低语义信息包括字符串值、变量值、变量名以及变量顺序中的任一种或多种;
[0040]当需要时,则利用统一标识对所述两棵抽象语法树中的低语义信息进行替换。
[0041]进一步地,所述装置还包括选取单元,具体用于:
[0042]当所述两棵抽象语法树中存在多对公共子树时,判断所述多对公共子树中位于同一棵抽象语法树的多棵子树间是否存在包含关系;
[0043]若存在,则选取集合最大的一棵子树作为该棵抽象语法树的公共子树。
[0044]本发明具有以下有益效果:
[0045]本发明实施例在语法层对样本代码和待检测代码分别构建抽象语法树,接着在将两棵抽象语法树中的子树进行分类,并根据根节点类型相同子树的判断两段代码是否相似。通过本发明的方法可以完全避免空格、换行、缩进、注释等无关信息对相似性判定的影响,快速检测出重复代码。同时,本发明还可根据需要调整参数信息,以便对字符串值、变量值、变量名等低语义价值信息在相似性的判定中进行恰当处理,适用于软件缺陷检查、程序理解、代码质量分析、代码重构等多种软件开发与维护场景。
[0046]上述说明仅是本发明技术方案的概述,为了能够更清楚了解本发明的技术手段,而可依照说明书的内容予以实施,并且为了让本发明的上述和其它目的、特征和优点能够更明显易懂,以下特举本发明的【具体实施方式】。
【附图说明】
[0047]为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作一简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
[0048]图1为本发明实施例中基于抽象语法树的重复代码检测方法的流程图;
[0049]图2为本发明实施例中Javascript代码构建的抽象语法树示意图;
[0050]图3为本发明实施例中Javascript代码构建的抽象语法树的代码示例图;
[0051 ]图4a为本发明实施例中未过滤变量顺序的抽象语法树示意图;
[0052]图4b为本发明实施例中过滤变量顺序的抽象语法树示意图;
[0053]图5为本发明实施例中检测重复代码的代码示例图;
[0054]图6为本发明实施例中基于抽象语法树的重复代码检测装置的结构示意图。
【具体实施方式】
[0055]下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
[0056]如图1所示,本发明实施例中所提供的基于抽象语法树的重复代码检测方法,具体包括如下步骤:
[0057]步骤I,对待检测代码和样本代码分别构建抽象语法树;
[0058]步骤2,将两棵抽象语法树的子树根据根节点类型分别进行分类;
[0059]步骤3,将根节点类型相同的两棵抽象语法树的子树进行对比,判断是否存在公共子树;
[0060]步骤4,当存在公共子树时,获取公共子树对应的代码,判定该代码即为重复代码。
[0061]本发明实施例在语法层对样本代码和待检测代码分别构建抽象语法树,接着在将两棵抽象语法树中的子树进行分类,并根据两棵抽象语法树中根节点节点类型相同子树的判断两段代码是否相似,因此通过本发明的方法可以完全避免空格、换行、缩进、注释等无关信息对相似性判定的影响,快速检测出重复代码。
[0062]下面结合附图和具体实施例对本发明的技术内容进行详细说明。
[0063]步骤I,对待检测代码和样本代码分别构建抽象语法树。
[0064]一般而言,一段程序都是由一系列语句(Statement)构成的,而一条语句又分解为若干表达式(Express1n)。例如,从语法上分析一条赋值语句“X = 3+5”,首先执行算术表达式“3+5”,结果为“8” ;然后通过赋值表达式“X = 8”,将变量“X”赋值为“8”。将表达式的运算符作为树根(如上例中的“+”、“=”),参与运算的变量和常量(“X”、“3”、“5”等)作为树叶,就得到了表达式对应的抽象语法树;若干表达式对应的抽象语法树组成了一条语句对应的抽象语法树;而若干语句的抽象语法树就组成了整段程序的抽象语法树。参见图2和图3,一段Javascript程序的抽象语法树示例和代码示例。从抽象语法树的构建方法可以看到,代码中的空白、换行、缩进、注释等无关信息会被完全忽略,因此也不会影响后续的检测判定结果O
[0065]本发明实施例中仅对抽象语法树的创建进行简单介绍,其创建过程已属于本领域技术人员所熟知的技术,例如“廖兴等;基于Java语言的抽象语法树的创建与遍历;长沙大学学报;2004年04期”中有相关介绍,这里不再进行赘述。
[0066]步骤2,将两棵抽象语法树的子树根据根节点类型分别进行分类。
[0067]本发明实施例中构建好抽象语法树后,列举每棵抽象语法树的所有子树,在对子树进行分类前,首先对子树进行初步筛选,将子树规模(节点数)小于预设数量阈值的子树进行忽略。这样可以有效避免单叶子节点(节点数为I)和简单语句(例如赋值语句“X = y”对应的子树大小为3)等不必要的元素参与相似性比对。对子树的初步筛选在不影响最终相似度比对结果的同时可以有效降低整个检测过程的计算量。对子树完成初步筛选后,根据根节点的类型对子树进行分类。
[0068]步骤3,将根节点类型相同的两棵抽象语法树的子树进行对比,判断是否存在公共子树。
[0069]本发明实施例将程序代码转换为抽象语法树后,判定两段代码的相似性就等价于判断两棵抽象语法树的相似性。通过查找两棵抽象语法树的最大公共子树集合来进行相似性判定,即两棵树的相似性与其最大公共子树集合的大小呈正比。当两棵树完全一样时,最大公共子树等于原抽象语法树本身(集合最大);反之,当两棵树完全不相似时,就没有公共子树,最大公共子树集合为空。这样,不仅能对相似程度进行一定量化评价,还能计算出具体的相似代码片段。
[0070]在计算相似性之前,用户可以根据实际需要对低语义信息进行过滤。本发明实施例中提供4类参数,包括字符串值、变量值、变量名、变量顺序。用户可以选其中的任一种或者多种低语义信息进行过滤,不考虑其对相似性的影响。本发明实施例根据需要调整参数,以便低语义价值信息在相似性判定中进行恰当处理,非常适用于软件缺陷检查、程序理解、代码质量分析、代码重构等多种软件开发与维护场景。
[0071]具体地,图4a为本发明实施例中未过滤变量顺序的抽象语法树示意图,图4b为本发明实施例中过滤变量顺序的抽象语法树示意图。对于变量顺序,直接忽略即可。对于其他低语义信息,如果需要忽略,本发明实施例中利用统一的标志对抽象语法树上的相应信息进行替换,使其对公共子树判定没有影响。
[0072]然后,将根节点类型相同的子树进行两两匹配(如“变量声明语句”对应的子树只和其它同类子树进行匹配)。由于类型不同的子树一定对应不同的代码,因此本发明实施例中根据根节点类型对子树进行匹配,可以有效降低整个检测过程的计算量。
[0073]进一步地,本发明实施例中在比较两棵子树是否为一对公共子树时,具体包括如下步骤:
[0074]获取待对比的两棵子树中的相同节点的节点数(两棵子树的节点交集);
[0075]计算节点数占两棵抽象语法树所有节点和(两棵子树的节点并集)的比值;
[0076]当比值大于预设比例阈值时,则判定两棵子树为一对公共子树。
[0077]本发明实施例中,在求得公共子树后,还通过一次额外检查来保证只留下最大公共子树,即:当两棵抽象语法树中存在多对公共子树时,判断多对公共子树中位于同一棵抽象语法树的多棵子树间是否存在包含关系;若存在,则选取集合最大的一棵子树作为该棵抽象语法树的公共子树,具体的代码实现过程,可以参见图5。
[0078]最后,只需将找到的最大公共子树对应到原始代码,就得到了两段代码的相似片段集合,即重复代码。
[0079]参见图6,本发明实施例还提供了一种基于抽象语法树的重复代码检测装置,用于实现上述的重复代码检测方法,具体包括:
[0080]构建单元,用于对待检测代码和样本代码分别构建抽象语法树;
[0081 ]分类单元,用于将两棵抽象语法树的子树根据根节点类型分别进行分类;
[0082]判断单元,用于将根节点类型相同的两棵抽象语法树的子树进行对比,判断是否存在公共子树;
[0083]获取单元,用于当存在公共子树时,获取公共子树对应的代码,该代码即为重复代码。
[0084]进一步地,分类单元具体用于;
[0085]获取两个抽象语法树的所有子树的节点数;
[0086]判断每棵子树的节点数与预设数量阈值的大小:当某棵子树的节点数大于预设阈值时,则子树放入对应的根节点类型集合中;否则,不对子树进行分类。
[0087]进一步地,判断单元具体用于:
[0088]获取待对比的两棵子树中的相同节点的节点数;
[0089]计算节点数占两棵子树所有节点和的比值;
[0090]当比值大于预设比例阈值时,则判定两棵子树为一对公共子树。
[0091]进一步地,装置还包括过滤单元,具体用于:
[0092]将根节点类型相同的两棵抽象语法树的子树进行对比前,判断是否需要过滤低语义信息;其中,低语义信息包括字符串值、变量值、变量名以及变量顺序中的任一种或多种;
[0093]当需要时,则利用统一标识对两棵抽象语法树中的低语义信息进行替换。
[0094]进一步地,该检测装置还包括选取单元,具体用于:
[0095]当两棵抽象语法树中存在多对公共子树时,判断多对公共子树中位于同一棵抽象语法树的多棵子树间是否存在包含关系;
[0096]若存在,则选取集合最大的一棵子树作为该棵抽象语法树的公共子树。
[0097]本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,程序可存储于计算机可读取存储介质中,该程序在执行时,可包括如上述各方法的实施例的流程。
[0098]虽然通过实施例描述了本申请,本领域的技术人员知道,本申请有许多变形和变化而不脱离本发明的精神和范围。这样,倘若本发明的这些修改和变型属于本发明权利要求及其等同技术的范围之内,则本发明也意图包含这些改动和变型在内。
【主权项】
1.一种基于抽象语法树的重复代码检测方法,其特征在于,包括: 对待检测代码和样本代码分别构建抽象语法树; 将两棵抽象语法树的子树根据根节点类型分别进行分类; 将根节点类型相同的所述两棵抽象语法树的子树进行对比,判断是否存在公共子树; 当存在公共子树时,获取所述公共子树对应的代码,判定所述代码为重复代码。2.如权利要求1所述的方法,其特征在于,所述将两棵抽象语法树的子树根据根节点类型分别进行分类,包括; 获取所述两个抽象语法树的所有子树的节点数; 判断每棵子树的节点数与预设数量阈值的大小:当某棵子树的节点数大于预设阈值时,则将该子树放入对应的根节点类型集合中;否则,不对该子树进行分类。3.如权利要求1所述的方法,其特征在于,所述将根节点类型相同的两棵抽象语法树的子树进行对比,判断是否存在公共子树,包括: 获取待对比的两棵子树中的相同节点的节点数; 计算所述节点数占所述两棵子树所有节点和的比值; 当所述比值大于预设比例阈值时,则判定所述两棵子树为一对公共子树。4.如权利要求1所述的方法,其特征在于,所述将根节点类型相同的两棵抽象语法树的子树进行对比前,包括: 判断是否需要忽略低语义信息;其中,所述低语义信息包括字符串值、变量值、变量名以及变量顺序中的任一种或多种; 当需要时,则利用统一标识对所述两棵抽象语法树中的低语义信息进行替换。5.如权利要求1所述的方法,其特征在于,所述方法还包括: 当所述两棵抽象语法树中存在多对公共子树时,判断所述多对公共子树中位于同一棵抽象语法树的多棵子树间是否存在包含关系; 若存在,则选取集合最大的一棵子树作为该棵抽象语法树的公共子树。6.一种基于抽象语法树的重复代码检测装置,其特征在于,包括: 构建单元,用于对待检测代码和样本代码分别构建抽象语法树; 分类单元,用于将两棵抽象语法树的子树根据根节点类型分别进行分类; 判断单元,用于将根节点类型相同的所述两棵抽象语法树的子树进行对比,判断是否存在公共子树; 获取单元,用于当存在公共子树时,获取所述公共子树对应的代码,则判定所述代码即为重复代码。7.如权利要求6所述的装置,其特征在于,所述分类单元具体用于; 获取所述两个抽象语法树的所有子树的节点数; 判断每棵子树的节点数与预设数量阈值的大小:当某棵子树的节点数大于预设阈值时,则将该子树放入对应的根节点类型集合中;否则,不对该子树进行分类。8.如权利要求6所述的装置,其特征在于,所述判断单元具体用于: 获取待对比的两棵子树中的相同节点的节点数; 计算所述节点数占所述两棵子树所有节点和的比值; 当所述比值大于预设比例阈值时,则判定所述两棵子树为一对公共子树。9.如权利要求6所述的装置,其特征在于,所述装置还包括过滤单元,具体用于: 将根节点类型相同的所述两棵抽象语法树的子树进行对比前,判断是否需要过滤低语义信息;其中,所述低语义信息包括字符串值、变量值、变量名以及变量顺序中的任一种或多种; 当需要时,则利用统一标识对所述两棵抽象语法树中的低语义信息进行替换。10.如权利要求6所述的装置,其特征在于,所述装置还包括选取单元,具体用于: 当所述两棵抽象语法树中存在多对公共子树时,判断所述多对公共子树中位于同一棵抽象语法树的多棵子树间是否存在包含关系; 若存在,则选取集合最大的一棵子树作为该棵抽象语法树的公共子树。
【文档编号】G06F11/36GK105975392SQ201610282319
【公开日】2016年9月28日
【申请日】2016年4月29日
【发明人】易立, 杜翠兰, 任彦, 李鹏霄, 钮艳, 刘晓辉, 查奇文, 佟玲玲
【申请人】国家计算机网络与信息安全管理中心
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1