一种基于文档的库函数的代码模型的自动合成方法与流程

文档序号:12664347阅读:153来源:国知局
一种基于文档的库函数的代码模型的自动合成方法与流程

本发明涉及一种基于文档的库函数的代码模型的自动合成方法,主要利用自然语言处理技术和自动化测试技术来解决库函数的代码模型的自动生成问题,进而提高其它程序分析技术的正确性和效率。属于软件工程、程序合成领域。



背景技术:

在现代的程序中,类库被广泛使用,类库的行为是软件行为中不可分割的一部分,对软件程序进行分析的时候,这些类库也应该被分析。然而分析类库是一件非常困难的事情,首先,在很多情况下,类库的源代码是无法获取的。即使可以获取源代码,代码通常也非常复杂,比如包含高度优化的代码、复杂的工程技巧,或者是由多种语言实现,这一系列的原因都导致分析类库源代码非常困难。

目前有很多研究工作人工为类库建立模型,通过对模型的分析来替代对类库的分析。然而,人工建模不仅耗时,而且容易出错。另外还有一些研究工作通过动态执行程序来跟踪输入输出之间的关系,这种方法依赖于测试用例的充分度,而且输入输出之间的依赖关系无法反应类库的精确行为。



技术实现要素:

技术问题:类库的文档中通常包含了丰富的信息,描述了类库的行为,因此,本发明的目标是从文档中抽取有用信息,根据这些信息,综合使用自然语言处理技术与自动化测试技术为类库自动生成代码模型。代码模型模拟了类库的行为,解决了程序分析过程中由于源代码缺失或者源代码过于复杂导致难以分析等问题,有效地提高其它程序分析技术的有效性和效率。

技术方案:给定一个Java API函数,本发明使用自然语言处理工具生成每个句子的语法树,然后在语法树中识别参数和程序结构生成树结构形式的中间表示,接着将中间表示与预定义的一组原语的树模板进行匹配,每个原语是由一个树模板以及该树模板所对应的代码模板组成。在匹配过程中,本发明尝试用若干个原语的树模板对中间表示进行覆盖,当找到合适的树模板将中间表示覆盖完全后,使用中间表示中对应的节点信息来实例化树模板中的节点,实例化的结果是与树模板匹配的子树所对应的代码片段,将这些代码片段组合起来生成一个代码模型。由于自然语言的二义性以及参数识别过程中的不确定性等,每个句子可能对应多个中间表示,此外,每个中间表示可能有多个覆盖方法,因此可能生成多个候选的代码模型,本发明使用测试技术过滤掉与原始的类库具有行为不一致的候选模型。本方法包括以下步骤:

步骤1:从文档中抽取类和函数的描述信息,例如函数的声明、函数的行为描述等。

步骤2:对步骤1抽取的信息进行等价分析、冗余信息删除以及语句增强。

步骤3:使用自然语言处理工具为经过步骤2处理的每一个自然语言句子生成一棵语法树,这棵树给出了每个单词的词性,同时标记了不同的短语。

步骤4:将步骤3生成的语法树进行节点变换生成多个变体,不同变体表示不同的语义。

步骤5:识别步骤4中生成的语法树中表示参数的节点以及从语法树中识别出程序的结构,即循环结构和分支结构,为语法树生成相应的中间表示。

步骤6:结合给定的原语,为步骤5生成的中间表示合成对应的代码片段,然后将一个函数的所有中间表示对应的代码片段组合起来生成每一个函数的模型,然后将不同函数的模型组合起来生成类的模型。

步骤7:使用测试工具对步骤6生成的候选的代码模型进行测试,过滤那些与类库具有行为不一致的候选模型。

有益效果:本发明所述的基于文档的库函数的代码模型的自动构造方法所生成的代码模型模拟了类库的行为,模型的代码实现更加简单,复杂性低,不会调用本地方法等,代码模型的平均代码行数是原始类库中函数的1/3,而且调用函数简洁清晰。代码模型可以有效地辅助其它程序分析技术,比如库函数的规约生成技术、静态污点分析技术以及动态切片技术等。具体而言:

(1)将生成的代码模型应用于静态污点分析技术中,结果显示使用代码模型可以有效地提高静态污点分析的正确性,发现一些使用源代码无法发现的信息泄露路径,同时还可以提高分析的效率。

(2)将生成的代码模型应用于动态切片技术中,结果显示使用代码模型生成的切片大小远远小于使用朴素模型所生成的切片大小,而且还可以提高分析的效率,这主要得益于代码模型提供了函数功能的简单而准确的实现,对代码模型进行分析时可以得到输出与输入之间的精确的依赖关系,而朴素模型的依赖关系过多而且很多是不准确的。

附图说明

图1是基于文档的库函数的代码模型的自动构造方法的流程图。

图2是本发明实施例的ArrayList类中indexof方法的文档示例图。

图3是本发明实施例的语法树图一。

图4是本发明实施例的语法树图二。

图5是本发明实施例的语法树图三。

图6是本发明实施例的中间表示示意图。

图7是本发明实施例的覆盖示意图。

图8是本发明实施例的代码片段。

具体实施方式

下面结合实施例和说明书附图对本发明做进一步说明。

图1是基于文档的库函数的代码模型的自动构造方法的流程图。本实施例给出了一种基于文档的库函数的代码模型的自动合成方法。包括如下步骤:1.从文档中抽取有用信息;2.对抽取的描述语句进行预处理。3.使用自然语言处理工具生成句子的语法树;4.对步骤3中生成的语法树进行结构上的变换生成多个语法树的变体;5.对步骤4中生成的语法树进行分析,识别其中的参数、程序结构以及操作语义的中间表示;6.生成候选的代码模型;7.对步骤6中的候选模型进行检验,删除与原始的类库具有行为不一致的候选模型。本发明综合使用了自然语言处理技术与自动化测试技术,成功地为Java容器类生成了代码模型,生成的代码模型可以有效地提高其它程序分析技术的正确性和效率,解决了程序分析过程中由于类库源代码缺失或者类库源代码过于复杂导致难以分析等问题。

本实施例通过图2中展示的ArrayList类中indexof方法的文档为例进行详细说明。

一.从文档中抽取信息

在具体实施中,本发明以HTML格式的Javadoc文档作为输入,从中抽取类的信息和函数的信息。针对类,主要提取包名和类的声明。针对函数,主要抽取(1)函数的声明;(2)参数名以及相应的解释部分;(3)描述函数行为的语句;(4)描述函数返回值的语句;(5)描述函数抛出的异常以及抛出异常的条件。

二.预处理

本发明对抽取的描述语句进行预处理,主要包括下面三个方面:

(1)等价分析:将词语按照领域字典进行等价类的划分,以减少重复处理。例如,在函数的行为描述中,insert和add是语义等价的。

(2)删除冗余信息:尝试删除用于解释其它语句的句子。例如,图2中以“more formally”开头的句子是进一步解释其前面的句子。

(3)增强语句:在Javadoc中的返回值描述和异常描述中的语句往往是不完整的,本发明尝试将这类语句补充完整。

三.为自然语言句子生成语法树

本发明使用自然语言处理工具Stanford Parser为每一个经过预处理的句子生成语法树,识别出句子中单词的词性、短语结构等。有些单词在计算机领域中具有固定的词性,但是Stanford Parser并不具备领域知识,因此,本发明开发了一个词性限制模块,引导Stanford Parser将和计算机程序领域相关的词汇标记为期望的词性。针对图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所示的语法树。

四.变换语法树结构生成多个变体

本发明将Stanford Parser生成的语法树进行结构的变换生成不同的变体,每个变体表示不同的语义。

为了解决自然语言的模糊性,当用户指定一个数值K时,Stanford Parser返回K棵不同语义的语法树。如果将K的值设置的很大来提高生成正确语法树的概率,那么将花费大量的时间来分析语法树,会带来性能问题。而且,即使K的值很大,也无法保证一定可以生成正确的语法树。

本发明所分析的句子属于一类特定的领域,通过对语法树进行结构上的变换可以得到表达正确语义的语法树。当句子中出现“,or”或者“,and”时,往往会出现歧义。针对这种情况,本发明通过将概率最高的语法树中的“,or”或者“,and”以及所有的右兄弟节点向上移动或者向下移动若干次来生成正确的语法树。针对图3中的语法树,本发明将通过将“,”、“or”以及“-1if this list does not contain the element”节点向上移动五次可以得到图4所示的语法树,图4中的语法树是这个句子真正想要表达的语义。

五.生成中间表示

本发明将根据领域知识在语法树中识别出参数和程序结构来构造树结构形式的中间表示。

(1)识别参数

文档对参数的描述并不是杂乱无章的,而是有规律可循的。因此,本发明根据规则在句子中识别出参数的载体。鉴于自然语言的这种模糊性,当系统无法确定单词或者词组是否描述的是参数时,系统将分两种情况进行建模,一种情况将描述视为参数,另一种情况认为描述的并非参数,由最后一步的模型过滤器排除错误的情况。针对图4中的语法树,本发明将“the specified element”与参数o关联起来,而本发明在这一步中无法确定“the element”是否描述的是参数o,因此,本发明将两种可能的情况均视为候选。

在Javadoc中,当出现词组“this WORD”,而“WORD”又是当前所处理的类的名字或者类名的缩写时,本发明将给这棵子树添加“this”标签。这个标签代表这个操作的对象是执行该操作的实例。例如,在图4中出现的“this list”,它表示操作是针对类java.util.ArrayList的对象的。

经过参数的识别之后,本发明将图4中的语法树变换为图5中的语法树。

(2)识别程序结构

在缺省情况下,本发明将默认程序语句是按照顺序依次执行的,因此,本发明只在语法树中识别循环结构和分支结构。

针对循环结构,在自然语言中,复数名词以及用each修饰的单数名词往往表示句子所描述的行为将被重复执行多次,因此需要一个循环结构。但有些时候,循环并没有这么明显。例如,“the first occurrence of”这个短语暗示了循环迭代的顺序,这时也需要一个循环结构,本发明将在语法树的节点中添加“ltr”(left to right)标签,同时将表示“the first occurrence of”的子树删除。

对于分支结构而言,单词“if”和“when”表示一个if分支,“otherwise”表示一个else分支。本发明将添加相应的标签(“if”和“else”)到对应的子树并删除中间表示。针对图5中的语法树,本发明将点中并删除表示“if”的节点,生成图6中所示的“-1tag:if”节点。需要注意的是,本发明同时仔细判断了条件描述是肯定的还是否定的从而决定if条件。图5中的“contain”是被“does not”修饰的,这表示该if分支中包含的行为是在“contain”行为结果的相反情况下触发的,在这种情况下,本发明删除表示“does not”的子树并在表示“contain”的树节点中添加标签“-”,如图6中的“contain:-”节点。

经过程序结构的识别之后,本发明根据图5中所示的语法树生成图6中的中间表示。

六.生成候选的代码模型

本发明在中间表示中识别操作语义生成候选的代码模型。本发明定义了一些原语,每个原语包含一个树模板和树模板对应的代码模板。本发明从中间表示的根节点开始,使用树模板对中间表示进行覆盖,当中间表示被覆盖完全后,本发明将这些树模板对应的代码模型进行实例化来生成中间表示对应的代码片段。针对图6中的中间表示,本发明将为其生成图7所示的覆盖和图8所示的代码片段。当生成了每个中间表示的代码片段之后,本发明将每个函数的文档中所有句子的中间表示的代码片段进行组合生成函数的代码模型,接着将各个函数的代码模型进行组合生成类的代码模型。一个句子可能有多个中间表示,因此,本发明可能为一个函数生成多个代码模型,同样地,也可能为一个类生成多个代码模型。

七.删除错误的候选模型

并不是所有的语法树都表示了正确的语义,因此,本发明将使用测试技术来过滤掉错误的代码模型。对于任意的候选类模型,本发明首先对其进行编译并使用Randoop工具为其生成单元测试用例,这些测试用例体现了候选类模型的行为。然后,在原始的JDK类库上运行这些测试用例。如果有一个测试用例失败,这就意味着候选的类模型和原始的类库存在行为不一致,那么本发明就将该候选类模型舍弃。如果某个候选的类模型的测试用例全部通过,那么本发明认为该候选是所期望的类库的代码模型。

本发明已以较佳实施例公开如上,但它们并不是用来限定本发明,凡不脱离本发明之精神和范围内,自当可作各种变化或润饰,因此本发明的保护范围应当以本申请的权利要求保护范围所界定的为准。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1