编译原理总结Word格式.docx
《编译原理总结Word格式.docx》由会员分享,可在线阅读,更多相关《编译原理总结Word格式.docx(40页珍藏版)》请在冰豆网上搜索。
![编译原理总结Word格式.docx](https://file1.bdocx.com/fileroot1/2023-1/25/7306d44d-aeee-49a3-b74e-fdd7790363d8/7306d44d-aeee-49a3-b74e-fdd7790363d81.gif)
real;
sum:
=first+count*10end.
保留字beginvarrealend
标识符sumfirstcountsumfirstcount
界符.
逗号,逗号,冒号:
分号;
加号+乘号*赋值号:
=整数1010
2、语法分析阶段
是编译过程的第二个阶段。
语法分析的任务是在词法分析的基础上将单词序列分解成各类语法短语,如“程序”,“语句”,“表达式”等等。
一般这种语法短语,也称语法单位,或语法成分,或语法范畴。
语法分析所依据的是语言的语法规则,即描述程序结构的规则。
通过语法分析确定整个输入串是否构成一个语法上正确的程序。
3、语义分析阶段
依据语言的语义规则,对语法分析得到的语法结构分析其含义以及应进行的运算,审查源程序中有无语义错误,为代码生成阶段收集类型信息。
4、中间代码生成
在进行了上述的语法分析和语义分析阶段的工作之后,有的编译程序将源程序转变成一种内部表示形式,这种内部表示形式叫做中间代码。
所谓“中间代码”是一种结构简单,含义明确的记号系统,这种记号系统可以设计为多种多样的形式。
重要的设计原则:
一是容易生成;
二是容易将它翻译成目标代码。
5、代码优化
任务:
对前阶段产生的中间代码系列进行变换或改造。
目的是使生成的目标代码更高效,即省时间省空间。
例如上例四个四元式可优化为下面两个四元式。
6、目标代码生成
将中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码。
它的工作与硬件系统结构和指令含义有关。
7、表格管理
编译过程中源程序的各种信息被保留在种种不同的表格里,编译各阶段的工作都涉及到构造、查找或更新有关的表格,因此需要有表格管理的工作;
8、出错处理
如果编译过程中发现源程序有错误,编译程度应报告错误的性质和错误发生的地点,并且将错误所造成的影响限制在尽可能小的范围内,使得源程序的其余部分能继续被编译下去,有些编译程序还能自动校正错误,这些工作称之为出错处理。
(5)前端与后端
参考上面的图,目的是为了在多种源语言和多种目标语言的开发过程中,可以灵活搭配组合,消除重复开发的工作量,提高编译系统的开发效率。
(6)遍
所谓遍,是对源程序或源程序的中间形式从头到尾扫视并完成规定任务的过程。
每一遍扫视可完成一个阶段或多个阶段的功能。
一遍的编译程序:
以语法分析程序为核心。
多遍扫描的优点:
可以减少内存容量的需求,分遍后,以遍为单位分别调用编译的各个程序,各遍程序可以相互覆盖。
可使各遍的编译程序相互独立,结构清晰。
能够进行充分优化,产生高质量的目标程序。
可将编译程序分为前端和后端,有利于编译程序的移植。
多遍扫描的缺点
每遍都要读符号、送符号,增加了许多重复性的工作,降低编译效率。
(7)程序设计语言范型(从支持的计算模式)
1.强制(命令)式语言:
是面向动作的,即一个计算过程看做是一系列动作,其动作是命令驱动,以语言形式表示。
也称过程式语言,如C,FORTRAN等;
2.函数式语言:
注重程序表示的功能
也称应用式语言,如ML和LISP等;
3.基于规则的语言:
检查一定的使能条件,满足时执行动作
也称逻辑程序设计语言,如PROLOG。
4.面向对象语言:
提供抽象数据类型,支持封装性、继承性和多态性。
如C++和Java等。
(1)符号和符号串
1、字母表:
元素的有穷非空集合。
2、符号串:
由字母表中的符号组成的任何有穷序列。
3、符号串的头尾,固有头和固有尾:
如果z=xy是一符号串,那么x是z的头,y是z的尾,如果x是非空的,那么y是固有尾;
同样如果y非空,那么x是固有头。
如:
设z=abc,那么z的头是,a,ab,abc,除abc外,其它都是固有头;
z的尾是,c,bc,abc,z的固有尾是,c,bc。
4、符号串的运算
(1)符号串的连接:
设x和y是符号串,x和y的连接xy是把y的符号写在x的符号后得的符号串。
如:
x=ST,y=abu,则xy=STabu显然有x=x=x。
(2)符号串的方幂:
设x是符号串,把x自身连接n次得x的几次方幂xn。
设x=ab则x0=x1=abx2=ababx3=ababab
(3)符号串集合的乘积:
设A和B为符号串集合,则A和B的乘积定义为AB={xy|xA且yB}
a={a,b},B={00,11}则AB={a00,a11,b00,b11}显然:
{}A=A{}=A
(4)符号串集合的方幂:
设A为符号串集,则A的n次方幂An定义为:
An=AA……A=AAn-1=An-1A
(5)符号串集合的正闭包A+:
A+=A1UA2U…UAnU…
(6)符号串集合的闭包A*:
A*=A0UA+={}UA+
设有正字母表={0,1}则*=0U1U2U…UnU…={,0,1,00,01,10,11,000,001,……}
(2)文法
文法G定义为四元组(VN,VT,P,S)其中:
(1)VN为非终结符号集
非终结符号表示一个语言短语(或语法成分、语法单位)。
如程序、语句、表达式等。
一般用大写字母或用〈〉括起表示非终结符号。
(2)VT为终结符号集
终结符号:
组成语言的基本符号。
是文法中不属于非终结符号集合的符号。
一般用小写字母或不带〈〉的符号表示。
如程序设计语言的单词符号。
设V=VNUVT,称V为文法G的字母表。
(3)P为产生式(也称规则)的集合。
产生式的形式:
→或∷=,其中∈V+,∈V*
(4)S称作识别符号或开始符号,是一个非终结符号。
一般表示此文法定义的最大语法短语,至少要在一条产生式中作为左部出现。
句型、句子的定义
设G[S]是一文法,如果符号串x是从识别符号推导出来的,即有S*x,则称x是文法G[S]的句型。
若x仅由终结符号组成,即S*x,xVT,则称x为G[S]的句子。
句型:
在一棵树生长过程的任何时刻,所有那些端末结点自左至右的排列,就是一个句型。
语言的定义:
文法G产生的语言记为L(G),它是文法G产生的全部句子的集合。
文法等价定义:
若L(G1)=L(G2)则称文法G1和G2是等价的。
(3)文法的类型N.Chomsky
0型文法:
定义0型语言,对应Turing机;
1型文法:
定义1型语言,对应线性限界自动机;
箭头后面的要比前面的长或相等
2型文法:
定义2型语言,对应非确定下推自动机;
箭头前面的是非终结符,后面是串
3型文法:
定义3型语言,对应有限自动机。
非终结符可以推出一个终结符或一个终结符和一个非终结符
最右推导也称为规范推导,所得句型称为规范句型。
如果一个文法存在某个句型对应两棵不同的语法树,则说这个文法是二义的。
或者说,若一个文法中存在某个句型,它有两个不同的最左(最右)推导,则这个文法是二义的。
上下文无关文法是否具有二义性是不可判定的。
但有些特殊的2型文法[例如LL
(1)、LR(0)、LR
(1)等文法]是无二义性的。
一个文法兼有左递归和右递归是导致二义性的常见原因。
排除文法二义性通常有两种方法:
(1)在语义上加些限制
(2)重新构造一个无二义性的文法
(4)句型的分析
句型的分析:
就是识别一个符号串是否为某文法的句型。
是某个推导的构造过程。
分析方法分两大类:
自上而下分析法和自下而上分析法推导与归约,最右推导是规范推导,逆过程为规范规约
若S*A+(由A+得)则称是句型相对于非终结符A的短语。
若S*A(由A→得)则称是句型相对于A→的直接短语(也称简单短语)。
一个句型的最左直接短语称为该句型的句柄。
一棵子树(至少要有父子两代)的所有端末结点自左至右排列起来形成相对于子树根的短语。
若子树只有父子两代,则得到直接短语。
(5)有关文法
(1)有害规则文法中含形如U→U的产生式。
它对描述语言没有必要,且会引起文法的二义性。
(2)多余规则文法中任何一个句子的推导都用不到的规则。
(3)无用规则文法中含形如U→V的产生式,即单产生式。
为保证文法G的任一非终结符A在句子推导中出现,必须满足如下两个条件:
(1)A必须在某句型中出现,A。
(2)必须能够从A推导出终结符号串t。
有关文法的化简和改造,包括以下几项工作:
(1)无用符号和无用产生式的删除。
(2)-产生式的消除。
(3)单产生式的消除。
(4)左递归的消除。
(1)词法分析输出
单词符号(TOKEN)是一个程序设计语言的基本语法符号。
程序设计语言的单词符号一般可分成下列5种:
1.基本字,也称关键字,如PASCAL语言中的begin,end,if,while和var等。
2.标识符,用来表示各种名字,如常量名、变量名和过程名等。
3.常数,各种类型的常数,如25,3.1415,TRUE和"
ABC"
等。
4.运算符,如+,*,<
=等。
5.界符,如逗点,分号,括号等。
词法分析程序所输出的单词符号常常采用下二元式表示:
(单词种别,单词自身的值)
可用整数码或助记符等表示。
(2)单词的描述工具
程序设计语言中的单词(TOKEN)是基本语法符号。
单词符号的语法可以用有效的工具加以描述。
正规式和它所表示的正规集的递归定义如下。
设字母表为∑,辅助字母表∑={|,·
*,(,)}
定义(正规式和它所表示的正规集):
设字母表为Σ,辅助字母表Σ`={Φ,ε,|,·
,*,(,}。
2ε和Φ都是Σ上的正规式,它们所表示的正规集分别为{ε}和{};
②任何a∈Σ,a是Σ上的一个正规式,它所表示的正规集为{a};
③假定e1和e2都是Σ上的正规式,它们所表示的正规集分别为L(e1)和L(e2),那么,(e1),e1|e2,e1·
e2,e1*也都是正规式,它们所表示的正规集分别为L(e1),L(e1)∪L(e2),L(e1)L(e2)和(L(e1))*。
④仅由有限次使用上述三步骤而定义的表达式才是Σ上的正规式,仅由这些正规式所表示的字集才是Σ上的正规集。
(3)有穷自动机
有穷自动机(也称有限自动机)作为一种识别装置,它能准确地识别正规集,即识别正规文法所定义的语言和正规式所表示的集合,引入有穷自动机这个理论,正是为词法分析程序的自动构造寻找特殊的方法和工具。
确定的有穷自动机(DFA):
定义:
一确定的有穷自动机(DFA)M是一个五元组:
M=(K,∑,f,S,Z)其中
1.K是一个有穷集,它的每个元素称为一个状态;
2.∑是一个有穷字母表,它的每个元素称为一个输入字符,所以也称为输入符号字母表;
3.f是转换函数,是在K×
∑→K上的映像,即,如f(ki,a)=kj,就意味着,当前状态为ki,输入字符为a时,将转换到下一状态kj,我们把kj称为ki的一个后继状态;
4.S是唯一的一个初态;
5.Z是一个终态集,终态也称可接受状态或结束状态。
DFA的作用:
对于∑*中的任何字符串t,若存在一条从初态到某一终态结的道路,且这条路上所有弧的标记符连接成的字符串等于t,则称t可为DFAM所接受,若M的初态结同时又是终态结,则空字可为M所识别。
DFAM所能接受的字符串的全体记为L(M)。
不确定的有穷自动机(NFA)
一个不确定的有穷自动机(NFA)M是一个五元组,M=(K,∑,f,S,Z)。
3.f是一个从K×
∑*到K的幂集的映象
4.S属于K,是一个非空初态集
5.Z属于K,是一个终态集
区别:
DFA:
只有唯一初态。
NFA:
有初态集。
DFA是NFA的特例。
对于每个NFAM,存在一个DFAM’,使得L(M)=L(M’)
对于任何两个有穷自动机M和M’,如果L(M)=L(M’),则称M与M’是等价的。
(1)自顶向下语法分析
语法分析的作用是识别由词法分析给出的单词符号序列是否是给定文法的正确句子。
其中自顶向下分析,就是从文法的开始符号出发企图推导出与输入的单词串完全匹配的句子,若输入串是给定文法的句子,则必能推出,反之必然出错。
FIRST()={a|a,aVT,,V*}
(1)求FIRST(x),xV
(a)若xVT,则FIRST(x)={x}
(b)若x是,则FIRST(x)={}
(c)若xVN,且x→y1y2…ym|…|z1z2…zn
则FIRST(x)=FIRST(y1y2…ym)∪…∪FIRST(z1z2…zn)
(2)求FIRST(y1y2…ym),其中y1,y2,…,ymV。
(a)若y1VT,则FIRST(y1y2…ym)={y1}
(b)若y1VN,FIRST(y1),则FIRST(y1y2…ym)=FIRST(y1)
若FIRST(y1),则FIRST(y1y2…ym)=(FIRST(y1)\{})∪FIRST(y2y3…ym)
按上法求FIRST(y2y3…ym),类推下去。
对文法中每一AVN,计算FOLLOW(A)
(a)设S为文法的开始符号,则#FOLLOW(S)
(b)若有A→B,则将FIRST()-{}加入到FOLLOW(B)中,如果其中,则将FOLLOW(A)加入到FOLLOW(B)中。
计算SELECT集
SELECT(A→)=FIRST(),其中。
若,则SELECT(A→)=(FIRST()-{})∪FOLLOW(A)
判定LL
(1)文法
对每个非终结符A的两个不同产生式,A→,A→,满足SELECTC(A→)∩SELECT(A→)=其中、不能同时
(2)非LL
(1)文法到LL
(1)文法的等价变换
由LL
(1)文法的定义可知,若文法中含有直接或间接左递归,或含有左公共因子,则该文法肯定不是LL
(1)文法。
参考:
文法含左递归不便于使推导按从左往右的顺序匹配,甚至使分析发生死循环。
(a)消除直接左递归
一般情况下,直接左递归的形式为:
A→A1|A2|…|Am|1|2|…|n
消除左递归后改写为:
A→1A|2A|…|nA
A→1A|2A|…|mA|
(b)消除间接左递归
先通过产生式的替换,将间接左递归变为直接左递归,然后再消除直接左递归。
(3)确定的自顶向下分析方法
1、基本思想
对每一非终结符构造一个过程,每个过程的功能是识别由该非终结符推出的串。
2、编写程序
IP:
是输入串指示器,开始工作前IP指向串的第一个符号,每个程序工作完后,IP指向下一个未处理符号。
sym:
表示IP所指符号。
ADVANCE:
是过程,让IP指向下一个符号。
ERROR:
是出错处理子程序。
(4)预测分析方法
(1)预测分析表M如下矩阵形式:
矩阵M
•行标题用文法的非终结符表示。
•列标题用文法的终结符号和#表示。
•矩阵元素M[A,a]的内容是产生式A→(或→)表明当对A进行推导,面临输入符号a时,应采用候选进行推导。
出错处理标志(即表中空白项)表明A不该面临输入符号a。
(2)符号栈
用于存放文法符号,栈顶为推导过程中句型尚未匹配部分的开头符号。
分析开始时,栈底先放一个#,然后放进文法开始符号,即S#
(3)预测分析总控程序
总是按栈顶符号x和当前输入符号行事。
对于任何(x,a),总控程序每次都执行下述三种可能动作之一:
(a)若x=a=‘#’,则宣布分析成功。
(b)若x=a‘#’,则把x从栈顶逐出,指针指向下一输入符号。
(c)若x是一个非终结符,则查看分析表M。
①如果M[A,a]中存放关于X的一个产生式,那么,首先把X顶出栈,然后把产生式右部符号串按反序一一推进栈。
②如果M[A,a]中存放“出错标志”,则调用出错处理程序ERROR。
(1)自底向上优先分析法
自底向上分析方法,也称移进—归约分析法,粗略地说它的实现思想是对输入符号串自左向右进行扫描,并将输入符逐个移入一个后进先出栈中,边移入边分析,一旦栈顶符号串形成某个句型的句柄时,(该句柄对应某产生式的右部),就用该产生式的左部非终结符代替相应右部的文法符号串,这称为一步归约。
重复这一过程直到归约到栈中只剩文法的开始符号时则为分析成功,也就确认输入串是文法的句子。
可以看出,移进一归约过程是自顶向下最右推导的逆过程。
最右推导称为规范推导。
自左向右的归约过程称为规范归约。
如何知道何时在栈顶符号串中已形成某句型的句柄,这是自底向上分析的关键。
在自底向上分析方法中,本章主要介绍常用的算符优先分析法和LR类分析法。
(2)算符优先分析法
算符文法的定义:
设有一文法G,如果G中没有形如A→…BC…的产生式,其中B和C为非终结符,则称G为算符文法(OperaterGrammar)也称OG文法。
(文法中没有两个非终结符相临的情况,则称是算符文法)
性质1在算符文法中任何句型都不包含两个相邻的非终结符。
性质2如果Ab或bA出现在算符文法的句型中;
其中AVN,bVT,则中任何含b的短语必含有A。
算符优先文法的定义:
设有一不含产生式的算符文法G,如果对任意两个终结符对a,b之间至多只有<
、>
和=三种关系的一种成立,则称G是一个算符优先文法。
(OperatorPrecedenceGrammar)即OPG文法。
(3)算符优先关系表的构造
FIRSTVT(B)={b|Bb…或BCb…}
构造规则:
(1)若B→b…或B→Qb…,则bFIRSTVT(B)
(2)若B→Q…,则FIRSTVT(Q)FIRSTVT(B)
LASTVT(B)={a|B…a或B…aC}
构造规则
(1)若B→…a或B→…aQ,则aLASTVT(B)
(2)若B→…Q,则LASTVT(Q)LASTVT(B)
最左素短语:
设有文法G[S],其句型的素短语是一个短语,它至少包含一个终结符,并且除自身外不包含其它素短语,最左边的素短语称最左素短语。
(4)归约步骤
初始时栈底存#,输入指针指向输入串的首字符。
控制程序根据栈顶终结符a(若栈顶是非终结符,则次栈顶的终结符称为栈顶终结符)和输入指针所指的输入符b,查优先关系表M,可能有四种情况:
(1)M[a,b]为<
或=时移进b,即将b进栈,输入指针指向下一输入符。
(2)M[a,b]为>
时,则将栈顶含a的素短语按对应的产生式归约,素短语与产生式右部需终结符对应相同,非终结符位置应相同名称可不同。
顶出栈中素短语,非终结符入栈。
(3)M[a,b]为空白,语法错,调用相应出错处理程序。
(4)a=b=#时分析结束。
(5)优先函数
用关系法构造。
构造步骤:
(a)对每一终结符a(包括#),用fa,ga为结点名。
(b)若ai>
aj或ai=aj,则从fai到gaj画一条箭弧。
若ai<
aj或ai=aj,则从gaj到fai画一条箭弧。
(c)给每个结点赋一个数,此数等于从该结点出发所能到达的结点(包括该结点自身在内)的个数。
赋给结点f(ai)的数,就是函数f(ai)的值,赋给g(aj)的数,就是函数g(aj)的值。
(d)对构造出的优先函数,按优先关系矩阵检查一遍是否满足优先关系的条件,若不满足时,则在关系图中有回路说明不存在优先函数。
优先函数的优缺点
优点:
(1)节省存储空间;
(2)执行整数比较运算比查优先关系表方便。
缺点:
(1)有些优先关系表不存在优先函数。
(2)原先不存在优先关系的两个终结符变成可比较其函数值大小了,需加以克服。
(1)LR分析法
LR分析法是一类对上下文无关文法进行“自左向右的扫描和最左归约(即最右推导的逆过程)”分析的方法,是一种规范归约过程。
LR(k)分析方法是1965年Knuth提出的,其中k表示向右查看输入符号串的个数。
(1)总控程序所有LR分析器的总控程序都是相同的,共有四种动作:
移进、归约、接受、出错。
(2)分析表常见的有四种:
LR(0)分析表适应文法范围小,是其它类型分析表构造的基础。
SLR
(1)分析表是LR(0)分析表的改进,适应文法范围强于LR(0)。
LR
(1)分析表分析能力强(指适应范围,查错速度),但状态太多。
LALR
(1)分析表是LR
(1)分析表的改进,分析能力强于SLR而稍弱于LR
(1),但状态少于LR
(1)
(3)分析栈包括文法符号栈和相应的状态栈。
(2)LR(0)分析
可归前缀
规范句型中,包括句柄及句柄以左的部分,称为可归前缀。
有些可归前缀的前缀是相同的,不仅仅属于某一个规范句型。
我们把可归前缀的前缀称为活前缀。
进行语法分析时,只要将待分析符号串的当前部分符号与i[Pi]进行比较,便可知是否归约,以及应按哪条产生式归约。
为了得到所有可归前缀,可以对文法G构造一个有穷自动机,该有穷自动机能识别文法G的所有可归前缀。
构造识别可归前缀的有穷自动机
项目:
文法的识别可归前缀的有穷自动机以文法的“项目”作为它的状态,所谓文法的项目,是在文法的每一条规则的右部添加一个圆点而形成。
之所以这样构造项目,是受可归前缀的启发。
圆点表示在识别可归前缀的过程中,对句柄(即某产生的右部)已识别过的部分。
项目分四类
(a)圆点在最右端的项目,形如A→·
,表示已从输入串看到能由一条产生式右