编译原理期末复习.docx
《编译原理期末复习.docx》由会员分享,可在线阅读,更多相关《编译原理期末复习.docx(32页珍藏版)》请在冰豆网上搜索。
编译原理期末复习
1.编译程序结构图
(1)词法分析
任务:
输入源程序,对构成源程序的字符串进行扫描和分解,识别出一个个单词符号。
表示成二元式的形式:
(单词种别,单词自身的值)。
如基本字(if、for、等)、标识符、常数、运算符和界符(如“()”、“;”)等,将所识别出的单词用统一长度的标准形式(也称内部码)来表示,以便于后继语法工作的进行。
词法分析工作是将源程序中字符串变换成单词符号流的过程,词法分析阶段工作遵循的是语言的构词规则。
描述构词规则的有效工具是:
正规式和有限自动机。
(2)语法分析
任务:
在词法分析的基础上,根据语言的语法规则(文法规则)把单词符号流分解成各类语法单位(语法范畴),如“短语”、“子句”、“句子(语句)”、“程序段”和“程序”等。
通过语法分析可以确定整个输入串是否构成一个语法上正确的“程序”。
语法分析所遵循的是语言的语法规则。
语法规则通常用上下文无关文法描述。
例:
Z=x+97*y
语法分析应识别x+97*y为“算术表达式”,并识别整个字符串为赋值语句。
(3)语义分析与中间代码生成
任务是:
对语法分析所识别处的各类不同语法范畴,分析其含义,按语言的语义进行初步翻译(产生中间代码。
常见的中间代码有四元式、三元式、间接三元式和逆波兰式等)
本阶段包含两个方面的工作:
1)对每种语法范畴进行静态语义检查,如变量是否定义、类型是否正确等;
2)在语义检查正确的情况下,进行中间代码的翻译。
把语法范畴翻译成中间代码所遵循的是语言的语义规则。
语义规则通常使用属性文法描述。
(4)代码优化
优化的任务:
是对前阶段产生的中间代码进行等价变换或改造,以期获得更为高效(节省时间和空间)的目标代码。
(输出是优化了的中间代码)
常用的优化措施:
删除冗余运算、删除无用赋值、合并已知量、循环优化等。
例如:
其值并不随循环而发生变化的运算可提到进入循环前计算一次,而不必在循环中每次循环都进行计算。
优化所遵循的原则是程序的等价变换规则。
(5)目标代码生成
任务:
把中间代码(或经优化处理之后)变换成特定机器上的机器语言程序或汇编语言程序,实现最终的翻译工作。
此阶段的工作因为目标语言的关系而十分依赖硬件系统,即如何充分利用机器现有的寄存器,合理地选择指令,生成尽可能短且有效的目标代码,这些都与目标机器的硬件结构有关。
2.由正规表达式构造等价的最简DFAM
分割法
子集法
4+1条
注意
自然语言————>正规表达式—————>NFA————>DFA————>最简DFA
(1)由正规表达式构造等价的NFAM
方法:
1)将正规表达式R表示成下图
2)对正规表达式采用下图所示的三条转换规则来构造NFAM。
方法描述:
对于给定的正规表达式R,首先将其表示成拓广转换图,其中x为初态,y为终态;然后逐步将这个拓广转换图运用三条转换规则不断加入新结点进行分解,直至每条有向边上仅标识有S上的一个字母或ε为止,则NFAM构造完成。
(2)NFAM的确定化(子集法)
①构造一张转换表,其第一列为状态子集I,对不同的a(a属于∑)在表中单设一列Ia。
②表的第一行第一列其状态子集I为ε_CLOSURE(s0),其中s0为初始状态。
③根据第一列中的I为每个a求其Ia,并记入对应的Ia列,如此Ia不同于第一列已存在的所有状态子集I,则将其顺序列入空行中的第一列。
④重复步骤③直至对每个I及a均已求得Ia,并且无新的状态子集加入第一列时为止。
此过程可在有限步后终止。
⑤重新命名第一列的每一个状态子集,则转换表便成为新的状态转换矩阵,其状态转换函数f是S*∑S至S的单值映射,即与NFAM等价的DFAM’,其初态是该表首行首列的那个状态,终态是那些含有原终态的状态子集。
如何求ε_CLOSURE(I):
首先:
定义FAM的一个状态子集I的ε_闭包,即ε_CLOSURE(I):
①若siI,则siε_CLOSURE(I);
②若siI,则对从si出发经过ε通路所能到达的任何状态sj,都有sjε_CLOSURE(I)。
其次:
对FAM的一个状态子集I,若a是∑S中的一个字符,定义Ia=ε_CLOSURE(J),其中J是所有那些可以从I中的某个状态出发经过有向边a而能到达的状态集。
(3)DFAM的化简(分割法)
DFA的化简是指寻找一个状态数比M少的DFAM’,使得:
L(M)=L(M’)
化简后的DFAM’满足下述两个条件:
①没有多余状态(多余状态是指从自动机的开始状态出发,任何输入串也不可达的状态);
②在其状态集中,没有两个相互等价的状态存在。
分割法:
①首先将DFAM的状态集S中的终态与非终态分开,形成两个子集,即得到基本划分。
②对当前已划分出的I
(1)、I
(2)、…、I(m)子集(属于不同子集的状态是可区分的),看每一个I(i)是否能进一步划分,即对某个I(i)={s1,s2,…,sk}若存在一个输入字符a(a∈Σ)使得Ia(i)不全包含在当前划分的某一子集I(j)中(即跨越到两个子集),就将I(i)一分为二(如下图)。
(a)无需划分;(b)需要划分
划分状态子集方法:
假定当前子集I(i)={s1,s2,…},且状态s1和s2经过有向边a分别到达状态t1和t2,而t1和t2又分属于当前已划分出的两个不同子集I(j)和I(k),则此时应将I(i)分为两部分,使得一部分含有s1:
I(i1)={s∣s∈I(i)且s经有向边a到达t1所在子集的某状态}
另一部分含有s2:
I(i2)=I(i)−I(i1)
③重复步骤②,直到子集个数不再增加为止(即每个子集已是不可再分的了)。
所谓不能划分,是指该子集或者仅有一个状态,或者虽有多个状态但这些状态均不可区分(即等价)。
④从每个子集中选取一个状态代表其它状态,例如,设子集I={s1,s2,…,sk},可选s1代表整个子集,在原来的自动机中,凡导入到s2,…,sk的箭弧都改成导入s1,然后删除s2,…,sk。
若I中含有原来的初态,则s1为新初态;若I中含有原来的终态,则s1为新终态。
证明两个正规表达式等价可证:
①对应最简DFA等价
②转换矩阵等价
③准确的自然语言描述
3.推导与语法树
(1)推导
规范推导:
句子推导序列中的每一步推导都是对句型中的最右非终结符用相应产生式的右部进行替换,这样的推导称为最右推导。
如果每一步推导都是对句型中的最左非终结符用相应产生式的右部进行替换,则称为最左推导。
称最右推导为规范推导,规范推导得到的句型成为规范句型,规范推导的逆过程称为规范归约。
(2)语法树
对文法G=(VT,VN,S,ξ),满足下列条件的树称为G[S]的语法树:
(1)每个结点用G[S]的一个终结符或非终结符标记;
(2)根结点用文法开始符S标记;
(3)内部结点(指非树叶结点)一定是非终结符,如果某内部结点A有n个分支,它的所有子结点从左至右依次标记为x1、x2、…、xn,则A→x1x2…xn一定是文法G[S]的一条产生式;
(4)如果某结点标记为ε,则它必为叶结点,且是其父结点的唯一子结点。
语法树中的一些定义:
1)语法树的某个结点连同它的所有后代组成一棵子树,只含有单层分枝的子树称为简单子树。
2)短语:
子树的末端结点(即树叶)组成的符号串是相对于子树根的短语。
3)直接短语:
简单子树的末端结点组成的符号串是相对于简单子树根的直接短语。
4)句柄:
最左简单子树的末端结点组成的符号串为句柄。
5)素短语:
子树的末端结点组成的符号串含终结符,且在该子树中不再有包含含有终结符的更小子树。
对于一个给定的文法G,如果存在某个句子它有两种不同的最左(右)推导,或者有两棵不同的语法树,则称该文法G是一个二义性文法。
排除文法二义性通常有两种方法:
(1)不改变文法中原有的语法规则,仅加进一些语法的非形式规定。
(2)构造一个等价的无二义性文法,即把排除二义性的规则合并到原有文法中,改写原有的文法。
注意:
①一个推导=>,只能推一条规则。
②推导是用每条规则的右部替换左部。
③语法树中越远离根结点,优先级越高。
例:
现有文法G[E],
E→E+T|E-T|T
T→T*F|T/F|F
F→(E)|i
求出句型(F+i)-T*(E-T)的短语、直接短语和句柄。
解:
所以短语有:
F,i,F+i,(F+i),E-T,(E-T)
T*(E-T),(F+i)-T*(E-T)
直接短语有:
F,i,E-T
句柄为:
F
4.自上而下分析方法——递归下降
每个非终结符对应一个递归过程。
分析过程是从文法的开始符号出发执行一组递归过程,向下推导直到推出句子。
或者说,从根结点出发,自上而下为输入串寻找一个最左匹配序列,建立一棵语法树。
确定的自上而下分析:
1)文法不含左递归,即不存在这样的非终结符号A:
有A→A…或者AÞAα;
2)无回溯,对于文法任一非终结符,当其产生式右部有多个候选时,各候选式所推出的终结符号串的首字符集合要两两不相交。
(1)消除左递归
变形为等价的右递归形式:
A→Aα|βA→βA'
A'→αA'|ε
一般情况下,设关于非终结符A的产生式形如:
A→Aα1|Aα2|…|Aαn|β1|β2|…|βn
其中,每个α都不等于ε且每个β不以A开头,则消除A的直接左递归就是将A的产生式改写成如下形式:
A→β1A'|β2A'|…|βnA'
A'→α1A'|α2A'|…|αnA'|ε
消除一个文法的一切左递归
如果一个文法不含回路(形如AA的推导),且产生式的右部也不含ε的候选式,下述算法将消除文法的左递归:
(1)将文法的所有非终结符按任一种顺序排列:
A1、A2、…、An;
(2)执行下述循环语句可将间接左递归改为直接左递归:
for(i=1;i<=n;i++)
{for(j=1;j<=i-1;j++)
{把一个形如Ai→Ajγ|β1|β2|…
Aj→δ1|δ2|…|δk的产生式改写成:
Ai→δ1γ|δ2γ|…|δkγ|β1|β2|…|βn;}
按照消除直接左递归的方法消除Ai的直接左递归;}
(3)化简由
(2)得到的文法,即去掉多余的产生式。
(2)消除回溯
回溯发生的原因在于候选式存在公共左因子。
A→δβ1|δβ2|…|δβi|βi+1|…|βj
可以把这些产生式改写成为:
A→δA'|βi+1|…|βj
A'→β1|β2|…|βi
经过反复提取左因子,就能把每个非终结符(包括新引进者)的所有候选首符集变为两两不相交(不含公共左因子)。
(3)递归下降分析器
5.LL
(1)
已知文法:
1)
文法等价变换二义性
压缩文法
消回溯A→δβ1|δβ2|…|δβi|βi+1|…|βj
A→δA'|βi+1|…|βj
A'→β1|β2|…|βi
消除左递归A→Aα|βA→βA'
A'→αA'|ε
2)FIRST集,FOLLOW集的构造
3)判定LL
(1)文法充要条件
可知:
①LL
(1)文法首先是无二义性的,这一点可以从分析表不含多重定义入口得知;
②含有左递归的文法绝不是LL
(1)文法,所以必须首先消除文法的一切左递归。
③含有公共左因子的文法绝不是LL
(1)文法,应该即提取公共左因子(消除回溯)
4)构造LL
(1)分析表
5)分析过程
6.算符优先分析法
算符优先算法——>FIRSTVT,LASTVT(各两条)——>优先关系表(4条,两对)——>最左素短语要素——>最左素短语——>可归约串——>形式规约
在整个归约过程中起决定性作用的是相继两个终结符的优先关系。
算符文法:
任何产生式的右部都不含两个相继(并列)的非终结符的文法。
算符优先文法首先应是算符文法,其次还要定义任何两个可能相继出现的终结符a与b(它们之间最多有一个非终结符)的优先关系
假定G[S]是一个不含有ε产生式的文法,对于任何一对终结符a、b有:
①a=b,当且仅当文法中含有形如P→…ab…或P→…aQb…的产生式;
②a⋖b,当且仅当文法中含有形如P→…aR…的产生式,而Rb…或RÞQb…;
③a⋗b,当且仅当文法中含有形如P→…Rb…的产生式,而RÞ…a或R…aQ。
如果一个文法G中的任何终结符对(a,b)至多满足以上三种关系(相同,低于,高于)之一,则称该文法G[S]是一个算符优先文法。
FIRSTVT集合的构造方法:
(1)若有产生式P→a…或P→Qa…,则a∈FIRSTVT(P)
(2)若a∈FIRSTVT(Q),且产生式P→Q…,则a∈FIRSTVT(P)
LASTVT集合的构造方法:
(1)若有产生式P→…a或P→…aQ,则a∈LASTVT(P)
(2)若a∈LASTVT(Q),且产生式P→…Q,则a∈LASTVT(P)
(1)算符优先关系表的构造方法:
(1)对形如P→…ab…或P→…aQb…的产生式,有a=b
(2)对形如P→…aR…的产生式,若bFIRSTVT(R),有a⋖b
(3)对形如P→…Rb…的产生式,若aLASTVT(R),有a⋗b
(4)若将语句括号“#”当作终结符对待,而S为文法的开始符号,则有#=#;#⋖FIRSTVT(S);LASTVT(S)⋗#。
首行首列是所有终结符和#,须填的每项是行对应列的的优先关系。
算符优先分析法是用最左素短语来刻画“可归约串”。
aj-1⋖aj=aj+1=…=ai⋗ai+1
7.LR(0)分析表构造
0)消除二义性
1)将文法G[S]拓广为文法G'[S'](S'→S.,给产生式编号)
2)给出拓广为文法的所有项目
3.5)项目集规范族C={I0............Ik}
定义项目集构造算法:
3)构造DFA(1.S'→.S,2.闭包,求每个状态,3.GO())
定义状态转换函数GO
4)构造LR(0)的分析表
5)据表分析句子
8.SLR
(1)分析表构造
构造方法同LR(0),不同点是:
多求FOLLOW
构造LR(0)的分析表的第②条改为:
9.属性文法
属性是指与文法符号的类型和值等有关的一些信息,在编译中用属性描述处理对象的特征.
判断变量X的类型是否匹配,要用X的数据类型来描述;判断变量X是否存在,要用X的存储位置来描述;而对X的运算,则要用X的值来描述;
因此,语义分析阶段引入X的属性,如:
X.type、X.place、X.val
继承属性用于“自上而下”传递信息。
继承属性由相应语法树中结点的父结点属性计算得到,即沿语法树向下传递,由根结点到分枝(子)结点,它反映了对上下文依赖的特性。
综合属性用于“自下而上”传递信息。
综合属性由相应语法分析树中结点的分枝结点(子结点)属性计算得到,其传递方向与继承属性相反,即沿语法分析树向上传递,从分枝结点到根结点。
特别强调:
(1)终结符只有综合属性,它们由词法分析器提供。
(2)非终结符既可有综合属性也可有继承属性,文法开始符号的所有继承属性作为属性计算的初始值。
10.几种常见的中间语言
1)抽象语法树
在抽象语法树表示中,每一个叶结点都表示诸如常量或变量这样的运算对象,而其它内部结点则表示运算符。
※2)逆波兰表示法
把运算量(操作数)写在前面,把运算符写在后面,因而又称后缀表示法。
(1)表达式的逆波兰表示:
例如:
a+b写成ab+
a*(b+c)写成abc+*
(2)程序语句的逆波兰表示:
BL:
转向某标号;
BT:
条件为真时转移;
BF:
条件为假时转移;
BR:
无条件转移。
3)三地址代码
※
(1)四元式
(op,arg1,arg2,result)
四元式出现的顺序与表达式计值的顺序是一致的,四元式之间的联系是通过临时变量实现的
(2)三元式
(op,arg1,arg2)
op为运算符;arg1、arg2既可指向有关名字在符号表中的登记项或临时变量,也可以指向三元式表中的某一个三元式。
(3)间接三元式
三元式表只记录不同的三元式语句,而间接码表则表示由这些语句组成的运算次序。
例如,赋值语句a=(b+c)*(b+c)对应的三元式表与间接码表为:
三元式表:
①(+,b,c)
②(*,①,①)
③(=,a,②)
间接码表:
①①②③
11.表达式及赋值语句的翻译
(1)布尔表达式的翻译
如何确定一个表达式的真假出口:
需要返填时,先空着。
做题时没有要求的话,设四元式从100开始。
(2)条件语句if(E)S1;elseS2
代码结构图
(3)
条件循环语句while的代码结构
例:
将下面语句翻译成四元式:
while(A
if(C代码结构图如下:
该语句对应的四元式序列如下:
100(j<,A,B,102)/*E1为T*/
101(j,_,_,107)/*E1为F*/
102(j<,C,D,104)/*E2为T*/
103(j<,_,_,106)/*E2为F*/
104(+,Y,Z,T)
105(=,T,_,X)
106(j,_,_,100)/*转对E的测试*/
107
12.代码优化
(1)基本块是指程序中一顺序执行的语句序列,其中只有一个入口和一个出口,入口就是该序列的第一个语句,出口就是该序列的最后一个语句。
划分四元式程序为基本块的算法:
1)从四元式序列确定满足以下条件的入口语句:
①四元式序列的第一个语句;
②能由条件转移语句或无条件转移语句转移到的语句;
③紧跟在条件转移语句后面的语句。
2)确定满足以下条件的出口语句:
①下一个入口语句的前导语句;
②转移语句(包括转移语句自身);
③停语句(包括停语句自身)。
3)划分基本块
①对每个入口语句,确定其基本块。
它是由该入口语句到下一个入口语句(不包括下一个入口语句),或到一个转移语句(包括该转移语句),或到一个停语句(包括该停语句)之间的语句序列组成。
②凡未包含在基本块内的语句,都是控制流程不可到达的语句,故予以删除。
(2)基本块的DAG表示
(3)利用DAG进行基本块的优化处理
四元式——>DAG——>四元式
无用赋值
合并已知量
删除公共子表达式
(4)控制流程图(简称流图)
首结点:
就是从它开始到控制流程图中任何一个结点都有一条通路的结点。
就是包含程序第一个语句的基本块。
流图的有向边集E的构成:
假设流图中结点i和结点j分别对应于程序的基本块i和基本块j,当下述条件有一个成立时,从结点i有一条有向边引到结点j:
基本块j在程序中的位置紧跟在基本块i之后,并且基本块i的出口语句不是无条件转移语句goto(s)或停语句。
基本块i的出口语句是goto(s)或if…goto(s),并且(s)是基本块j的入口语句。
(5)循环:
(1)它们是强连通的,其中任意两个结点之间必有一条通路,而且该通路上各结点都属于该结点序列;如果序列只包含一个结点,则必有一条有向边从该结点引到其自身。
(2)它们中间有一个而且只有一个是入口结点。
入口结点是指序列中具有下述性质的结点:
从序列外某结点有一条有向边引到它,或者它就是程序流图的首结点。
在程序流图中,对任意结点m和n,如果从流图的首结点出发,到达n的任一通路都要经过m,则称m是n的必经结点,记为mDOMn;对任何结点n来说都有nDOMn。
(6)回边的定义:
假设a→b是流图中一条有向边,如果bDOMa,则称a→b是流图中的一条回边。
如果已知有向边n→d(d是n的必经结点)是一条回边,则由它组成的循环就是:
由结点d、结点n以及有通路到达n但该通路不经过d的所有结点组成的。
(7)循环优化
1)代码外提
条件:
(1)S所在的结点是L的所有出口结点的必经结点;
(2)A在L中其它地方未再定值;
(3)L中的所有A的引用点都是而且仅仅是只有S中A的定值才能到达。
2)强度削弱
指把程序中执行时间较长的运算替换为执行时间较短的运算。
强度削弱不仅可对乘法运算实行(将循环中的乘法运算用递归加法运算来替换),对加法运算也可实行。
进行强度削弱后,循环中可能出现一些新的无用赋值,如果它们在循环出口之后不是活跃变量则可以从循环中删除
3)删除归纳变量
如果循环中对变量I只有惟一形如I=I±C的赋值,且其中C为循环不变量,则称I为循环中的基本归纳变量。
J=C1*I±C2,其中C1和C2都是循环不变量,则称J是归纳变量,并称它与I同族。
可以用同族的某一归纳变量来替换循环控制条件中的这个基本归纳变量。
13.嵌套过程语言的栈式实现
(1)嵌套层次显示表(DISPLAY)和活动记录
每进入一个过程后,在建立它的活动记录区的同时建立一张嵌套层次显示表DISPLAY
例:
序的结构如图6–12所示,其中A、B、C为过程名,图6–13为过程C调用A前后的栈顶活动记录。
(2)存取链(静态链)方法
具有存取链的活动记录结构