基于对比学习的跨语言代码克隆检测方法

2024-08-17 00:00:00吕泉润谢春丽万泽轩魏家劲
计算机应用研究 2024年7期

摘 要:代码克隆检测是提高软件开发效率、软件质量和可靠性的重要手段。基于抽象语法树(abstract syntax tree,AST)的单语言克隆检测已经取得了较为显著的效果,但跨语言代码的AST节点存在同义词、近义词且手工标注数据集成本高等问题,限制了现有克隆检测方法的有效性和实用性。针对上述问题,提出一种基于对比学习的树卷积神经网络(contrastive tree convolutional neural network,CTCNN)的跨语言代码克隆检测方法。该方法首先将不同编程语言的代码解析为AST,并对AST的节点类型和节点值作同义词转换处理,以降低不同编程语言AST之间的差异;同时,采用对比学习扩充负样本并对模型进行训练,使得在小样本数据集下能够最小化克隆对之间的距离,最大化非克隆对之间的距离。最后在公开数据集上进行了评测,精确度达到95.26%、召回率为99.98%、F1为97.56%。结果表明,相较于现有的最好的CLCDSA和C4方法,该模型的检测精度分别提高了43.92%和3.73%,其F1值分别提升了29.84%和6.29%,证明了所提模型是一种有效的跨语言代码克隆检测方法。

关键词:跨语言;代码克隆;对比学习;抽象语法树

中图分类号:TP311 文献标志码:A 文章编号:1001-3695(2024)07-031-2147-06

doi: 10.19734/j.issn.1001-3695.2023.11.0534

Contrastive learning based cross-language code clone detection

Abstract: Code clone detection is an important technology to improve software development efficiency, quality, and reliability. Single-language clone detection based on AST has achieved significant performance. However, the existence of synonyms and near-synonyms in AST nodes of cross-language codes and the high cost of manual labeling limit the effectiveness and usefulness of existing clone detection methods. To address these issues, this paper proposed a cross-language code clone detection method based on contrastive tree convolutional neural network(CTCNN). Firstly, it parsed the codes of different programming languages into ASTs, and processed the node types and values of ASTs by synonym conversion to reduce the differences between ASTs in different programming languages. At the same time, it employed contrastive learning to augment negative samples and train the model, so that this approach ensured the minimization of distances between clone pairs and the maximization of distances between non-clone pairs in small sample datasets. Finally, it evaluated the proposed method on a public dataset with precision, recall, and F1-scores of 95.6%, 99.98%, and 97.56%. The results show that compared to the best existing methods CLCDSA and C4, the proposed model improves the detection accuracy by 43.92% and 3.73%, and increases the F1-score by 29.84% and 6.29%, which confirms that the proposed model is an effective cross-language code clone detection method.

Key words:cross-language; code clone; contrastive learning; abstract syntax tree

0 引言

在软件开发过程中,开发人员在开发功能类似的应用程序时,往往会复用已经成功上线的其他语言版本的软件代码或发布在开源社区平台上面的代码,因此,不同语言之间的代码克隆是一个普遍存在的问题。研究表明,在软件系统中,存在7%~23%的克隆代码[1]。代码克隆虽然可以提高编程效率,但对软件维护、软件质量也存在一定的负面影响[2]。例如,源代码中的重复代码块增加了程序的复杂性,从而导致软件维护更加困难[3]。对代码片段的更改也需要在其他所有克隆块上同步修改,如果更改不一致,则将导致错误传播,给软件的可维护性和可靠性带来了新的挑战。因此,跨语言代码克隆是软件开发和维护中亟待解决的问题。

不同于单语言克隆检测,各编程语言的词法、语法的差异增加了跨语言代码克隆检测的难度。目前已有的跨语言代码克隆检测方法主要包括C4(contrastive cross-language code clone detection) [4]、LICCA[5]、CLCDSA[6]、树自动编码器(tree autoencoder,TAE)[7]等。C4模型将源代码的token转换为向量,通过比较向量相似度进行克隆代码检测,该方法可以有效地检测出跨语言的克隆代码,但这些token仅包含代码的词法信息,缺乏代码的语法和语义信息。LICCA利用SSQSA[8]平台将不同的编程语言转换为通用的中间表示,它虽然可以在一定程度上实现编程语言的统一,但该模型要求源代码长度相等并且两个代码块的代码步骤和功能流程需要相同,这些限制使得该模型不适用于现实世界中的场景。TAE使用无监督学习的方式对大规模数据集的AST进行预训练以解决数据集瓶颈问题,并取得了较好的结果,但该方法未考虑到不同编程语言词法的影响。

现有基于AST的方法虽然在单语言代码克隆检测有较好的表现,但在处理跨语言的代码克隆时性能有限,主要原因在于不同编程语言的AST表示存在差异,基于AST的方法通常依赖于特定语言的AST结构进行代码克隆检测,每种编程语言都有其独特的语法规则和结构,因此对应的AST表示也会有所不同。

为解决上述问题,本文提出了一种基于对比学习[9]的树卷积神经网络[10]方法进行跨语言代码克隆检测,该方法通过构建同义词转换表的方法对不同编程语言的AST进行同义词转换处理,并采用对比学习的方法进行跨语言代码克隆检测。该方法可以减轻人工标注的工作,提高模型的抗干扰能力,为提高软件开发效率、降低软件维护成本提供技术支撑。

本文的主要贡献有:

a)提出一种新的跨语言代码克隆检测方法CTCNN,该方法通过树型卷积提取AST中的语法和节点属性信息,并利用字典方法解决不同语言之间的同义词转换问题,提高模型的语义表征能力。

b)提出对比学习方法来学习跨语言的相似性样本和不相似性样本,利用自监督学习方法解决跨语言数据集标注缺失问题。

1 相关工作

1.1 跨语言代码克隆检测

深度学习模型能够挖掘出大量数据中的隐藏模式,获得有效的特征表示。基于深度学习的跨语言代码克隆检测被分为基于词法(token)、基于语法树(AST)和基于图(graph)的代码克隆检测。

a)基于token的方法。该方法利用词法分析器把不同语言的代码转换为token序列,通过比较代码序列来检测克隆代码[11]。 Tao等人[4]提出的C4是一种跨语言克隆检测模型,该模型采用了对比学习的思想,使用token作为输入,采用CodeBERT[12]来提取代码中的特征,并将其转换为向量表示,通过比较向量之间的相似度来检测克隆代码,如果两个向量之间的相似度超过了一定的阈值,就认为它们是克隆代码。

b)基于AST的方法。该方法将不同语言的代码转换为语法树,通过比较语法树来检测克隆代码。Vislavski等人[5]提出的LICCA是一种开源的跨语言代码克隆检测工具,LICCA依赖于软件质量静态分析器(SSQSA)平台[8]的高级代码表示,提取AST的语法和语义特征,LICCA使用了一个中间程序表示法,它可以实现语义上等价的语言结构的统一,并通过跨语言使用不同的语法来实现。Ling等人[7]提出了一种基于树自动编码器(TAE)预训练的跨语言代码克隆检测模型,其思想是利用TAE预训练来提高表示学习的质量,通过在预训练模型的基础上进行微调来实现跨语言代码克隆检测。Perez等人[13]提出了一种基于AST的跨语言代码克隆检测模型,该模型使用graph2vec[14]方法对AST进行嵌入学习,将AST映射到统一的低维向量空间中,通过计算不同代码段之间的相似度来判断是否为克隆代码。Yang等人[15]提出的ASTERIA是一种基于AST的深度学习方法,该方法利用Tree-LSTM[16]网络从其AST中学习函数的语义表示,通过测量两个表示向量之间的相似度进行相似度检测。

c)基于图的方法。Zhang等人[17]提出了一种基于代码流程图的跨语言代码相似度检测(CLCSD)方法,该方法将特定编程语言编写的源代码转换为标准化代码流程图(standardized code flow chart,SCFC),将不同编程语言编写的两个源代码片段转换为SCFC,并利用所提出的SCFC-SPGK算法测量其对应的SCFC来获得它们的相似性。

除了以上的跨语言代码克隆检测方法,还有一些别的方法技术,如Cheng等人[18]提出的CLCMiner通过计算不同编程语言中不同片段之间的相似性,并选择每个差异中最相似的片段作为一对匹配的差异,根据不同的相似性对匹配的差异对进行排序和克隆检测,但CLCMiner从修订历史中挖掘克隆,从而限制了其应用。Nafi等人[19]提出了一种基于深度学习的向量学习方法来识别语义关系,使用应用程序编程接口(API)文档来查找不同语言使用的API调用之间的关系,但这种方法的克隆检测效果取决于API文档的质量。为了支持大规模的克隆检测,Nafi等人[6]提出一种用于跨语言代码克隆检测的模型CLCDSA,该模型使用了一个基于跨语言API的过滤器来丢弃非潜在的克隆,使用语义分析实现跨语言代码检测。Bui等人[20]提出一种基于暹罗神经网络[21]的神经网络框架(Bi-NN),通过长短期记忆(LSTM)[22]和门控图神经网络(GGNN)[23]等模型来实例化双边代码表示框架,以表示语法、语义和算法分类。

1.2 对比学习

对比学习是一种自监督学习方法,通过最小化相似数据表示之间的距离,并最大限度地提高不同数据之间的距离,以提高模型的泛化能力。与样本总和的损失函数不同,对比学习的损失函数通过成对的例子运行。在实际应用中,对比损失函数通常需要结合具体的模型和任务来进行设计和优化。Yahya等人[24]提出使用InferCode的暹罗架构从AST获得的源代码嵌入中学习更抽象的嵌入,将AST循环到将整个子树嵌入到一个描述整个代码片段的向量中,这样就可以更容易地将给定的代码与不同语言中的其他源代码片段进行比较。

2 方法设计

2.1 方法整体结构

本文提出的基于CTCNN的跨语言代码克隆检测方法,如图1所示。该方法主要包括三个部分:

a)数据预处理:去除与源码无关的信息,利用语法解析工具将代码解析为AST,并对AST的节点进行上下文信息扩展。

b)同义词转换处理:对不同编程语言的AST进行同义词转换处理,以实现跨语言AST的统一表示。

c)代码克隆检测模型:以 AST作为输入,送入基于对比学习的TBCNN模型中得到代码的向量表示,使用对比学习提高模型的泛化能力。通过比较代码表征的余弦相似度,判断是否为跨语言代码克隆对。

2.2 数据预处理

数据预处理是对源代码进行解析和增强处理,以获取源码的语义信息,主要包括以下三个步骤:a)去除源码中多余的换行符、注释等无关信息;b)将源码解析为AST;c)扩展AST节点信息,通过对AST自顶向下的遍历,将子节点信息添加到父节点中,以获取AST的上下文信息。算法1描述了将源码解析为带有上下文信息的AST的过程,该算法将AST的节点n由n=〈Nt,Nv〉扩充为ne=〈Nt,Nv,Nct,Ncv〉的形式,其中Nt、Nv、Nct、Ncv分别表示AST节点的节点类型、节点值、子节点类型列表和子节点值列表。算法1中:步骤a)b)加载指定语言的解析器,将源代码解析为 AST;步骤c)~g)定义一个递归函数,采用自顶向下的遍历方式对 AST 中每个节点进行访问,获取其节点类型、节点值和子节点列表,并构造一个节点信息元组;最终,步骤h)i)从根节点开始将整个 AST 表示为一棵树型结构并返回AST。

算法1 将源码解析为带有上下文信息的AST

2.3 基于字典的同义词转换

如图2所示,各编程语言的AST节点存在一定差异,例如Java语言中的根节点称为“program”,而C语言中的节点则称为“translation_unit”。虽然这两种术语在词汇上有所不同,但实际上它们代表的是相同的语义,即编码单元。

采用基于字典的同义词转换可用于解决不同编程语言AST之间节点值和节点类型同义词的问题。具体过程如下:首先,对生成的AST进行遍历,得到所有节点类型和节点值;然后,将语义相同但词汇不同的节点类型或节点值采用统一的词汇表示;最终,以字典的形式生成同义词转换表。通过同义词转换表,将具有编程语言特性的关键词、特殊符号的节点值或节点类型替换成统一的词汇,可以进一步降低不同编程语言AST的差异性,以统一不同编程语言AST的语义。

例如,使用“unit”统一替换不同编程语言中的“program”“translation_unit”等词汇,从而减少不同编程语言AST之间的差异。这样做可以让不同编程语言的AST在语义上更加一致,进而提高程序分析的精度和效率。

2.4 代码克隆检测模型

跨语言的代码克隆检测主要分为四层,分别为嵌入层、卷积层、池化层和对比层。

2.4.1 嵌入层

首先,对数据集中的所有AST进行遍历,得到AST节点类型和节点值的词汇表,在生成AST的过程中,抽象化了函数命名、用户自定义标识符等,提高了模型的泛化能力;此外,添加‘unk’标识符来表示数据集中未出现的词汇。算法2描述了生成AST节点类型和节点值词汇表的过程,其中vocab_node_type为AST节点类型的词汇表,vocab_node_token为AST节点值的词汇表。步骤a)b)初始化两个带有‘unk’字符的列表,表示如果AST中存在未知的token,则将其标记为‘unk’。步骤c)~g)对AST进行遍历,依次执行以下操作:如果该节点的token不在vocab_node_token中,则将其添加到vocab_node_token列表中;如果该节点的type不在vocab_node_type中,则将其添加到vocab_node_type列表中。步骤h)输出所生成的词汇表。得到词汇表后,将带有子节点信息的AST送到单层全连接网络中得到AST的向量表示,并将其作为卷积层的输入。

算法2 词汇表的生成

2.4.2 卷积层

得到AST的嵌入后,使用一组固定深度的树卷积核Wk∈Euclid ExtraaBpd×h在整个树上滑动,对树进行卷积操作,其中h为特征检测器的数量,d为向量的维度,将相邻节点的信息通过一组卷积核汇聚到了当前节点上,并得到了当前节点的特征向量y。

为了增加模型的泛化能力和防止过拟合,在卷积层后添加一个dropout层,这样训练时会随机关闭一定比例的神经元,从而使得模型更具泛化能力。

2.4.3 池化层

对AST卷积后,对向量的每个维度应用最大池化,得到整个AST的汇总向量u后,将其送到全连接层中以得到向量表示。最终向量可以表示为

S=σ(Wu+b)(2)

其中:σ(·)为激活函数;Wu为权重矩阵;b为偏置矩阵。同样采用LeakyReLU作为激活函数。

2.4.4 对比层

对比学习着重于学习同类实例之间的共同特征,以区分非同类实例之间的不同之处。通过缩小与正样本间的距离,扩大与负样本间的距离,使正样本与锚点的距离远远小于负样本与锚点的距离,如式(3)所示。

s(f(x),f(x+))>>s(f(x),f(x-))(3)

其中:s(·)为计算样本间距离的函数; f(·)为编码器; x为锚定样本,x+为正样本,x-为负样本。

CTCNN模型使用N元组损失(N-pair loss)作为损失函数,并设置一个超参数τ来调整对负样本的惩罚。如图1右上角所示,绿色的代表锚定样本,蓝色的代表正样本,黄色的代表负样本(参见电子版)。计算得出该批次向量表示后,利用对比学习的N-pair损失函数最小化正样本之间的距离,并将负样本之间的距离最大化,最后进行模型训练和优化,对不同的代码通过计算向量之间的相似值作为是否克隆对的标准。损失函数如式(4)所示。

其中:N代表的是一个batch的样本数;sim(·)为相似度计算函数;τ为温度系数。在构建数据集的时候已经生成了正样本,因此需要设计负样本来对模型进行训练。对于每个批次,都有n对克隆对(正样本)。以第一个正样本为例,其余该批次中与正样本任务不一致的克隆对都是第一个样本的负样本,依此类推,构建出所有样本的负样本。在构造正例和负例后,通过上述损失函数得到这一批次的损失值并通过RAdam[25](rectified Adam)进行优化。RAdam是一种基于梯度的优化算法,通过采用预热启发式算法,提高了自适应学习率算法训练的稳定性、收敛速度和泛化能力。它是Adam[26](adaptive moment estimation)优化算法的改进版本。

3 实验分析

本章介绍了实验数据集、实验设置与基准模型,为探究CTCNN模型的有效性,提出以下7个问题进行探究:

a)RQ1: CTCNN在跨语言代码克隆检测中表现如何?

b)RQ2:CTCNN在不同类型的跨语言代码克隆检测效果如何?

c)RQ3:同义词转换后CTCNN的跨语言克隆检测效果如何?

d)RQ4:对比学习对CTCNN的影响如何?

e)RQ5:小样本下CTCNN性能如何?

f)RQ6: CTCNN在卷积层数不同的情况下表现如何?

g)RQ7: CTCNN的时间性能如何?

3.1 数据集介绍

在评估方法的有效性时,使用C4[5]的数据集作为实验的数据集,按照8∶1∶1的比例划分为训练集、测试集和验证集进行交叉验证,该数据集从谷歌的CodeJam(https://www.go-hero.net/jam/10/languages/0)和AtCoder(https://atcoder.jp/)编程竞赛网站中获取源码,将同一问题的不同源码解决方案作为克隆对构成正样本,Java、Python、C、C++作为跨语言克隆对,得到45 535个样本对。

3.2 评价指标

本文采用精确率P(precision)、召回率R(recall)和F1(F1 score)三个指标来评估跨语言克隆检测模型的性能。精确率P是指预测为正例的样本中,真正为正例的比例;召回率R是指实际为正例的样本中,被正确预测为正例的比例;F1值综合考虑了精确率和召回率,因此F1值通常被用来综合评估模型的性能, F1值越高,说明模型的性能越好。

其中:TP指实际为正例的样本中被正确预测为正例的数量;FP指实际为负例的样本中被错误预测为正例的数量;FN是指实际为正例的样本中被错误预测为负例的数量。

3.3 实验设置与基准模型

实验采用Tree-sitter(http://tree-sitter.github.io/tree-sitter/)工具对源码进行解析并生成AST。Tree-sitter是一种语法解析工具,它使用先进的解析算法和生成的语法树分析各种编程语言,并为它们提供语法结构。为了验证本文CTCNN方法的有效性,与CLCDSA和C4跨语言代码克隆检测方法进行了比较。CLCDSA通过度量两个矩阵之间的余弦相似性来检测跨语言的克隆代码,该矩阵是从源码中提取9个特征的值而产生的。C4利用CodeBERT模型将不同语言中的程序转换为高维向量表示,CodeBERT作为一种预训练模型,可以获取代码的上下文信息;此外,C4还通过一个能够有效识别克隆对和非克隆对的约束性学习目标来进行微调。

对于CTCNN,设置在NVIDIA A5000设备上进行训练,epoch设置为3,batch size设置为8,学习率为0.001。对于C4模型,采用相同的数据集进行训练,并遵照原文献实验设置进行实验。由于CLCDSA针对的是Java、Python和C#进行的跨语言代码克隆检测,所以从数据集中抽取包含Java和Python的克隆对,共有12 846对样本,按照8∶1∶1的比例划分训练集、测试集和验证集进行交叉验证,正样本和负样本的比例约为50%,同样遵照原文献实验设置进行实验。

3.4 实验结果与分析

3.4.1 RQ1: CTCNN模型的性能

为了测试CTCNN模型在跨语言代码克隆检测任务的效果,本文通过与目前表现最好的模型进行比较,表1和2显示了本文模型与CLCDSA、C4模型的精确度、召回率和F1值。C4模型对每个代码片段使用CodeBERT来提取代码中的特征,CodeBERT作为一种预训练模型,可以获取代码的上下文信息,因此可以获得较好的表现。与C4相比,CTCNN具有更高的F1、召回率和精确率, CTCNN的F1值提高了6.29%,召回率提高了8.97%,精准率提高了3.73%;与CLCDSA相比,CTCNN同样具有较好的表现, CTCNN的F1值提高了29.84%,召回率提高了3.84%, 精准率提高了43.92%。这表明CTCNN可以更好地学习代码的语义信息。CTCNN还可以通过改进不同编程语言AST的差异性和损失函数等来训练跨语言代码克隆检测,将在未来探索这项工作。

3.4.2 RQ2: CTCNN在不同跨语言类型的克隆检测效果

为了测试本文方法在不同类型的跨语言代码克隆的检测效果,分别对不同跨语言代码类型进行实验,实验结果如表3所示。从表中可以看出,Python和Java这两种语言的跨语言代码克隆检测得到了最高的 F1 值,为 98.25%,这意味着相对于其他组合,该模型在识别Python和Java代码时更加准确且具有更好的综合效果。而当检测C和Python语言时,该模型的精准率稍低,F1值为94.40%。

进一步分析可发现,C和Java的组合虽然召回率很高,但精确度较低。Python和C的组合精确度比较高,但是召回率较低,这可能是因为 Python和C在语法上有很大的差异,所以将它们结合起来进行检测会导致一些漏检情况的发生。而Python和Java的组合具有最高的精确度,达到了97.23%,这说明两种语言之间的区别更加明显,因此检测效果更好。

3.4.3 RQ3:同义词转换的消融实验

为了验证AST同义词转换后的效果,进行了一个消融实验来探讨同义词转换后的AST对模型性能的影响。本实验数据集共有91 070个AST,其中包含294 233 588个token,通过对AST进行同义词转换,共修改了1 043 725个token,占总数的0.35%。

由表4可以看出,在同义词转换后,CTCNN的精准率提升了0.33%,召回率提升了14.8%,F1值提升了7.77%。这主要是因为不同编程语言的AST虽然在语法的差异性较低,但是在AST节点值上仍具有一定的差异性。所以,通过统一不同编程语言AST的节点值,降低了代码解析的差异性,使得模型在语义表征方面有更好的表现。

3.4.4 RQ4: 对比学习的消融实验

为了验证对比学习对CTCNN的影响,通过调整CTCNN模型,去除CTCNN中对比学习的设置,具体步骤如下:首先,将CTCNN中的损失函数替换为交叉熵损失函数;然后,对数据集作调整,将训练集中克隆对和非克隆对的比例设置为1∶1,验证集和测试集中克隆对和非克隆对的比例设置为4∶1。将CTCNN与TCNN设置在A5000上训练1个epoch,得到的结果如表5所示。可以看到CTCNN的性能指标比TCNN更好,CTCNN 的召回率提升了0.69%,精准率提升了14.01%,F1值提升了8.22%。这表明对比学习有助于CTCNN更好地分类正负样本,从而提高模型的性能。因此,对比学习在CTCNN中起到了积极的作用。

3.4.5 RQ5: CTCNN在小样本数据的性能

为了测试本文方法在小样本情况下的优势,实验按照随机抽取样本的原则,分别取训练集中10%、20%、30%、40%数据训练3个epoch,实验结果如表6所示。当训练样本为全部的训练集时,F1值最高,为97.56%。从表6可以看到,当训练集使用的数据比较少的时候,模型的表现不如使用更多的数据进行训练,但与使用全部训练数据集进行训练得到的结果相比,没有较大的差距。最后值得注意的是,随着训练样本的增多,模型在R、P、F1这三个指标上的表现也并没有稳定增长。

总之,基于对比学习的跨语言代码克隆检测在小样本情况下也可以获得较好的结果,但是为了更好地提升模型的性能,本文还需要进一步研究如何在有限的数据情况下有效地提取和利用关键信息。

3.4.6 RQ6: 卷积层数对CTCNN的影响

当使用树的卷积神经网络进行代码的表示学习时,卷积层数的选择可以影响模型的性能。在AST上执行卷积操作是一种有限制的方式,因为AST的结构是有限的,不能像图像一样采用更深的网络来提取更高层次的特征。 所以,在卷积神经网络中增加卷积层数的主要目的是为了通过在多个层级中对语法树进行卷积操作来获取更丰富的特征。

通常,增加模型的复杂度可以提高模型在训练集上的性能,但可能会降低在测试集上的性能。因此,需要权衡模型的复杂度和性能来确定最佳的卷积层数。表7显示了CTCNN分别在卷积层数为1、2、4层的表现。可以看到卷积层数对于跨语言代码克隆检测效果有着明显的影响。增加卷积层数会提高模型的性能。这是因为在深层网络中,模型可以学习更复杂的特征表示,从而更好地区分不同的克隆实例。

3.4.7 RQ7: CTCNN的时间效率

为了测试CTCNN的训练时间性能,将本文方法与其他方法在训练1个epoch的时间开销进行对比。表8展示了本文方法与CLCDSA和C4模型的训练时长,其中:CLCDSA模型的训练时间最短,为8 s,这是由于CLCDSA模型根据特征工程提取了9个特征,需花费大量的时间对数据进行预处理;C4的训练时间约为57 min,这是由于C4使用了大型的预训练模型CodeBERT; CTCNN的训练时间平均为7 min 35 s,这表明CTCNN在训练时间上仍有一定的优势。

3.5 实例分析

CTCNN模型主要被设计用于跨语言的代码克隆检测中不同编程语言AST差异性较大的问题,通过对AST进行同义词转换,能够提高不同编程语言AST的统一表示能力,使用对比学习可以更好地区分克隆对与非克隆对,例如,图2是一对由Java和C语言组成的跨语言克隆代码,这两个代码的AST存在较大的差距,通过同义词转换后,差异性得到了显著降低,通过本文模型进行检测,结果显示这两段代码存在代码克隆关系。这进一步证明了本文模型的有效性。

3.6 有效性威胁

实验的训练集在不同类型的跨语言克隆对的数量不一致,可能会对样本量较少的跨语言代码克隆检测效果不是很友好,如3.3节RQ2中的C语言和Python语言的跨语言代码克隆检测,除了这两种语言本身差异性较大的原因,还有可能是由于训练样本量较小或样本质量不好所导致的。为了降低该部分的影响,通过仔细地对样本进行了分析,尽可能地保证不同编程语言在训练集、测试集和验证集上的比例保持一致,减少这部分的差距。

4 结束语

本文提出的CTCNN模型是一种用于检测跨语言克隆代码的模型。它通过对抽象语法树(AST)作出语义统一的处理来降低不同编程语言AST之间的差异性。同时,该模型使用了基于树的卷积神经网络学习代码表示,以获取更加丰富的语义信息。相比传统的方法,CTCNN模型利用对比学习可以训练更准确的模型,并能够提高模型的鲁棒性。然而,目前的CTCNN模型仅适用于树结构的代码表示,并仅对AST的节点类型和节点值进行了语义统一的处理。在未来的工作中,主要目标是如何基于对比学习,使用图结构的网络模型对源码进行表征。这将使得模型具有更好的可扩展性和泛化能力,同时也能更好地应对不同编程语言的差异性。此外,还需要对不同编程语言的关键词、标识符、操作符等进行语义统一的处理。这可以通过引入预处理步骤来实现,例如使用自然语言处理技术来提取关键词的语义信息,并将不同语言的关键词映射到一个通用的向量空间中,从而降低不同语言之间的差异性。综上所述,CTCNN模型是一种有前途的方法,可用于跨语言克隆代码的检测。未来的工作可以将其扩展到图结构的代码表示,并对不同编程语言的关键词、标识符、操作符等进行语义统一的处理。这将使得该模型更具适应性和泛化能力,从而实现更准确的检测效果。

参考文献:

[1]Roy C K,Cordy J R,Koschke R. Comparison and evaluation of code clone detection techniques and tools: a qualitative approach[J]. Science of Computer Programming,2009,74(7): 470-495.

[2]Cheng Xiao,Peng Zhiming,Jiang Lingxiao,et al. Mining revision histories to detect cross-language clones without intermediates[C]// Proc of the 31st IEEE/ACM International Conference on Automated Software Engineering. Piscataway,NJ: IEEE Press,2016: 696-701.

[3]Fanta R,Rajlich V.Removing clones from the code[J].Journal of Software Maintenance: Research and Practice,1999,11(4):223-243.

[4]Tao Chenning,Zhan Qi,Hu Xing,et al. C4: contrastive cross-language code clone detection[C]//Proc of the 30th IEEE/ACM International Conference on Program Comprehension. 2022: 413-424.

[5]Vislavski T,Rakic' G,Cardozo N,et al. LICCA: a tool for cross-language clone detection[C]//Proc of the 25th IEEE International Conference on Software Analysis,Evolution and Reengineering.Pisca-taway,NJ:IEEE Press,2018: 512-516.

[6]Nafi K W,Kar T S,Roy B,et al. CLCDSA: cross language code clone detection using syntactical features and API documentation[C]// Proc of the 34th IEEE/ACM International Conference on Automated Software Engineering. Piscataway,NJ:IEEE Press,2019:1026-1037.

[7]Ling Huading,Zhang Aiping,Yin Changchun,et al. Improve representation for cross-language clone detection by pretrain using tree autoencoder[J]. Intelligent Automation & Soft Computing,2022,33(3): 1561-1577.

[8]Rakic' G. Extendable and adaptable framework for input language independent static analysis[D]. Novi Sad: University of Novi Sad,2015.

[9]Bui N D Q,Yu Yijun,Jiang Lingxiao. InferCode: self-supervised learning of code representations by predicting subtrees[C]//Proc of the 43rd IEEE/ACM International Conference on Software Enginee-ring. 2021: 1186-1197.

[10]Mou Lili,Li Ge,Zhang Lu,et al. Convolutional neural networks over tree structures for programming language processing[C]// Proc of the 30th AAAI conference on artificial intelligence. Palo Alto,CA: AAAI Press,2016: 1287-1293.

[11]Kamiya T,Kusumoto S,Inoue K. CCFinder: a multilinguistic token-based code clone detection system for large scale source code[J]. IEEE Trans on Software Engineering,2002,28(7): 654-670.

[12]Feng Zhangyin,Guo Daya,Tang Duyu,et al. CodeBERT: a pre-trained model for programming and natural languages[C]// Proc of Conference on Empirical Methods in Natural Language Processing. Stroudsburg,PA: Association for Computational Linguistics,2020: 1536-1547.

[13]Perez D,Chiba S. Cross-language clone detection by learning over abstract syntax trees[C]//Proc of the 16th IEEE/ACM International Conference on Mining Software Repositories. 2019: 518-528.

[14]Narayanan A,Chandramohan M,Chen Lihui,et al. subgraph2vec: learning distributed representations of rooted sub-graphs from large graphs[EB/OL].(2016). https://arxiv.org/abs/1606.08928.

[15]Yang Shouguo,Cheng Long,Zeng Yicheng,et al. Asteria: deep lear-ning-based AST-encoding for cross-platform binary code similarity detection[C]//Proc of the 51st Annual IEEE/IFIP International Conference on Dependable Systems and Networks. 2021: 224-236.

[16]Shido Y,Kobayashi Y,Yamamoto A,et al. Automatic source code summarization with extended Tree-LSTM[C]//Proc of International Joint Conference on Neural Networks. 2019: 1-8.

[17]Zhang Feng,Li Guofan,Liu Cong,et al. Flowchart-based cross-language source code similarity detection[J]. Scientific Programming,2020,2020: 1-15.

[18]Cheng Xiao,Peng Zhiming,Jiang Lingxiao,et al. CLCMiner: detecting cross-language clones without intermediates[J]. IEICE Trans on Information and Systems,2017,100(2): 273-284.

[19]Nafi K W,Roy B,Roy C K,et al. CroLSim: cross language software similarity detector using API documentation[C]//Proc of the 18th International Working Conference on Source Code Analysis and Manipulation. 2018: 139-148.

[20]Bui N D Q,Yu Yijun,Jiang Lingxiao. Bilateral dependency neural networks for cross-language algorithm classification[C]//Proc of the 26th IEEE International Conference on Software Analysis,Evolution and Reengineering. 2019: 422-433.

[21]Bromley J,Guyon I,LeCun Y,et al. Signature verification using a “siamese” time delay neural network[C]// Advances in Neural Information Processing Systems. 1993: 737-744.

[22]Yu Yong,Si Xiaosheng,Hu Changhua,et al. A review of recurrent neural networks: LSTM cells and network architectures[J]. Neural Computation,2019,31(7): 1235-1270.

[23]Groh F,Ruppert L,Wieschollek P,et al. GGNN: graph-based GPU nearest neighbor search[J]. IEEE Trans on Big Data,2022,9(1): 267-279.

[24]Yahya M A,Kim D K. CLCD-I: cross-language clone detection by using deep learning with InferCode[J]. Computers,2023,12(1):12.

[25]Liu Liyuan,Jiang Haoming,He Pengcheng,et al. On the variance of the adaptive learning rate and beyond[C]//Proc of International Conference on Learning Representations.2020.

[26]Kingma D,Ba J. Adam: a method for stochastic optimization[EB/OL].(2014). https://arxiv.org/abs/1412.6980.