没写的就是不会的
一、 绪论
- 编译程序(编译器)
a.编译程序:把某一种高级语言程序等价地转换成另一种低级语言程序(如汇编语言或机器语言程序)的程序
b.翻译程序:把源程序语言等价地转换成目标语言程序的程序
c.解释程序:把源语言写的源程序作为输入,但不产生目标程序,而是边解释边执行源程序。 - 前后端的划分
a. 前端:词法分析器、语法分析器、语义分析器、中间代码生成器、独立于机器的代码优化器
b.后端:代码生成器、依赖于机器的代码优化器 - 各逻辑阶段的输入和输出
a.词法分析器:输入是源程序,输出是记号流
(注:词法分析也称线性分析,语法分析成为层次分析)
b.语法分析器:在词法分析的基础上,根据语法规则把单词符号分解成各类语法单位 - 哪些逻辑阶段必须有?哪些可以省略?
a.必须有:词法分析器,语法分析器,语义分析器,目标代码生成
b.中间代码生成、中间代码优化、目标代码优化
二、 词法分析
- (注:词法分析是一种线性分析。二元组流包括哪两个,举例分析)
- 词法分析器的功能,对符号表的操作
a.输入源程序、对符号表的操作 - DFA和NFA的定义
a.NFA五部分:有限状态集合S,输入符号集合 ∑ \sum ∑,一个转换函数move: S × ( ∑ ⋃ { ε } ) → P ( S ) [ P ( S ) 指 S 的 幂 集 ] S\times(\sum\bigcup \{\varepsilon\})\rightarrow P(S)[P(S)指S的幂集] S×(∑⋃{ε})→P(S)[P(S)指S的幂集]、初始状态 S 0 S_{0} S0、状态集合F是接受状态集合,并且 F ⊆ S F\subseteq S F⊆S
b.DFA五部分:有限状态集合S,输入符号集合 ∑ \sum ∑,一个转换函数move: S × ∑ → S 单 S\times\sum\rightarrow S_{单} S×∑→S单、初始状态 S 0 S_{0} S0、状态集合F是接受状态集合,并且 F ⊆ S F\subseteq S F⊆S - 举例说明RE不能描述的串
a. RE不能描述配对或嵌套的串
例如1:配对括号串的集合
例如2:{wcw|w是a和b的串}
b.RE能:定义一些简单的语言,能表示给定结构的固定次数的重复或者没有指定次数的重复。例a(ab)^5,a(ba)* - 词法分析主线上的各算法及其功能
a.主线算法MYT,将RE转化为NFA
- 例如:a
- 例如:s|t
- 例如:st
b. 主线算法子集构造算法,将NFA转化为DFA
课本28页 例题2.11
c. 主线算法DFAmin,DFA最小化
- 例题
- 没有提及的重点:
死状态:如果一个DFA不是完全DFA,那么需要加入死状态,DFAmin之后然后删除死状态
Lex:三部分1:声明2:翻译规则3:辅助函数
三、 语法分析
注:语法分析是一种层次分析
- LL(1)文法定义,LL(1)分析表构造算法
A → α ∣ β A\rightarrow\alpha|\beta A→α∣β都满足下面这两个条件
a. F I R S T ( α ) ⋂ F I R S T ( β ) = ∅ FIRST(\alpha)\bigcap FIRST(\beta)=\varnothing FIRST(α)⋂FIRST(β)=∅
b.若 β ⇒ ∗ ε , 那 么 F I R S T ( α ) ⋂ F O L L O W ( A ) = ∅ \beta\Rightarrow^{*}\varepsilon,那么FIRST(\alpha)\bigcap FOLLOW(A)=\varnothing β⇒∗ε,那么FIRST(α)⋂FOLLOW(A)=∅
- 把满足这两个条件的文法称为 LL(1)文法,其中第一个L代表从左向右地扫描输入,第二个L表示产生最左推导,1代表在决定分析器地每步动作时需要向前查看下一个输入符号。
- LL(1)文法,没有公共左因子,不含二义性,不含左递归。
- 分析表的构造:课本58页
a. 对 f i r s t ( α ) 的 每 个 终 结 符 a , 把 A → α , 加 入 到 M ( A , a ) 对first(\alpha)的每个终结符a,把A\rightarrow\alpha,加入到M(A,a) 对first(α)的每个终结符a,把A→α,加入到M(A,a)
b. 如 果 ε 在 f i r s t ( α ) 中 , 对 f o l l o w ( A ) 的 每 个 终 结 符 b ( 包 括 # ) , 把 A → α 加 入 到 M ( A , b ) 中 如果\varepsilon在first(\alpha)中,对follow(A)的每个终结符b(包括\#),把A\rightarrow\alpha加入到M(A,b)中 如果ε在first(α)中,对follow(A)的每个终结符b(包括#),把A→α加入到M(A,b)中
c.M中其它没有定义的条目都是error
- 自上而下语法分析方法有哪些?
LL(1),递归下降的预测分析,非递归的预测分析
- 五部分:中心控制程序,输入带,分析表,栈顶指针,输出
- 自下而上语法分析方法有哪些?
SLR(1)/LR(0),LR(1),LALR(1)
- L是指从左向右扫描输入,R是指构造最右推导的逆,k是指在决定分析动作时向前查看的符号个数,(k)省略时,表示k是1
- 二义性文法的分析表的特点。如何证明二义性文法?
a.二义文法是至少存在一个句子有不止一个最左(最右)推导的文法
证明二义性文法:存在两棵或两棵以上的语法分析树 - 什么是句柄、活前缀
a.句柄:句型的句柄是该句型中和一个产生式右部匹配的子串,并把它规约成该产生式左部的非终结符代表了最右推导过程中的逆过程的一步。句柄的右边仅含终结符。如果文法二义,那么句柄可能不唯一。
- 1. A → β 1.A\rightarrow\beta 1.A→β
-
2.
S
⇒
r
m
∗
α
A
w
⇒
α
β
w
,
在
α
后
的
β
是
α
β
w
的
句
柄
2.S\Rightarrow^{*}_{rm}\alpha Aw\Rightarrow \alpha\beta w,在\alpha后的\beta是\alpha\beta w的句柄
2.S⇒rm∗αAw⇒αβw,在α后的β是αβw的句柄
b.活前缀:是一个文法它的右句型的前缀,该前缀不超过该右句型的最右句柄的右端
- LR(k)的特点、分析表的构造
1.适用于一大类上下文无关文法,效率高
2.栈中的文法符号总是形成一个活前缀
3.分析表中的GOTO本质上是识别活前缀的DFA
4.栈顶状态包含确定句柄所需要的一切信息
5.是已知的最一般的无回溯的移进-规约方法
6.是预测分析法能分析的文法类的真超集
7.能及时发现语法错误
- 没有提及的重点
- 推导:把产生式看成重写规则,把右部非终结符用右部的串来替代
- 消除直接左递归:
消
除
产
生
式
A
→
A
α
∣
β
消除产生式A\rightarrow A\alpha|\beta
消除产生式A→Aα∣β
a. A → β A ′ A \rightarrow\beta A^{'} A→βA′
b. A ′ → α A ′ ∣ ε A^{'}\rightarrow\alpha A^{'}|\varepsilon A′→αA′∣ε - F I R S T 集 : α 经 过 若 干 步 的 推 导 , 第 一 个 位 置 上 为 终 结 符 的 集 合 FIRST集:\alpha经过若干步的推导,第一个位置上为终结符的集合 FIRST集:α经过若干步的推导,第一个位置上为终结符的集合
- F O L L O W 集 : f o l l o w ( A ) { 1. F o l l o w ( S ) = # , . . . 2. F o l l o w ( A ) w → α A β { β 没 有 , 则 F o l l o w ( w ) ⊆ F o l l o w ( A ) β 有 { ε ∉ F i r s t ( β ) , F i r s t ( β ) ⊆ F o l l o w ( A ) ε ∈ F i r s t ( β ) ⊆ { F i r s t ( β ) ⊆ F o l l o w ( A ) F o l l o w ( w ) ⊆ F o l l o w ( A ) FOLLOW集:follow(A) \begin{cases} 1.Follow(S) = {\#,...} \\ 2.Follow(A) \\ w\rightarrow\alpha A\beta \begin{cases} \beta没有,则Follow(w)\subseteq Follow(A)\\ \beta有\begin{cases} \varepsilon\notin First(\beta),First(\beta)\subseteq Follow(A)\\ \varepsilon \in First(\beta) \subseteq\begin{cases} First(\beta)\subseteq Follow(A)\\ Follow(w)\subseteq Follow(A) \end{cases} \end{cases} \end{cases} \end{cases} FOLLOW集:follow(A)⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧1.Follow(S)=#,...2.Follow(A)w→αAβ⎩⎪⎪⎪⎨⎪⎪⎪⎧β没有,则Follow(w)⊆Follow(A)β有⎩⎪⎨⎪⎧ε∈/First(β),First(β)⊆Follow(A)ε∈First(β)⊆{First(β)⊆Follow(A)Follow(w)⊆Follow(A)
- SLR分析表构造和LR(1)分析表构造:相同点:在 i i i和终结符位置写 s j s_j sj,非终结符位置写 j j j,接受项目写acc。不同点: SLR分析表构造的时候,规约项目用的是Follow(A)的集合,然后在Follow(A), i i i和 b b b(Follow(A) 中的代表元素)的位置写 r j r_j rj(代表第几个产生式),而LR(1)在构造分析表时候,规约项目时侯在 i i i和搜索符的位置写 r j r_j rj
- LR(1)的搜索符计算:核项目的搜索福继承,非核项目的搜索符单独计算,例如: { A → ⋅ B C , c ∣ d B → C D , f i r s t ( C ⋅ ( c ∣ d ) ) \begin{cases} A\rightarrow ·BC,c|d\\ B\rightarrow CD,first(C·(c|d)) \end{cases} {A→⋅BC,c∣dB→CD,first(C⋅(c∣d))
- LALR(1) 把核项目相同的合并。LALR(1)可能会有r-r冲突,但是不会有s-r冲突
- Yacc: − 5 + 10 -5+10 −5+10看成是 − ( 5 + 10 ) -(5+10) −(5+10),还是(-5)+10。答案取后者
四、 语法制导翻译
- 什么是语法制导翻译
a.它包括两种具体形式,语法制导定义和翻译方案
b.语法制导定义:为每一个候选式单独写一个规则
c.翻译方案:把合适的计算规则放到产生式右部合适的位置
(两个合适) - 综合属性和继承属性的计算位置
a.综合属性计算位置:从叶结点到根节点
b.继承属性计算位置: 兄弟节点,父节点,和自己的属性 - SAD和LAD
- 重点
-
五、 静态语义检查
- 类型系统用于类型检查
- 使用标记非终结符提取语义动作时的限制条件
E1 op E2 ,E1和E2 类型比较,类型的转换
六、 中间代码生成
- 中间代码的形式有哪些?//简答5分,凑够5个要点,图形表示里面的两种都写上
a.后缀表示,例: (8-5)+2的后缀表示形式为85-2+
b.图形表示:语法树和有向无环图
c.三地址代码,例:一般形式 x = y op z,例如x+y*z的三地址语句序列是t1 = y * z,t2 = x + t1
d,静态单赋值,例:一种便于某些代码优化的中间表示,和三地址代码的主要区别是所有赋值指令都是对不同名字的变量的赋值 - 后缀表达式的不足
a.后缀表示可以拓广到表示赋值语句和控制语句,但很难用栈来描述控制语句的计算 - 静态单赋值的特点
a.静态单赋值中所有的赋值指令都是对不同的变量赋值
b.它使用一种记号上的约定来区别不同控制流路径应该用哪个变量名。
七、 目标代码生成
- 目标代码的形式有哪些?分别有什么特点?
绝对机器语言程序,可重定位机器语言程序,汇编语言程序
绝对机器语言程序:装入内存的起始地址是固定的;目标程序可以放在内存的固定地方并且 立即执行,因此程序可以被快速的编译和执行
可重定位机器语言程序 :代码装入内存的起始地址可以任意;代码中有一些重定位信息,以适应重定位的要求;允许子程序分别地编译;允许从目标模块中调用其他先前编译好的程序模块
汇编语言程序:免去编译器重复汇编器的工作 - 指令代价与附加代价的关系,计算实例
指 令 代 价 = 1 + 源 地 址 模 式 的 附 加 代 价 + 目 的 地 址 模 式 的 附 加 代 价 范 围 [ 1 , 3 ] \text指令代价=1+源地址模式的附加代价+目的地址模式的附加代价 范围[1,3] 指令代价=1+源地址模式的附加代价+目的地址模式的附加代价范围[1,3]
例 : 指 令 代 价 \text例:指令代价 例:指令代价
M O V R 0 , R 1 1 \text MOV \quad R0,R1 \quad1 MOVR0,R11
M O V R 5 , M 2 \text MOV\quad R5,M \quad2 MOVR5,M2
A D D # 1 , R 3 2 \text ADD\quad \#1,R3 \quad2 ADD#1,R32
S U B 4 ( R 0 ) , ∗ 12 ( R 1 ) 3 \text SUB\quad 4(R0), *12(R1) \quad3 SUB4(R0),∗12(R1)3
只要是寄存器和间接寄存器,代价都是0,其他代价都是1。寄存器是R,间接寄存器是*R
- 重点
-
- 最后一道大题是语法分析题(课本例题和课后习题)