程序分析技术.docx
《程序分析技术.docx》由会员分享,可在线阅读,更多相关《程序分析技术.docx(23页珍藏版)》请在冰豆网上搜索。
![程序分析技术.docx](https://file1.bdocx.com/fileroot1/2023-1/5/328f5583-766e-47e1-a21d-0c16d3c2535c/328f5583-766e-47e1-a21d-0c16d3c2535c1.gif)
程序分析技术
第一讲:
程序语言的发展过程
任务:
以程序为对象,分析其属性,如:
值的获取与传播,活跃性
应用:
程序转换程序理解程序演化程序逆向工程程序验证与测试程序优化重构自动并行化
发展:
机器语言:
指令:
二进制组成
具有基本操作,左移、右移、加1
缺点:
可读性差(可理解性差)
写程序困难(不方便)
问题:
程序的维护比较困难
扩展纠错预防适应
汇编语言:
符号化了的机器语言
功能没有扩充
可读性强
高级程序设计语言:
(1)过程(PASCAL,C,FORTRAN,PL1)
特点:
命令为基础,程序由一系列语句组成,语句的执行引起存储单元值的变化。
程序的正确型(归纳断言指导…)
数学性质弱(副作用,变量值变化)
数据类型不够丰富
程序的动静态结构差异大
Goto语言的争议(难以理解,难以查错,动静态差异大
修改引起的副作用小,全局优化简单
概念简单,效率高)
(2)函数式语言(LISP,ML,HOPE,FP)
程序由一组函数组成,通过调用执行程序。
特点:
数学性质好
数据类型可自定义
支持并行计算
抽象级别高
数据以表为基础
(3)逻辑式语言(PROLOG)
以谓词为基础,具有推理能力
特定的应用领域抽象的问题求解公式处理专家系统人工智能等
(4)对象式语言SmallTalk80
特点:
封装性继承性多态性
第四代语言:
特定领域的特殊类语言高级语言的抽象如:
Oracle应用开发环境、PowerBuilder…
程序分析方法:
静态分析方法:
(词法分析语法分析所需要的分析)
动态分析方法
第二讲:
编译原理基础
基本概念:
•字母表:
∑,元素的非空有穷集合。
•符号串:
由字母表中的符号组成的任何有穷序列。
或者如下定义:
1.空符号串ε是上的符号串
2.若x是上的符号串,a是的元素,则xa是上的符号串
3.y是上的符号串,当且仅当它可以由1和2导出
•符号串的连接:
设x和y均是字母表∑上的符号串,它们的连接是把y的所有符号顺序接在x的符号之后所得到的符号串。
•符号串的方幂:
设x是字母表∑上的符号串,把x自身连接n次得到的符号串z,称作符号串x的n次幂,记作z=(幂形式),特别地:
x0=
•前缀和后缀:
设x是字母表上的符号串,x=yz,则y是x的前缀,z是x的后缀,特别是当z≠时,y是x的真前缀;y≠ε时,z是x的真后缀。
•子字符串:
非空字符串x,删去它的前缀和后缀后所得到的字符串称为x的子字符串,简称子串。
如果删去的前缀和后缀不同时为ε,则称该子串为真子串。
•符号串集合:
若集合A中的所有元素都是某字母表上的符号串,则称A为该字母表上的符号串集合。
•符号串集合的乘积:
设A、B是两个符号串集合,AB表示A与B的乘积,则定义
AB={xy|(x∈A)∧(y∈B)}
•符号串集合的方幂:
设A是符号串集合,则称Ai是符号串集合A的方幂,其中i是非负整数。
A0={},A1=A,A2=AA,…,An=AA…A
•符号串集合的正闭包:
A+=A1∪A2∪A3…
•符号串集合的星闭包:
A*=A0∪A1∪A2∪A3…
2正则表达式
•定义:
RE为定义在∑上的正则表达式则
–∧,ε∈RE
–若a∈∑,则a∈RE
–若e1,e2∈RE,则e1·e2,e1|e2,e1+∈RE
•语义函数(解释函数)L
L(∧)=Ф,L(ε)={ε}
–若a∈∑则L(a)={a}
–若e1,e2∈RE则L(e1·e2)=L(e1)·L(e2)L(e1|e2)=L(e1)∪L(e2)L(e1+)=L+(e1)
Eg:
ab*表示所有以字母a开头的后面跟了n个(包括)0个b的字符串
a(a|b)*表示所有以a开头的字符串
3自动机定义:
一个DFA是一个5元组(S,∑,δ,S0,F),其中S是状态集合,∑是字符集,δ是转换函数(转移函数)S×∑→S,S0为初始状态S0∈S,F为终止状态集合,F⊆S。
两种表示形式(转换图转换矩阵)
Eg:
确定有限状态自动机M=({a,b},
{S,U,V,Q},f,S,{Q}),其中f定义为:
f(S,a)=Uf(V,a)=U
f(S,b)=Vf(V,b)=Q
f(U,a)=Qf(Q,a)=Q
f(U,b)=Vf(Q,b)=Q
词法分析:
功能:
读源程序的字符序列,逐个拼出单词,并构造相应的内部表示,同时检查源程序中的词法错误。
单词:
所谓单词是指语言中具有独立含义的最小的语义单位。
Token:
单词的内部表示。
“程序语言的操作对象(只能)是该语言规定的各种数据。
”编译程序是用某种程序语言书写的程序,其操作对象是一般程序中的各种语法单位。
单词的一种分类:
识别常数的自动机
文法概述
定义
文法G定义为四元组(VT,Vn,S,P)
VT是有限的终极符集合
Vn是有限的非终极符集合
S是开始符,SVn
P是产生式的集合,且具有下面的形式:
,其中,(VTUVn)*
分类
•O型文法:
也称为短语文法,其产生式具有形式:
→,其中,(VTVN)*,并且至少含一个非终极符。
•1型文法:
也称为上下文相关文法。
它是0型文法的特例,要求||||(S→例外,但S不得出现于产生式右部)。
•2型文法:
也称为上下文无关文法。
它是1型文法的特例,即要求产生式左部是一个非终极符:
A→。
•3型文法:
也称为正则文法。
它是2型文法的特例,即产生式的右部至多有两个符号,而且具有下面形式之一:
A→a,A→aB其中A,BVN,aVT。
•推导(直接推导):
如果A是一个产生式,则有A,其中表示一步推导(用A→)。
这时称是由A直接推导的。
的含义是,使用一条规则,代替左边的某个符号,产生右端的符号串。
•+:
表示通过一步或多步可推导出
•*:
表示通过0步或多步可推导出
•句型:
如果有S*,则称符号串为CFG的句型。
我们用SF(G)表示文法G的所有句型的集合。
•句子:
如果只包含终极符,则称为CFG的句子。
•语言:
L(G)={u|S+u,uVT*}
文法G所定义的语言是其开始符所能推导的所有终极符号串(句子)的集合。
最左(右)推导:
如果进行推导时选择的是句型中的最左(右)非终极符,则称这种推导为最左(右)推导,并用符号Þlm(Þrm)表示最左(右)推导。
左(右)句型:
用最左推导方式导出的句型,称为左句型,而用最右推导方式导出的句型,称为右句型(规范句型)。
结论:
每个句子都有相应的最右和最左推导(但对句型此结论不成立)
•短语:
设S是文法的开始符,是句型(即有S*),如果满足条件:
S*AA+VT+
则称是句型的一个短语。
任一子树的树叶全体(具有共同祖先的叶节点符号串)皆为短语。
•直接短语(简单短语):
如果满足条件:
S*AAVT+
则称是句型的一个简单短语。
任一简单子树的树叶全体(具有共同父亲的叶节点符号串)皆为简单短语。
•句柄:
一个句型可能有多个简单短语,其中最左的简单短语称之为句柄。
•语法分析树(简称分析树)用来描述句型的结构,是句型推导的一种树型表示。
文法G=(VN,VT,S,P),则称满足下面条件的树为G的一棵语法分析树:
•每个结点都有G的一个文法符号,并且根结点标有初始符S,非叶结点标有非终极符,叶结点标有终极符或非终极符或。
•如果一个非叶结点A有n个儿子结点(从左到右)为X1,X2,...,Xn,则G一定有产生式A→X1X2...Xn。
•线性推导:
我们称用符号进行的推导为线性推导。
•树型推导与线性推导的不同:
线性推导指明了推导的顺序,而树型推导则没有指明推导的顺序。
因此,句型一般只有一棵分析树(如果无二义性),而线性推导则可以有很多棵分析树。
•二义性文法:
如果一个文法的某个句型有两棵不同的语法分析树,则称该文法二义性为二义性文法。
例:
文法G=({+,*,i,(,)},{E},E,P),其中P为:
EiEE+E
EE*EE(E)
句型i*i+i可能的推导:
推导1:
EE+EE*E+Ei*E+Ei*i+Ei*i+i
推导2:
EE*Ei*Ei*E+Ei*i+Ei*i+i
语法分析
分类
自顶向下
递归下降法
LL
(1)方法
自底向上
简单优先方法
LR(0)方法
SLR
(1)方法
LR
(1)方法
LALR
(1)方法
自顶向下思想与例子:
思想:
从文法开始符出发试图推导出所给的终极符串
例子:
G[z]:
[1]ZaBd
[2]Bd
[3]Bc
[4]BbB
自底向上思想和实例:
思想:
从待分析的符号串开始,自左向右进行扫描,自下而上进行分析,通过反复查找当前句型的句柄,并使用产生式规则将找到的句柄归约为相应产生式的左部非终极符,直到将输入串归约为文法的开始符。
(移入-归约分析)
第三讲:
元程序设计
基础知识:
词法分析
1.基本概念
2.描述工具
1)正则表达式
2)自动机
3.实现词法分析器注意的问题
语法分析
1.形式语言
2.分析原来
自顶向下的语法分析
自底向上的语法分析
语法制导:
分析的过程生成中间表示
元程序:
定义:
处理程序的程序
组成:
1预处理:
把源程序变成一种中间表示(经过词法分析,语法分析)
2元级操作:
提供最基本的操作(根据需求,用户可选择如何操作)
3后处理:
有必要把中间表示转为源代码
中间表示
第四讲:
数据流分析技术
数据流分析技术是对源程序分析、获取程序中变量定值和传播的情况,帮助理解程序中的数据流动情况
定义一、基本块
是一个顺序执行的命令序列。
进入一个基本块,必须从第一条命令进入,退出基本块,必须由最后一条命令退出。
特点:
后续执行情况可判断。
定义二、程序图
是一个有向图,它的结点为基本块,有一个入口结点(无前驱结点)和一个出口结点(无后续结点)
扩展:
常用的程序图有三种表示(流程图N-S图PAD图)
定义三、定值
在基本块当中,若有d:
x:
=e,则称有对x的定值,d:
为x的定值点。
(注:
d:
为程序中引入的标识,对程序无影响)
定义四、注销
若有对变量x的赋值x:
=…,则程序注销了x的原定值。
用kill[B]表示B中被注销的所有变量之集。
定义五、向下暴露的定值
设(Bi,di)为x的一个定值,若从di+1到Bi的出口再无对x的定值,则称x的di的定值为向下暴露的定值,并用def[Bi]表示Bi中的所有向下暴露定值的变量之集。
定义六、可能到达的定值
说在(Bi,di)点x定值可能到达(Bj,dj)点,若从(Bi,di)存在一条路,且在该路上无x的定值。
可到达的定值数据流方程
in[B*]={},B*为入口块。
;
out[B]=def[B]∪(in(B)-kill(B))
in[B]=∪(out[Bi])
i=1,2,…n;Bi为B的前驱结点
其中
in[B]表示在B入口处有定值的变量之集
out[B]表示定值可到达B出口处的变量定值之集
实例:
定义七、定义性出现,使用性出现
称第一次出现在赋值命令左部的变量出现(即x:
=…第一次出现)为变量(x)的定义性出现,而称其他部位中的变量出现为其使用性出现
定义八、向上暴露的使用
在(Bi,di’)有x的使用性出现,若从Bi的入口到di’-1点无对x的赋值。
则称x在(Bi,di’)点的出现为向上暴露的使用,用use_live[B]表示B中所有向上暴露的使用
定义九、变量的活跃性
说变量x在(Bi,di’)点活跃,若:
1.存在一点(Bj,dj’)有x的使用性出现。
2.从(Bi,di’)到(Bj,dj’)存在一条通路,且在该路上无对x的定值。
定义十、注销活跃性
若在某一点(Bk,dk)有X:
=,则称注销X的活跃性
活跃变量的数据流方程
in_live[B]=use_live[B]∪(out_live[B]-kill_live[B])
out_live[B]=∪in_live[Bi]Bi为B的后续
out_live[B*]={}B*为出口块
其中
in_live[B]={x|x在B入口处活跃}
out_live[B]={x|x在B出口处活跃}
use_live[B]={x|B中所有局部向上暴露使用的变量}
kill_live[B]={x|B注销其活跃性的变量}。
定义十一、过程调用块
把过程调用P(e1,…en)定义为一个独立的基本块,称为过程调用块。
定义十二、过程的返回块
调用块的接续为返回块(或return的后续块)难点:
1.下标变量的分析
2.别名问题
第五讲:
数据流分析技术应用
第一个应用:
检测数据流异常
1.数据流异常情况:
1)变量无定值而使用;
2)变量重复定值;
3)变量定值无使用。
检测:
针对第一种情况(无定值而使用)
in_d[B]:
表示在B入口处所有定值的变量之集;
out_d[B]:
表示B在出口处所有定值的变量之集;
def_d[B]:
表示B中所有定值的变量之集。
数据流方程:
in_d[B*]={}B*为入口块
in_d[B]=∪(或∩)i=1,2…n(out_d[Bi])
Bi为B的前驱块
out_d[B]=def_d[B]∪in_d[B]
结论:
若in_live[B]–in_d[B]≠{},则必有变量无定值而使用;
特例:
若in_live[B*]≠{},则必有变量无定值而使用.
针对第2和3中情况:
in_dd[Bi]:
表示块B入口处所有定值而未使用的变量之集;
out_dd[Bi]:
表示块B出口处所有定值而未使用的变量之集;
def_dd1[Bi]={x|x在(B,di)点定值,且从(B,d1)….(B,di)无x的使用性出现。
}
def_dd2[Bi]={x|x在(B,di)点定值,且从(B,di+1)到B出口,无x的使用性出现。
}
in_dd[B*]={}B*为入口块
in_dd[B]=∪(或∩)out_dd[B]
out_dd[B]=def_dd2[B]∪(in_dd[B]-use[B])
结论:
若in_dd[B]∩def_dd1[B]≠{},则有变量重复定值;若in_dd[B]-in_live[Bi]≠{},则有变量定值而未使用,或重复定值。
若out_dd[B*]≠{},B*为出口块,则有变量定值而未使用。
程序优化:
全局常表达式节省
基本块的常表达式节省
v
vvl
问题:
利用的信息不充分
解决办法:
•定义:
常量定值
若在块B中有x:
=c,其中c是常数,且该定值是向下暴露的,,则称x有一个常量定值,记为x·c。
•定义:
注销常量定值
若有x:
=E,则称注销了x的常量定值。
•定义:
广义常量定值
若块B中有向下暴露的定值x:
=E,且E的值可计算为一个常量c,则称产生一个广义常量定值x·c。
•定义:
注销广义常量定值
若有x=…则称注销了广义常量定值
数据流方程:
in_ac[B0]={}B0为入口块
in_ac[Bi]=∩j=1,2,…nout_ac[Bj],Bj为Bi的前驱
out_ac[Bi]=def_ac[Bi]U(in_ac[Bi]-kill_ac[Bi])
优化过程:
•建立数据流方程
•求解
•对每一基本块进入优化
–把in-ac(B)填入vvl
–按原方法优化
例子:
in-ac[B1]={}
out-ac[B1]={x.1,y.2}
in-ac[B2]={x.1,y.2}
out-ac[B2]={x.1,y.2,z.3,b.4}
in-ac[B3]={x.1,y.2}
out-ac[B3]={x.1,y.2,z.3,b.4}
in-ac[B4]={x.1,y.2,z.3,b.4}
out-ac[B4]={x.1,y.2,z.3,b.4,k.7,u.9,r.16}
公共子表达式节省
•定义:
表达式定值
在块B中,若有d:
x:
=E,则称有表达式E的定值,d为定值点若从di+1到B的出口没有对表达式E中变量的赋值,则称B定值了表达式E
•定义:
注销表达式定值
若有x:
=E,且x出现在表达式E中,注销了E的定值。
数据流方程:
in_e[B0]={}B0为入口块
out_e[Bi]=def_e[Bi]∪(in_e[Bi]-kill_e[Bi])in_e[Bi]=∩Bj∊pre(Bi)out_e[Bj]
Bj为Bi的前驱
需要注意的两个问题:
•形式相同的表达式未必能节省(已解决)
•形式不同的表达式也可能节省(未解决)
•定义:
等式定值
在块B中,若有x:
=y。
且从di+1到B出口无对x或y的赋值,则称B有了一个等式定值。
即x=y
●定义:
注销等式定值
若有对x的赋值x:
=…,则称注销了所有x的等式定值。
数据流方程
in_eq[B0]={}B0为入口块
out_eq[Bi]=def_eq[Bi]∪(in_e[qBi]-kill_eq[Bi])
in_eq[Bi]=∩Bj∊pre(Bi)out_eq[Bj]
利用等式定值和表达式定值,可以解决形式不相同但语义相同的表达式节省问题。
例如:
X:
=A*B[1]
C:
=A[2]
Y:
=C*B[3]
由[2]可知[1][3]等价
第六讲:
一种信息流分析技术
一:
处理的语言
S->skip
|V:
=e
|Ifethenselses
|Ifethens
|s;s
|Whileedos
选择的原因:
结果定理
基本定义
定义:
设S为一个语句,若在S中有V:
=e,一则称S定义了v。
用Ds表示S定义的所有变量之集。
设S为一个语句,从G(S)入口到G(S)出口存在一条路,且在该路上无对变量x的赋值,则称S保护了x。
用Ps表示S保护的所有变量之集。
定义:
变量与表达式的关系
若变量v在G(S)入口处值,直接或间接参与了表达式e的计算,则说v和e具有关系,记为vSe或者(v,e)S。
定义:
表达式与变量的关系
若表达式e直接或间接参加变量v在G(S)出口处值的计算,则称e和v具有关系,记为eSv或者(e,v)S。
定义:
变量与变量的关系
S=SS{(v,v)|vPS}
解释,v1Sv2,v在G(S)的入口值参与v2在G(S2)出口值的计算。
v1Sv2,v1在G(S)的入口值可?
G(S)的出口
计算方法
空语句S:
skip;Ds=,ps=V
s=,s=ps={(v,v)|vps}
赋值语句S:
v:
=e;
DS={v},PS=V-{v}
S={(v,e)|vV(e)},
S={(e,v)}
S={(v,v)|vuse(e)}{(v,v)|vPS}
顺序语句S:
A;BDS=DADB,PS=PAPB
S=AAB,
S=ABB
S=AB
条件语句S:
ifethenAelseB
DS=DADB,PS=PAPB
S={(v,e)|vuse(e)}AB
S=AB{(e,v)|v(DADB)}
S=AB{(v’,v)|vuse(e),vDADB)}
简单条件语句s:
ifethenA
else部分为skip可用上述规则计算。
循环语句S:
whileedoA
DS=DA,PS=V
S=A*({(v,e)|vuse(e)}A)
S=({(e,v)|vDA}A)A*
S=公式计算
应用:
1.看某一输入变量对那些输出变量有影响
设v’Vi,v”Vo,若(v’,v”)成立,则v’对v”有影响。
影响集
{(v’,v”)v”Vo,(v’,v”)}
2.看那些输入变量对某些输出变量的影响
给定v’v”,
{v’|(v’,v”)v’v”}
被影响集对v”有影响
3.无用的输入变量
若输入变量影响的输出变量集为空,则该输入变量对程序的运行结果无影响。
4.无效语句
v:
=e,{(e,v)|vVo}=,则该语句可用skip替换或含有错误。
5.对循环语句的分析
设有whileedoA,定义一个G’(S),点集为DA,边集为A
定义:
稳定表达式e的稳定长度
设e是关于s稳定的,其稳定长度用(e)表示。
定义如下:
(e)=max({(v)|v∊use(e)})+1。
结论:
任意一个稳定变量,当循环的次数到达一个定值(稳定长度+1)时,其值不会改变。
任意一个稳定表达式,当循环的次数到达一个定值(稳定长度+1)时,其值不会改变。
若whileedoA中的e是稳定的,很有可能出错(陷入死循环)。
应用:
可根据上述分析结果,进行应用。
例如:
部分求值的程序例化(循环展开)
第七讲:
程序切片
一:
引言
二:
基本概念
定义一、控制流图
控制流图CFG=(N,E,S,e,v)是一个有向图,其中,
N是结点集,程序中的语句和消词属于该集,
E是边集,语句n,m之间的控制关系用(n,m)E表示,记为nm
S,e分别为开始结点和终点结点
VE{true,false,}
谓词输出边标true或false,其它边标
定义二、CFG的路径,路径可到达,可实现路径
若任意1≤i≤k-1,G中的一个结点序列P=.都满足nini+1,则称P为G的一个路径。
如果G中存在一条路径则称p是q的可到达的,记为qp。
G中的一条路径是程序的一条可执行序列,则称是可实现的。
定义三、必经点
1.从开始点s到n的所以路径都经过m,则称m为n的前必经点。
2.从n到出口e的所以路径都经过m,则称m为n的后必经点。
定义四、控制依赖
如果结点n,m满足下面条件,则称n控制依赖m,记为nm
1.G上存在一条路,n是mi的后必经点1≤i≤k.
2.n不是m的后必经点。
3.若m是G的唯一的开始结点,则m的所有后必经点都控制依赖于m。
定义五、数据依赖
如果结点m,n满足下面条件,则称n数据依赖于m,记nm,
1.存在一个变量v,有vεdef(m)∩ref(m)
2.存在(m,m1,…mk,n)且v∉def(