一种面向Java原型系统的自动验证方法及系统与流程

文档序号:30529113发布日期:2022-06-25 09:23阅读:166来源:国知局
一种面向Java原型系统的自动验证方法及系统与流程
一种面向java原型系统的自动验证方法及系统
技术领域
1.本发明涉及软件技术领域,具体涉及一种面向java原型系统的自动验证方法及系统。


背景技术:

2.软件技术需要不断的更新和完善,因此在改进软件的过程中代码会变得越来越复杂,维护软件的时间成本和金钱成本都在不断的增加。在此过程中,程序验证可以提前预判可能会出现的错误,会节省很大的人力物力成本,使软件更新和完善过程变得更简单化。但在目前能实现的程序验证的方法或工具中只能验证一些程序片断或是一些逻辑较为简单的程序,对于类似由需求模型生成的原型系统的java程序或者稍复杂的java程序没办法验证。在程序验证的过程中,简化程序技术起到了很大的作用,该技术可以对原程序进行增删查改,使得要验证的程序重点和逻辑更突出。
3.在现有的简化代码技术中,一些是针对程序中循环语句进行简化,一些是通过特定方法的调用来实现java程序编写的简化,还有一些通过特定技术的实现来对java程序进行简化。这些简化的工作中都有各自的特定,但针对具体函数体的简化,例如:修改数据类型、删除不必要的变量、修改if语句、简化for语句等简化操作是无法实现的。与此同时针对验证过程需要的合约,需要的时候都是以手动添加的方式实现,目前还不具备自动生成的功能。


技术实现要素:

4.有鉴于此,本技术实施例提供一种面向java原型系统的自动验证方法及系统,本技术实施例基于由需求模型生成原型java系统,通过抽象语法树的理论和技术,实现每一个类以及每一个方法的简化,并且对原型生成的java程序进行解析、修改简化,再转为java程序,同时实现原型java程序的ocl(object contraint language对象约束语言)合约自动生成jml(java modeling language java建模语言)格式的合约,最后采用key工具对基于jml合约的简化版原型java系统进行验证。
5.本技术实施例提供以下技术方案:一种面向java原型系统的自动验证方法,包括如下步骤:
6.由需求模型生成原型java程序;
7.对所述原型java程序进行简化,得到简化版原型java程序;
8.在所述简化版原型java程序中加上jml前后置条件,得到基于jml的原型java程序;
9.对所述基于jml的原型java程序进行验证。
10.进一步地,采用抽象语法树对所述原型java程序进行简化,得到所述简化版原型java程序。
11.进一步地,采用抽象语法树对所述原型java程序进行简化的过程具体包括:
12.将所述原型java程序解析为抽象语法树;
13.对抽象语法树进行修改和重写,得到简化抽象语法树;
14.将简化抽象语法树转为java程序,得到所述简化版原型java程序。
15.进一步地,将所述原型java程序解析为抽象语法树,再对抽象语法树进行修改和重写的过程中,具体实现的规则包括:读取文件规则、新建抽象语法树规则、获取方法规则、修改数据类型规则、删除规则、替换规则、定义新变量规则、增加方法调用规则、简化for循环规则。
16.进一步地,在所述简化版原型java程序中加上jml前后置条件的过程具体包括:
17.确定ocl合约转为jml合约的映射规则;
18.在xtend模板中编辑对应的所述映射规则;
19.运行后生成jml前后置条件。
20.进一步地,所述映射规则包括:基本数据类型映射规则、属性表达式映射规则、集合操作映射规则、ocl结构映射规则、方法规范的映射规则。
21.进一步地,采用key工具对所述基于jml的原型java程序进行验证。
22.本技术实施例还提供一种面向java原型系统的自动验证系统,包括:
23.原型生成模块,用于由需求模型生成原型java程序;
24.简化模块,用于对所述原型java程序进行简化,得到简化版原型java程序;
25.jml前后置条件自动生成模块,用于在所述简化版原型java程序中加上jml前后置条件,得到基于jml的原型java程序;
26.验证模块,用于对所述基于jml的原型java程序进行验证。
27.进一步地,所述简化模块采用抽象语法树,经过解析、修改和重写,最后将结果转为java程序,得到所述简化版原型java程序。
28.进一步地,所述jml前后置条件自动生成模块通过xtend模板完成所述简化版原型java程序的ocl合约自动生成jml合约,并在所述简化版原型java程序中加上已生成的jml合约,得到基于jml的原型java程序。
29.与现有技术相比,本说明书实施例采用的上述至少一个技术方案能够达到的有益效果至少包括:本发明实施例基于由需求模型生成原型java系统出发,通过抽象语法树的理论和技术,针对原型生成的java程序,可以对java程序每一个类以及每一个方法进行具体简化,通过抽象语法树来对原型生成的java程序进行解析、解析完之后修改简化、将修改后的结果转为java程序,在此之后通过xtend模板实现原型java程序的ocl合约自动生成jml格式的合约。本发明实施例有效提高了验证效率和精准性,节省人力物力成本,使软件更新和完善过程变得更简单化。
附图说明
30.为了更清楚地说明本技术实施例的技术方案,下面将对实施例中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本技术的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其它的附图。
31.图1是本发明实施例的自动验证方法流程示意图;
32.图2是本发明实施例的自动验证结构示意图;
33.图3是本发明实施例中简化过程流程示意图;
34.图4是本发明实施例中读取文件规则示意图;
35.图5是本发明实施例中新建ast规则示意图;
36.图6是本发明实施例中获取方法规则示意图;
37.图7是本发明实施例中修改数据类型规则示意图;
38.图8是本发明实施例中删除规则示意图;
39.图9是本发明实施例中替换规则示意图;
40.图10是本发明实施例中增加规则示意图;
41.图11是本发明实施例中简化for循环规则示意图;
42.图12是本发明实施例的自动验证系统结构示意图。
具体实施方式
43.下面结合附图对本技术实施例进行详细描述。
44.需要说明的是,在不冲突的情况下,本技术中的实施例及实施例中的特征可以相互组合。下面将参考附图并结合实施例来详细说明本发明,对本发明的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
45.如图1所示,本发明实施例提供了一种面向java原型系统的自动验证方法,包括:首先由需求模型生成原型java程序;对所述原型java程序进行简化,得到简化版原型java程序;再在所述简化版原型java程序中加上jml前后置条件,得到基于jml的原型java程序;最后对所述基于jml的原型java程序进行验证。
46.本发明实施例基于由需求模型生成原型java系统出发,通过抽象语法树的理论和技术,针对原型生成的java程序,可以实现每一个类以及每一个方法的简化。通过抽象语法树来对原型生成的java程序进行解析、解析完之后修改简化、将修改后的结果转为java程序,在此之后通过xtend模板实现原型java程序的ocl合约自动生成jml合约,并在所述简化版原型java程序中加上生成的jml合约,得到基于jml合约的原型java程序,最后用key工具对基于jml合约的原型java系统进行验证,有效提高了验证效率和精准性。
47.如图2所示,本发明第一实施例具体包括以下步骤:
48.s101、由需求模型生成原型java程序;
49.该步骤是由需求模型通过rm2pt工具自动生成原型java程序;
50.s102、对所述原型java程序进行简化,得到简化版原型java程序;
51.本实施例采用抽象语法树和相应的简化规则来对所述原型java程序进行简化,得到所述简化版原型java程序。抽象语法树,简称ast(abstract syntax tree),或简称语法树(syntax tree),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。
52.具体实施时,如图3所示,采用抽象语法树对所述原型java程序进行简化的过程具体包括:
53.s201、将所述原型java程序解析为抽象语法树;
54.在解析过程中,具体实现的规则如下,如图4和图5所示:
55.(1)读取文件规则(read file rule)
56.通过文件输入流来读取要简化的原型java文件,结果是把读取到的原型java文件转为字符串型。该规则一次只能读取一个java文件。
57.(2)新建ast规则(new ast rule)
58.调用eclipse中的jdt插件自带org.eclipse.jdt.core.dom_*类,通过createast方法来生成一颗以源文件为参数的抽象语法树。
59.s202、对抽象语法树运用规则进行修改和重写,得到简化抽象语法树;
60.在修改和重写过程中,具体运用的规则如下:
61.(1)获取方法规则(gets method rule)
62.如图6所示,以抽象语法树为头结点,逐级往下调用子结点。类型声明是抽象语法树的第一级子结点,方法是类型声明的子结点,因此为第二级子结点。每次调用都会得到整个源文件的方法子结点。
63.(2)修改数据类型规则(modify data type rule),如图7所示;
64.a、修改方法的数据类型。逐级遍历整颗抽象语法树,通过方法头结点来得到每个方法的子结点。从而得到一颗子方法抽象语法树。修改方法的数据类型要找到该数据类型所在结点,调用setreturntype2方法用新建的数据类型替换之前的数据类型。
65.b、修改方法参数的数据类型。逐级遍历整颗抽象语法树,通过方法头结点来得到每个方法的子结点。从而得到一颗子方法抽象语法树。修改方法参数的数据类型要找到该数据类型所在结点,调用settype方法用新建的数据类型替换之前的数据类型。
66.(3)删除规则(delete rule)
67.如图8所示,删除规则包括删除注释、删除变量、删除语句等。在以子方法的抽象语法树中,找到删除对象所在的结点,直接调用remove方法或者是delete方法来进行删除。调用remove方法时,注意参数的变化,删掉对象之后,下一个对象就会前移。
68.(4)替换规则(replace rule)
69.如图9所示,替换规则在此指的是变量替换本地的get、set方法。在以子方法的抽象语法树里,找到调用get、set方法的结点,通过newsimplename方法新建要替换的变量名,最后是替换整个调用get、set方法的表达式的左右两边的值,以及中间的操作符来完成整个替换操作。
70.(5)增加规则(increase the rules),如图10所示;
71.a、定义新变量规则。找到所要生成变量的结点位置,通过生成变量表达式的形式去完成定义新变量的操作。由newsimplename方法生成表达式左边的值,右边的值的不确定型也决定了调用的方法不同,再调用对应操作符的方法来完成整个变量表达式的生成。
72.b、增加方法调用规则。找到所要增加方法调用的结点位置,同样是以生成表达式的形式来完成该规则的操作,确定newsimplename方法生成的变量。名称不同的是,在生成方法的时候要newmethodinvocation方法生成的对象来链接调用的方法。
73.(6)简化for循环规则(simplify for loop rule)
74.如图11所示,把增强的for循环改为一般的for循环。找到所要简化for循环的结点位置。在删除增强的for循环后,通过新建一般的for循环来完成该规则的操作。新建时要确
定for循环的初始化表达式、条件表达式以及更新表达式。每一个表达式都以新建表达式的方式来完成,不同的是每个变量以及表达式的值。把最后新建完成的一般for循环添加在原来的结点位置。
75.具体方法步骤如下:
76.1.1:通过eclipse安装jdt插件,由于ast用到org.eclipse.jdt.core.dom_*类,因此要下载相应的jar包配置程序运行时要用到的依赖库;
77.1.2:解析ast。
78.首先要创建解析器astparser parsert=astparser.newparser(ast.jls3);
79.然后把要解析的java源文件以文件的形式来作为解析器源代码的参数
80.parsert.setsource(content.tochararray());
81.最后是使用解析器进行解析并返回ast上下文结果,compilationunit为根结点
82.compilationunit result=(compilationunit)parsert.createast(null);
83.1.3:修改ast。
84.a、修改数据类型:把float型改为int型。修改方法参数的数据类型,即把float参数类型改为int型,要获取到相应方法的参数类型在ast中的结点变量和类型,然后新建好int型的变量primitivetype typeint=ast.newprimitivetype(primitivetype.int);最后对该结点变量进行修改nametype.settype(typeint)。
85.b、删除不必要的变量:把最终程序不需要的变量删除。从ast中找到需要删除变量的结点,此时得到的是一个该方法所有语句的列表,然后直接调用list中的remove方法对变量进行删除。
86.c、修改if语句:即修改if语句的具体内容。第一步是找到改写if语句即ifstatement的结点,第二步确定该if语句的左语句和右语句以及构成该if语句的操作符,通过simplename fundspwdvalite=ast.newsimplename()构建新的左语句、通过booleanliteral nameptrue=ast.newbooleanliteral()构建新的右语句,第三步是通过setleftoperand()方法对左语句进行修改、setrightoperand()对右语句进行修改、setoperator()对操作符进行修改。每一个if语句都是如此修改。
87.d、重写for循环:把增强for循环改写为一般的for循环。第一步要把原java程序中的增强for循环删掉,第二步开始新建一般的for循环语句,首先要了解新建的一般for循环的树状结构。然后通过forstatement namefor=ast.newforstatement()语句来新建for语句的对象,紧接着构建for循环的具体内容。
88.首先是for循环的初始化表达式。因为是个表达式,因此要构建assignment表达式,先通过newsimplename()方法和newnumberliteral()方法构建assignment表达式左右两边的值,然后通过setlefthandside()方法对assignment表达式左边进行赋值,通过setrighthandside()方法对assignment表达式右边进行赋值,通过setoperator()方法对assignment表达式的操作符进行赋值。完成以上操作后要通过initializers().add()的方法把assignment表达式加入到新建的for循环的对象中。
89.其次是for循环的条件表达式。for循环条件表达式要通过infixexpression表达式来构建,首先通过newsimplename()方法确定infixexpression表达式左边的值,然后通过newqualifiedname()方法来确定infixexpression表达式右边的值,最后通过
setleftoperand()方法对infixexpression表达式左边进行赋值,通过setrightoperand()方法对infixexpression表达式右边进行赋值,通过setoperator()方法对infixexpression表达式的操作符进行赋值。完成以上操作后要通过setexpression()方法把infixexpression表达式加入到新建的for循环的对象中。
90.最后是for循环的更新表达式。for循环的更新表达式要通过postfixexpression表达式来构建,更新表达式是一个递增或者递减的动作,所以通过newsimplename()方法确定递增或递减的变量,然后通过setoperator()方法实现递增或者递减操作。完成以上操作后要通过updaters().add()方法把postfixexpression表达式加入到新建的for循环的对象中。第三步要构建循环体内容。通过block去构建整个循环体的内容,循环体的具体内容要根据新建for循环的ast树状结构来具体构建。无论是表达式、一般的变量声明、还是if语句都可以构建。最后通过statements().add()添加方法,按照顺序把这些具体语句逐一加入到block中。在完成以上操作之后通过setbody()方法把循环体的内容加入到新建的for循环中。
91.s203、将简化抽象语法树转为java程序,得到所述简化版原型java程序。
92.该步骤中,在最后的结果中,由文件输出流(fileonputstream)来解析修改后的字符串,最后把字符串转为java文件,并输出到指定的位置。
93.s103、在所述简化版原型java程序中加上jml前后置条件,得到基于jml的原型java程序;
94.前后置条件的添加工作主要是借助eclipse中的xtend工具自动生成。生成的前提是确定ocl转为jml的映射规则,其次是在xtend模板中编辑好对应的映射规则,最后就是运行得到jml前后置条件。
95.ocl(object contraint language对象约束语言)是一种用于施加在指定的模型元素上约束的语言。ocl表达式以附加在模型元素上的条件和限制的形式来指定规则。这包括附加在模型元素上的不变量或者约束的表达式,附加在操作和方法上的前置和后置条件,监护条件,以及模型元素之间的导航。
96.其中提到的ocl转为jml的映射规则主要分为以下几种:
97.(1)基本数据类型映射规则:ocl中的基本数据类型分为boolean类型、integer类型、real类型、string类型。相对应的与jml的映射规则如下表1所示:
98.表1:基本数据类型映射规则
99.ocljmland&&or||not!implies==》=《==》integerlongrealdoublestringstring
100.(2)属性表达式映射规则:property类表示所有ocl表达式,包括集合类型的属性
(如集合上的运算,模型元素和查询表达式上的导航等。),形如:e=source.property的表达式,其映射规则为:
[0101][0102]
(3)集合操作映射规则:ocl支持三种集合类型,分别是set、bag、sequence,并提供了公共的集合类collection(t),作为set(t)、orderedset(t)、bag(t)、sequence(t)的父类。针对ocl支持的集合类型,jml定义了一些模型类型来表示各种不同的java类的集合。对应规则如下ocl与jml布尔运算对应关系表2所示:
[0103]
表2:ocl与jml布尔运算对应关系表
[0104][0105]
a、当类型t是基本数据类型之一,set(t)被映射到jmlvalueset。每一个集合类型set(t)的集合s,被映射到类型为jmlvalueset的集合,并另外附加一条约束:被转换的集合元素都属于一个相应的jml类型。
[0106]
例子:若s是set(boolean)的,则对应的集合μ(s)属于jmlvalueset满足约束规则为:
[0107]
(\forall boolean e;μ(s).has(e);e instanceof jmlboolean)
[0108]
b、如果类型t是对象类型,则set(t)被映射到jmlobjectset。每一个集合s被映射到类型jmlobjectset的对应集合,并附加如下约束:被转换的集合元素都属于一个相应的jml类型。
[0109]
例子:给定类student代表student对象,一个集合s:set(student)被映射到类型jmlobjectset的集合,满足的约束规则为:
[0110]
(\forall object p;μ(s).has(p);p instanceof student)
[0111]
等价的映射规则:ocl集合之间等价关系用符号“=”标记,jml中用“==”表示,这类关系的映射规则为:
[0112]
(4)其他ocl结构映射规则:
[0113]
a、表达式e=exp@pre出现在后置谓词中,用来引用操作执行前exp的值,在jml中,\old表达式与之效果一致。映射规则为:μ(e)=\old(μ(exp))
[0114]
b、表达式e=exp.ocllsnew()返回真,当表达式exp指向一个新创建的对象;反之返回假。在jml的映射规则为:μ(e)=\fresh(μ(exp))
[0115]
c、表达式e=result表示操作的返回结果,jml中用\result代替,映射规则为:μ(e)=\result
[0116]
(5)方法规范的映射规则:
[0117]
在ocl和jml中,方法行为都使用前置谓词和后置谓词的形式,ocl方法规范形式如下:
[0118]
e=context c::m(p1:t1,

,pn:tn)
[0119]
pre:ocl-pre
[0120]
post:ocl-post
[0121]
转为jml方法规范的映射规则为:
[0122]
μ(e)=normal_behavior
[0123]
requiresμ(ocl-pre);
[0124]
assignable getassignablevairablelistμ(ocl-post);
[0125]
ensuresμ(ocl-post);
[0126]
在映射过程中,ocl的前置谓词pre映射为requires,后置谓词post映射为ensures。第一行由于ocl不支持对异常的规范,所以使用方法正常结束自子句。assignable子句给出了一个框架特性,只有在其中列出的变量才能在方法的实现中修改。
[0127]
s104、对所述基于jml的原型java程序进行验证。
[0128]
本实施例采用key工具对所述基于jml的原型java程序进行验证。
[0129]
key工具是一个专门验证java程序的工具,使用动态java逻辑来对java程序的语法逻辑进行验证,该验证工具首先把java程序转化为javadl的形式,然后运用该工具里面的taclet规则对javadl进行验证,最后通过证明树来呈现每一步的验证过程及最后的验证结果。
[0130]
如图12所示,本发明实施例还提供了一种面向java原型系统的自动验证系统200,包括原型生成模块201、简化模块202、jml前后置条件自动生成模块203和验证模块204。原型生成模块201用于由需求模型生成原型java程序;简化模块202用于对所述原型java程序进行简化,得到简化版原型java程序;jml前后置条件自动生成模块203,用于在所述简化版原型java程序中加上jml前后置条件,得到基于jml的原型java程序;验证模块204,用于对所述基于jml的原型java程序进行验证。
[0131]
本实施例中,所述简化模块采用抽象语法树,经过解析、修改和重写,最后将结果转为java程序,得到所述简化版原型java程序。所述jml前后置条件自动生成模块通过xtend模板完成所述简化版原型java程序的ocl合约自动生成jml格式的合约,得到基于jml的原型java程序。
[0132]
本技术实施例验证方法的简化过程中,可以对java程序每一个类和方法的内容进行具体简化,其中包括读取文件规则(read file rule)、新建ast规则(new ast rule)、获取方法规则(gets method rule)、修改数据类型规则(modify data type rule)、删除规则(delete rule)、替换规则(replace rule)、定义新变量规则(define new variable rule)、增加方法调用规则(add method call rule)、简化for循环规则(simplify for loop rule)。运用读取文件规则从本地读取java源文件,在修改java源文件之前运用新建ast规则生成java源文件抽象语法树,运用获取方法规则来得到所有方法的头结点,获取方法都是以此头结点展开。在java源文件中可以运用定义新变量规则在特定的结点位置生成所需的新变量,增加方法调用规则可以得到目标调用方法的表达式,修改任意数据类型都可以由修改数据类型规则来实现。在每一个子方法中,可以运用删除规则来删除删除注释、
删除变量、删除语句等,从而达到简化代码的效果。运用替换规则可以把旧的方法调用值替换为变量值。简化for循环规则可把增强for循环简化为一般的for循环,由删除增强for循环到再新建一般的for循环的步骤来达到简化的结果,本技术实施例有效提高了验证效率和精准性。
[0133]
以上所述,仅为本技术的具体实施方式,但本技术的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本技术揭露的技术范围内,可轻易想到的变化或替换,都应涵盖在本技术的保护范围之内。因此,本技术的保护范围应以权利要求的保护范围为准。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1