大数据专业,2024.5.31考,编译原理回忆版
考试回忆
考前就听说增加了客观题,果然多了判断题,因为和软工学的内容不同,我们多考了语义分析和代码优化
判断题
-
正则文法能够表示高级编程语言的语法结构
-
NFA对于每个符号及状态,有且只有一条边
-
DFA不能描述a^nb^n这个语言
-
(想不起来了)
解释概念题(各四分)
1.推导与规约
2.LL、LR中大写字母的含义
3.综合属性和继承属性
4.公共子表达式
5.归纳变量与强度减弱
简答题(共23分)
-
什么是编译,前端和后端分别包括哪些部分(5分)
-
上下文无关文法包含哪些部分,详细阐述,写出语言L(G) = {anbcn|n>=0}的上下文无关文法(8分)
-
解释回填思想
-
什么是预测分析,预测分析的工作流程是什么
计算题
(0|1)*01的NFA,DFA,最小化
语法分析
E->TE'
T->FT'
F->DIGIT
T'->*FT'|\epsilon
E'->+TE'|\epsilon
(1)写FIRST集和FOLLOW集,判断是否为LL(1)文法
(2)写SELECT集和预测分析表
语义分析
PPT原题
写出语义规则,用S-SDD
答案:
综合题
给了一大段代码(17个),b和r是活跃变量
(1)n=10
(2)n1 =1
(3)n2=1
(4)b = n+n
(5) t= n1+n2
(6)if n<=2 goto (7)
(7)r=1
(8) goto (17)
(9)i=3
(10)r=n1+n2
(11)n1=n2
(12)n2=r
(13)k = n*2
(14) i=i+1
(15)if i<=n goto (10)
(16)r= r / k
(17)
-
代码分块并画流图
-
使用3种以上技术进行代码优化
-
在代码生成过程中,如果运算分量还没存到寄存器,且没有空闲寄存器,该如何处理。
个人复习总结
以下是临近考前总结的一些偏概念性问题
CH 1 编译器总体概览
-
编译的过程
-
编译器分为前端(分析部分)和后端(综合部分)
-
前端:
-
前端是机器无关的,把源程序分解成单词元素,以及相应的语法结构,根据这个语法结构创建源程序的中间表示,同时收集和源程序相关的信息,存放到符号表
-
-
后端:
-
后端是机器相关的,根据中间表示和符号表信息构造目标程序
-
一遍扫描:对源语言或源语言的中间结果从头到尾扫描一次,并作有关的加工处理,生成新的中间结果或目标程序。
-
-
各部分:
-
词法分析器(扫描):读入源程序的字符流,将其组织成有意义的词素,产生词法单元作为输出,<token-name,attribute-value>
-
语法分析器(解析):根据文法构造分析表,对单词符号进行语法分析,检查程序是否符合语法规则
作用:从词法分析器获得一个由词法单元组成的串,并验证这个串可以由源语言的文法生成。
-
语义分析器和中间代码生成器:统称为语义翻译,按照文法翻译规则对语法分析器归约出的语法单元进行语义分析,并把他们翻译成一定形式的中间代码
-
语义分析:使用语法树和符号表中的信息检查源程序是否和语言定义语义一致
-
中间代码生成:编译器生成一个明确的低级语言或类机器语言的中间表示
-
-
代码优化器:对中间代码进行优化处理
-
代码生成器:把中间代码翻译成目标代码
-
符号表管理:记录源程序中使用的变量的名字,收集各种属性
-
-
趟:每趟读入一个输入文件,产生一个输出文件
-
一遍扫描:对源语言或源语言的中间结果从头到尾扫描一次,并作有关的加工处理,生成新的中间结果或目标程序。
CH 2 文法等基本概念
-
字母表是有穷符号集合
-
串:是字母表中符号的一个有序序列
-
文法:描述语言语法结构的形式规则,即语法规则。根据文法可推导出句子(语言)
-
上下文无关文法:对每个语法结构的处理与其所在上下文无关
-
形式化定义:包括四个部分,终结符VT,非终结符VN,开始符号S,一组产生式P
-
-
产生式:描述了终结符和非终结符组合成串的方法
-
推导:
-
归约:推导的逆过程
-
句型:
-
句子:
-
语言:由文法G的开始符号推导出的所有句子构成的集合称为文法G的语言,记为L(G)
-
文法二义性:如果一个文法的某个句子对应两颗不同的语法树,即最左(最右)推导不唯一,则称该文法为二义性文法。二义性文法对同一句子有多个最左推导或最右推导
-
为什么要消除二义性:
-
通常要求程序设计语言的文法无二义性,否则会导致一个程序有多个”正确“的解释。
-
-
四种文法:
CH 3 词法分析
-
词素:源程序中的字符序列,它和某个词法单元的模式匹配,被词法分析器识别为该词法单元的实例
-
正则语言:可以用RE定义的语言称为正则语言
-
状态转换图可用于识别(或接受)一定的字符串
-
有穷自动机FA:系统只需要根据当前所处状态和当前面临的输入信息就可以决定系统的后继行为。每当系统处理了当前的输入后,系统的内部状态也将发生变化
-
串被FA接收:给定输入串x,如果存在一个对应于串x的从初始状态到某个终止状态的转换序列,则称串x被FA接收
-
FA定义的语言:有一个有穷自动机M接受的所有串构成的集合称为由FA定义的语言,L(M)
-
NFA: 边上的标号没有限制,一个符号可以出现在离开同一个状态的多条边上,\epsilon可以做标号
-
DFA:对于每个状态及每个符号,有且只有一条边
-
词法分析器的恐慌模式:从剩余的输入中不断删除字符,直到词法分析器能够在剩余输入的开头发现一个正确的字符为止。
CH 4 语法分析
-
语法分析方法:
-
自顶向下的方法:从文法的开始符号开始,向下推导,推出句子。从语法分析树的根部开始构造语法分析树
-
自底向上的方法:从输入串开始,逐步进行归约,直到归约到文法开始符号,从语法分析树的叶子开始构造语法分析树
-
-
正则表达式都有一个CFG与其对应,但反之不成立
-
最左推导:每次推导时选择最左边的非终结符进行替换
-
最右推导:每次推导时选择最右边的非终结符进行替换
-
左递归:如果一个文法中有非终结符符号使得A--->(+)Aa,那么这个文法就是左递归的
-
自顶向下的语法分析需要消除左递归
-
含有A→Aα形式产生式的文法称为是直接左递归的
-
经过两步或两步以上推导产生的左递归称为是间接左递归的
-
递归下降分析:
-
由一组过程组成,每个过程对应一个非终结符。从文法开始符号S对应的过程开始,其中递归调用文法中其它非终结符对应的过程。如果S对应的过程体恰好扫描了整个输 入串,则成功完成语法分析
-
-
预测分析:
-
预测分析是递归下降分析技术的一个特例,通过在输入中向前看固定个数(通常是一个)符号来选择正确的A-产生式
-
可以对某些文法构造出向前看k个输入符号的预测分析器,该类文法有时也称为LL(k) 文法类
-
预测分析不需要回溯,是一种确定的自顶向下分析方法
-
-
S_文法
-
每个产生式的右部都以终结符开始
-
同一非终结符的各个候选式的首终结符都不同
-
-
FOLLOW集(后继符号集):非终结符A的FOLLOW集:可以在某个句型中紧跟在A后边的终结符a的集合。
-
FOLLOW集中没有\epsilon
-
可以有$
-
-
如果位于末尾就加上产生式左部的非终结符的FOLLOW集,否则就加上后边的串的FIRST集,有空串就去掉。
-
-
-
SELECT集(可选集):产生式A-->\beta的可选集是指使用该产生式进行推导时对应的输入符号的集合
-
产生式A-->a的可选集:
-
-
q_文法
-
每个产生式的右部或为ε,或以终结符开始
-
具有相同左部的产生式有不相交的可选集
-
-
FIRST集(串首终结符集):给定一个文法符号串α,α的串首终结符集FIRST(α)被定义为可以从α推导出的所有串首终结符构成的集合。如果α -->*ε, 那么ε也在FIRST(α)中
-
文法符号X的FIRST集
-
可以从X推导出的所有串首终结符构成的集合
-
-
-
LL(1)文法:
-
文法使用条件:
-
文法不含左递归
-
对A->\alpha1|...|\alphan的每对候选式,有First(\alpha1) \cap FIRST(\alphaj) = \emptyset
-
对非终结符符号A,若\epsilon \in FITRST(A),有FITRST(A)\cap FOLLOW(A) = \emptyset
定义:一个文法是LL(1)的当且仅当G的两个不同的产生式A-->\alpha|\beta满足下面的条件
-
不存在终结符号a使得\alpha和\beta都能推导出以\alpha开头的串
-
\alpha和\beta 至多只有一个可以推导出空串
-
如果β -->* ε,则FIRST (α)∩FOLLOW(A) =Φ; 如果α -->*ε,则FIRST (β)∩FOLLOW(A) =Φ
-
-
-
LL(1)文法分析方法
-
递归的预测分析法
-
是指:在递归下降分析中,根据预测分析表进行产生式的选择
-
根据每个非终结符的产生式和LL(1)文法的预测分析表,为 每个非终结符编写对应的过程
-
-
非递归的预测分析
-
不需要为每个非终结符编写递归下降过程,而是根据预测分析表构造一个自动机,也叫表驱动的预测分析
-
-
-
预测分析实现步骤
-
构造文法
-
改造文法:消除二义性、消除左递归、消除回溯
-
求每个变量的FIRST集和FOLLOW集,从而求得每个 候选式的SELECT集
-
检查是不是LL(1) 文法。若是,构造预测分析表
-
对于递归的预测分析,根据预测分析表为每一个非终结 符编写一个过程;对于非递归的预测分析,实现表驱动的预测分析算法
-
-
恐慌模式:
-
忽略输入中的一些符号,直到输入中出现由设计者选定 的同步词法单元(synchronizing token)集合中的某个词法单元
-
如果终结符在栈顶而不能匹配,一个简单的办法就是弹 出此终结符
-
-
短语:给定一个句型,其分析树中的每一棵子树的边缘称为该句 型的一个短语(phrase)
-
直接短语:如果子树只有父子两代结点,那么这棵子树的边缘称为该句型的一个直接短语(immediatephrase)
-
移入-归约分析
-
在对输入串的一次从左到右扫描过程中,语法分析 器将零个或多个输入符号移入到栈的顶端,直到它 可以对栈顶的一个文法符号串β进行归约为止
-
然后,它将β归约为某个产生式的左部
-
语法分析器不断地重复这个循环,直到它检测到一个语法错误,或者栈中包含了开始符号且输入缓冲区为空为止
-
-
移入:将下一个输入符号移到栈的顶端
-
归约:被归约的符号串的右端必然处于栈顶。语法 分析器在栈中确定这个串的左端,并决定用哪个非 终结符来替换这个串
-
接收:宣布语法分析过程成功完成
-
报错:发现一个语法错误,并调用错误恢复子例程
-
句柄:句型的最左直接短语
-
LR文法(Knuth, 1963) 是最大的、可以构造出相应 移入-归约语法分析器的文法类
-
L: 对输入进行从左到右的扫描
-
R: 反向构造出一个最右推导序列
把"历史"及"展望"综合抽象成状态;由栈顶的状态和现行的输入符号唯一确定每一步工作。
-
-
LR(k)分析
-
需要向前查看k个输入符号的LR分析
-
-
项目:右部某位置标有圆点的产生式称为相应文法的一个LR(0) 项目(简称为项目)。项目描述了句柄识别的状态
-
增广文法引入新的开始符号的意义
-
引入这个新的开始产生式的目的是使得文法开始符号仅出现 在一个产生式的左边,从而使得分析器只有一个接受状态
-
-
后继项目
-
同属于一个产生式的项目,但圆点的位置只相差一个符号, 则称后者是前者的后继项目
-
A→α· Xβ的后继项目是A→αX·β
-
-
展望符:
-
将一般形式为[A→α·β, a]的项称为LR(1)项,其中A→αβ是 一个产生式,a是一个终结符(这里将$视为一个特殊的终结符) 它表示在当前状态下,A后面必须紧跟的终结符,称为该项的展望符(lookahead)
-
CH 5 SDT
-
语法制导定义
-
SDD是对CFG的推广,将每个文法符号X和一个语义属性集合{a}相关联
-
将每个产生式和一组语义规则相关联,这些规则用于计算该产生式中各文法符号的属性值
-
-
语法制导翻译
-
对字符串进行语法分析,构造语法分析树,然后根据需要遍历语法树并在各节点处按照语义规则进行计算,这种有源程序的语法结构驱动方式就称为语法制导翻译
-
-
抽象语法树在语法制导翻译中的作用
-
抽象语法树中,每个结点代表一个语法结构,比如对应某个运算符;结点的每个子结点代表其子结构,比如对应运算分量,表示这些子结构按照特定的方式组成了较大的结构,可以忽略掉一些标点符号等非本质的东西。抽象语法树是将源代码转换为目标代码的中间表示形式,可以帮助我们更好地理解源代码的结构和语义。在语法制导翻译中,我们可以通过遍历抽象语法树来执行语义动作,生成目标代码。
-
-
综合属性:是指从语法树的子节点计算并传递给父节点的属性值。在分析树上节点N的非终结符A的综合属性只能通过N的子节点或N本身的属性值来定义。
-
终结符的综合属性值是由词法分析器提供的词法值
-
-
继承属性:指从父节点或相邻兄弟节点传递到当前节点的值。在分析树上结点N上的非终结符A的继承属性只能通过N的父节点、N的兄弟节点或N本身的属性值来定义。
-
终结符没有继承属性
-
-
属性文法:是一种描述语言语法及其语义属性的强大工具。
-
属性文法是没有副作用的SDD,SDD是对CFG的推广,将每个文法符号与一个语义属性集合相关联
-
将每个产生式与一组语义规则相关联,这些规则用于计算该产生式中各文法符号的属性值
-
-
S-属性文法:只有综合属性的文法
-
L-属性文法:既有综合属性,又有继承属性,在L属性文法中,一个节点的继承属性可能依赖于
-
产生式右部中该符号左侧的属性
-
产生式头部的继承属性
-
节点本身的值
-
-
依赖图
-
依赖图是一个描述了分析树中结点属性间依赖关系的有向图
-
-
三地址代码:
-
是中间代码的一种表示形式
-
是语法树或DAG的线性表示形式
-
三地址代码包含地址和指令
-
三地址代码可用四元式或三元式或间接三元式表示
-
-
回填技术:生成一个跳转指令时,暂时不指定该跳转指令的目标标号。这样的 指令都被放入由跳转指令组成的列表中。同一个列表中的所有跳转指令具有相同的目标标号。等到能够确定正确的目标标号时,才去填充这些指令的目标标号
-
基本块:
-
是满足下列条件的最大的连续三地址指令
-
控制流只能从基本块的第一条指令进入基本块,也就是说不存在跳转到基本块的中间或末尾指令的跳转指令
-
除了基本块的最后一个指令,控制流在离开基本块之前不会跳转或者停机
-
-
-
流图
-
流图的节点是一些基本块
-
从基本块B到基本块C之间有一条边当且仅当基本块C的第一个指令可能紧跟在B的做后一条指令之后执行
-
-
基本块划分算法:
-
确定首地址
-
第一条三地址代码
-
任意一条(无条件\条件)跳转指令跳转到的目标指令
-
紧跟在一个无条件\条件跳转指令之后的指令
-
-
上一条首地址到下一条首指令之间构成一个基本块
-
-
代码生成器主要任务:
-
指令选择:选择适当的指令实现中间表示语句
-
寄存器分配和指派:把哪个值放在哪个寄存器中
-
指令排序:按照什么顺序安排指令执行
-
CH 6 优化
-
代码优化的目的
-
为改进代码进行的等价程序变换,使其运行更快,占用空间更少或者两者兼顾
-
对中间代码进行改进,以生成更好的目标代码,更快、更短、能耗更低
-
-
机器无关代码优化
-
删除公共子表达式
-
如果表达式x op y先前已经被计算过,并且从先前的计算到现在,x op y 中变量的值没有改变,那么x op y 的这次出现就称为公共子表达式
-
-
删除无用代码
-
复制传播
-
常用的公共子表达式消除算法和其他一些优化算法会引入一些复制语句。
-
复制传播:在复制语句x= y 之后尽可能的用y代替x
-
-
无用代码(死代码):其计算结果永远不会被使用的语句
-
-
常量合并
-
如果在编译时刻推导出一个表达式的值是常量,就可以用该常量来代替这个表达式,该技术称为常量合并
-
-
强度削弱
-
用较快的操作代替较慢的操作,比如用加代替乘
-
-
代码外提
-
处理的是那些不管循环执行多少次都得到相同结果的表达式(即循环不变计算),在进入循环之前就对他们求值
-
-
删除归纳变量
-
归纳变量:对于一个变量x,如果存在一个正的或负的常数c使得每次x被赋值时它的值总增加c,那么就称为归纳变量
-
在沿着循环运行时,如果有一组归纳变量的值的变化保持步调一致,尝尝可以将这组变量删除为只剩一个。
-
-
-
机器相关代码优化
-
窥孔优化
-
定义:在优化的时候,检查目标指令的一个滑动窗口(即窥孔),并在只要有可能就在窥孔内用更快或更短的指令来替换窗口中的指令序列
-
分类
-
冗余指令删除
-
控制流优化
-
代数优化
-
代数恒等式
-
强度削弱
-
-
机器特有指令的使用
-
-
-
-
DAG优化(局部优化技术、基本块的优化)
-
首先把一个基本块转换成一个无环有向图
-
然后从一个DAG上删除没有附加活跃变量的根节点
-
-
局部优化是指单个基本块范围内的优化
-
全局优化是指面向多个基本块的优化
-
寄存器描述符:描述每个寄存器当前存储了哪些变量的值
-
地址描述符:描述了每个变量(名字)的当前值存储在哪个或哪些地址,这些地址可以是寄存器、内存地址、栈单元或者是他们的某个集合