编译原理(期末92pass!)
第1章(重点:各种各样的程序及联系、编译的结构、前后端)
1、机器语言与汇编语言统称为低级语言
2、什么是编译程序
- 翻译程序:将某一种语言程序(源语言程序)等价转换为另一种语言程序(目标语言程序)的程序
- 编译程序:把一种高级语言程序等价地转换为另一种低级语言程序(如:汇编语言、机器语言)
- 解释程序:把源语言写的源程序作为输入,但是不产生目标程序,而是边解释边执行源程序本身,
3、编译过程:
- 编译程序的工作分为五个阶段:词法分析👉语法分析👉中间代码产生👉优化👉目标代码生成
- 词法分析
- 任务:输入源程序,对源程序的字符串进行扫描与分解,识别出一个个单词符号
- 原则:构词规则
- 描述工具:有限自动机
- 语法分析
- 任务:在词法分析的基础上根据语言的语法规则把单词符号串分解成各类语法单位
- 原则:语法规则
- 工具:上下文无关文法
- 中间代码产生
- 任务:对各类不同语法范畴按照语言的语义进行初步翻译
- 原则:语义规则
- 中间代码:三元式、四元式、树形结构
- 优化
- 任务:对于前阶段产生的中间代码进行加工变换,以期在最后阶段产生更高效地目标代码
- 原则:程序的等价变换规则
- 目标代码生成
- 任务:把中间代码变换成特定机器上的目标代码
4、编译程序结构
表 | 👇源程序 | |
---|---|---|
格 | 词法分析器 | 出 |
管 | 👇单词符号 | 错 |
理 | 语法分析器 | 处 |
👇语法单位 | 理 | |
语义分析与中间代码生成器 | ||
👇中间代码 | ||
优化段 | ||
👇中间代码 | ||
目标代码 |
遍(pass):对源程序或者源程序的中间表示从头到尾扫描一次,从外存输入,处理后结果输出到外存
编译的前端与后端
- 编译前端:与源语言有关,如词法分析、语法分析、语义分析与中间代码产生,与机器无关的优化
- 编译后端:与目标机有关,与目标及有关的优化,目标代码产生
源语言 | 前端👉 | 中间语言 | 后端👉 | 目标语言 |
---|---|---|---|---|
第2章(文法四要素、什么是上下文无关文法、画语法树、区分几型文法【0/1/2/3】)
文法的含义
描述语言的语法结构的形式规则,是对语言、语言结构的定义和描述
文法的四要素
- 一个文法开始符号(描述对象)
- 一组非终结符(描述语法范畴的一类单词)
- 一组终结符(基本字、运算符)
- 一组产生式规则
上下文无关文法的定义
一个上下文无关文法G是一个四元式G=(VT,VN,S,P)
其中,VT:终结符集合(非空)
VN:非终结符集合(非空),且 VT ∩ VN = 空
S:文法开始符号,S∈VN
P:产生式集合(有限)
开始符号S至少必须在某个产生式左部出现一次,但尽量不单独出现在产生式右部
一个上下文无关文法定义一个语言的中心思想是
从S出发,连续反复地使用产生式规则对非终结符进行替换与展开,直到推导出全部的终结符为止。
推导过程中出现的一些符号
+:一步或若干步
*:经过0步或若干步
一些定义:
假设G是一个文法,S是它的开始符号,如果
S-(*)->α,则称 α 是一个句型,仅含终结符的句型是一个句子,文法所产生的句子的全体是一个语言,把他称为L(G)
最左推导与最右推导
最左推导:任何一步 α→β 都是对α中的最左非终结符进行替换
最右推导:任何一步 α→β 都是对α中的最右非终结符进行替换,又称之为“规范推导”
语法树与二义性
语法树:用一张图表示一个句型的推导
二义性:如果一个文法存在某个句子对应两颗不同的语法树,则说明这个文法是二义的
语言的二义性:一个语言是二义性的,如果对它不存在无二义性的文法
对于上下文无关文法的限制
- 不含P->P形式的产生式
- 每个非终结符P必须有用处
形式语言鸟瞰
Chomsky将文法分为四种类型:0、1、2、3型,与上下文无关文法移一样,它们都由四部分组成,但对产生式的限制有所不同
-
0型(短语文法)
- 产生形式:α->β
- α∈(VT∪VN)* ,至少含有一个非终结符,β∈(VT∪VN)*
-
1型(上下文有关文法)
- 产生形式:α->β
- 要求:|α|≤|β|,仅S->e(这是一个空子)例外
-
2型(上下文无关文法)
- 产生形式:A->β
- 其中:A∈VN(非终结符),β∈(VT∪VN)*
-
3型(正规文法)
-
产生形式(右线性文法):
A->αB或A->α
-
其中,α∈VT* ,A,B∈VN
-
产生形式(做线性文法):
A->Bα或A->α
-
其中,α∈VT* ,A,B∈VN
-
四种类型文法之间的关系:3型∈2型∈1型∈0型
第3章词法分析(状态转换图[DFA、正规式],超前搜索技术,有限自动机[DFA],一个大题目!)
1、词法分析器
-
功能:输入源程序,输出单词符号
- 单词符号的种类:
- 基本字:例如 if、while
- 标识符:标是各种名字,如变量名、数组名
- 常数:各种类型的常数
- 运算符:+、-、*、/
- 界符:逗号、分号、括号、空白
- 输出单词符号的表示形式:
- (单词种别,单词自身值)
- 单词符号的种类:
-
词法分析器的设计
-
输入、预处理
输入串放在输入缓冲区中,预处理子程序
-
单词符号识别:超前搜索
-
基本字的识别:需要超前搜索才能确定哪些是基本字
-
标识符识别:字母开头的字母数字串,后跟界符或算符
-
常数识别:有些也要超前搜索
-
算符与界符的识别:把多个字符复合而成的算符与界符拼合成一个单一单词符号
如: :=、**、++
-
-
状态转换图
- 概念:状态转换图是一张有限方向图,一张图里包含有限个状态其中一个为出台,至少一个终态
-
3、正规表达式与有限自动机
- 正规集可以用正规表达式(简称正规式)表示,正规表达式是表示正规集的一种方法,一个字集合是正规集当且仅当他能用正规式表示
- 假设e1和e2都是Σ上的正规式,他们所表示的正规集为L(e1)和L(e2)
- (e1|e2)为正规式,它所表示的正规集为L(e1)∪L(e2)
- (e1.e2)为正规式,它所表示的正规集为L(e1)L(e2)
- **(e1)*为正规式,它所表示的正规集为(L(e1)) ***
4、确定有限自动机
- 自动机M是一个五元式M=(S,Σ,f,S0,F)
- S:有穷状态机
- Σ:输入字母表
- f:状态转换函数,单值映射
- S0:S的唯一的一个初态
- F:终态集
第4章 语法分析——自上而下分析法(1、消除左递归 2、克服回溯 3、递归下降子程序 4、LL(1)预测分析程序法)
语法分析是分析一个文法的句子结构
语法分析器的功能:按照文法的产生式(语言的语法规则)识别输入符号串是否为一个句子
语法分析方法:
-
自下而上分析法:逐步进行“规约”,直到文法的开始符号
方法如下
- 算符优先文法
- LR分析法
- 规范规约
-
自上而下分析法:从文法开始符号出发,反复使用各种产生式,寻找“匹配”的推高
方法如下:
- 递归下降分析法
- 预测分析程序
面临的问题
- 回溯
- 左递归
因此在进行自上而下分析法时,我们应该
-
消除文法的左递归
P->Pa|b 消除左递归后 P->bP' P'->aP'|e(空子)
-
克服回溯
提取公共左因子
递归下降分析程序构造(消除文法的左递归性与克服回溯)
E->TE'
E'->+TE'|e
对应的递归下降子程序:
PROCEDURE E;
BEGIN
T;E';
END
PROCEDURE E';
IF SYM='+' THEN
BEGIN
ADVANCE;
T;E';
END
F->(E)|i
对应的递归下降子程序:
PROCEDURE F;
BEGIN
IF SYM='i' THEN ADVANCE
ELSE
IF SYM='(' THEN
BEGIN
ADVANCE;
E;
IF SYM=')' THEN ADVANCE
ELSE ERROR
END
ELSE ERROR;
END
如果候选式右部全是非终结符开头,应该怎么?
E->TE'|BC
对应的递归下降子程序为:
PROCEDURE E;
BEGIN
IF SYM∈FIRST(TE') THEN
{T;E';}
ELSE IF SYM∈FIRST(BC) THEN
{B;C;}
ELSE ERROR
END
预测分析程序或者LL(1)分析法
三个动作(栈顶符号X、当前输入符号a)
- X=a=‘#’,分析成功!
- X=a≠#',X从栈顶逐出,让a指向下一个输入符号
- X是一个非终结符,将X逐出栈顶,并将产生式右部符号串按反序一一推入栈中(若为空字,则不推什么)
LL(1)分析法分析过程:
- 完成 消除左递归(公式)与克服回溯(公式 提取公共左因子) 两个前提工作
- 求所有候选式的FIRST
- 求对应非终结符的FOLLOW集
- 构造分析表
- 分析输入串
第5章 自下而上分析法(①规范归约——句柄②算符优先文法——最左素短语③LR(0) SLR(1) ④属性文法)
采用“移进——归约”思想进行自下而上分析,基本思想:用一个寄存符号的先进后出的栈,把输入符号一个一个地移入栈里,当栈顶形成某个产生式的候选式时,即把栈顶的这一部分替换成(归约为)该产生式左部符号
规范归约
- 短语(找内部结点,能长叶子的)
- 直接短语(直接长成的)
- 句柄(最左最小的树对应的符号串,在直接短语中最左边的那个)
- 最左素短语(在短语中找,1、至少含有一个终结符;2、不含有其他更小的素短语)
规范归约 定义:假定文法G的一个句子,我们称为序列
αn,αn-1...α1
是α一个规范归约,如果此序列满足
- αn=α
- α0是文法的开始符号,即α0=S
- 对于任何 i ,0<=i<=n,αi-1是从αi经把句柄替换成相应的产生式左部符号而得到的
规范归约是一个最右推导的逆过程,最左规约是规范推导,由规范推导推出来的句型称为规范句型
算符优先分析
定义算符之间的某种优先关系,借助于这种关系可以寻找“可归约串”和进行归约
三种关系(优先关系不传递,不可逆)
a<.b //a的优先级低于b
a=.b //a的优先级等于b
a.>b //a的优先级高于b
什么是算符文法:
一个文法,如果它的任一产生式的右部都不含两个相继(并列)的非终结符,即不含如下形式的产生式右部:…QR…,则称之为 算符文法
(1)a=.b(横看)
形式如下:
P->...ab...或者...aQb...的产生式
(2)a<.b(横看)
形式如下
P->...aR..的产生式,b∈FIRSTVT(R)
(3)a.>b(竖看)
P->...Rb...的产生式,由a∈LASTVT(R)
算符优先文法一般并不等价于规范归约,它的特点:
- 优点:简单、快速
- 缺点:可能错误接受非法句子,能力有限
优先函数 f称为入栈优先函数,g称为比较优先函数
1、a<.b -> f(a)<g(b)
2、a=.b -> f(a)=g(b)
3、a.>b -> f(a)>g(b)
LR分析法
由Knuth提出;规范归约的关键问题就是寻找句柄
LR分析器由两部分组成(总控程序与分析表),它的核心是一张分析表,不同的LR分析法其分析表不同,总控程序对任何分析表一样的工作,
ACTION[s,a]指当状态S面临输入符号a时,应该采取什么样的动作;GOTO[s,X]指状态s面对文法符号X时,下一个状态是什么
每一个ACTION[s,a]所规定四种动作
- 移进
- 归约
- 接受:分析成功acc
- 报错
LR文法,对于一个文法,如果能够构造一张分析表,使得它的每一个入口均是唯一确定的,则这个文法就称之为LR文法
LR(k)文法:一个文法,如果能用一个每步顶多向后检查k个输入符号的LR分析器进行分析,则这个文法就称为LR(K)文法
非LR结构:LR文法不是二义的,二义文法肯定不会是LR文法
文法G的每个产生式右部添加一个圆点,则称为G的LR(0)项目
A->XYZ有四个项目
1、A->.XYZ
2、A->X.YZ
3、A->XY.Z
4、A->XYZ.
这里介绍四种项目
1、归约项目:A->α.
2、接受项目:S'->α.
3、移进项目:A->.αβ(a∈VT)
4、待约项目:A->α.Bβ(B∈VN)
LR(0)分析表的构造,不存在如下情况:
- 既含移进项目,又含归约项目
- 含有多个归约项目
如果没有以上情况,则称为LR(0)文法
SLR分析表的构造
每个SLR(1)文法都是无二义的,但是也存在许多无二义的文法不是SLR(1)的
“移进——归约”冲突解决判断
状态I:
I={X->α.bβ,A->α.,B->α. }
FOLLOW(A)与FOLLOW(B)的交集为空集,且不包含b,那么对了
第6章 属性文法和语法制导翻译
属性:
- 综合属性:“自下而上”传递信息
- 继承属性:“自上而下”传递信息
终结符只有综合属性,由词法分析器提供;非终结符既有综合属性又有继承属性
语义规则所描述的工作可以包括
- 属性计算
- 静态语义检查
- 符号表操作
- 代码生成…
仅仅使用综合属性的属性文法称为——S-属性文法
语法制导翻译法
直观上说,就是为文法中每个产生式配上一组语义规则,并且在语法分析的同时执行这些语义规则
第7章 语义分析和中间代码产生
后缀表达式:又称为逆波兰表示法
图的表示法
DAG图表示法的特点:没有公共部分,这个公共部分不会重复出现,但是会多次使用
三地址代码可以看作是抽象语法树或者DAG的一种线性表示
三元式、间接三元式、四元式的优缺点:
- 三元式
- 优点:三元式没有result字段,且不需要临时变量,故占用空间相对四元式较少
- 缺点:因为三元式之间通过地址指示器密切联系,所以三元式改动比较困难
- 间接三元式(三元式表+间接码表)
- 优点:方便优化,节省空间
- 缺点:
- 四元式:四元式之间的联系是通过临时变量来实现的
- 优点:在进行代码优化处理时,需要从现有的运算序列中删去某些运算或挪动一些运算的位置,这对三元式来说是很困难的,但四元式之间的相互联系是通过临时变量来实现的,所以影响就比较小
- 缺点:占用空间较大
布尔表达式的翻译
两个基本作用:
- 用于逻辑演算,计算逻辑值
- 用于控制语句的条件式
第10章 优化
什么是优化:对程序进行各种等价变换,使得从变换后的程序出发,能生产更有效地目标代码
- 等价:指不改变程序的运行结构
- 有效:指目标代码运行时间段,占用的存储空间小
优化的目的就是为了产生更加高效的代码,还需要遵循一定地原则
- 等价原则
- 有效原则
- 合算原则
优化的三个不同级别:
- 局部优化
- 循环优化
- 全局优化
细节知识点(往年试卷)
1、规范归约是一个最右推导的逆过程;最左归约是规范推导的逆过程
2、代码优化的原则:等价变换原则
3、文法两种属性:综合属性与继承属性