【HUST】网安|编译原理|期末复习概念梳理笔记
纯自用,仅概念无题型,配合课本《编译原理 第4版》(ISBN: 978-7-121-31930-3)理解。
参考文献:刘铭. 编译原理 第4版. 北京:电子工业出版社, 2018.06.
有很多地方我写得很简略,算是自己的思维导图。
书上有一(很)些(多)描述得与一般的编译原理不一样。
【详细复习了1到4章,剩下的没时间复习了就开摆了】
第1章 编译概述
1.1 概念
- 编译程序:将高级语言(源语言)翻译成汇编语言或机器语言之类的低级语言(目标程序)的翻译程序。
是系统软件,不是常用的应用软件。
- 解释程序:不产生目标程序、边解释边执行的一种翻译程序。
- 采用编译方法的程序执行通常可分为编译阶段(、汇编阶段)、运行阶段。
1.2 编译过程的5个阶段
- 词法分析:对构成源程序的字符串从左到右进行扫描和分解,根据语言的词法规则,识别出一个一个具有独立意义的单词。(
词法规则:单词的形成规则,规定了哪些字符串构成一个单词符号。
) - 语法分析:根据语言的语法规则从单词符号串中识别出各种语法单位并进行语法检查。(
语法规则:语法单位的形成规则
;语法检查:检查各种语法单位在语法结构上的正确性。
) - 语义分析及中间代码生成:首先对每一种语法单位进行静态的语义审查,然后分析其含义,并用中间代码或目标语言来描述这种语义。
- 代码优化:对前阶段产生的中间代码进行等价变换或改造,主要包括局部优化和循环优化等。
- 目标代码生成:将中间代码变换成特定机器上的绝对指令代码、可重定位的指令代码或汇编指令代码。
- 2个贯彻整个过程的程序:表格管理程序、出错处理程序。
第2章 文法和语法的基本知识
2.1 描述程序设计语言应考虑的因素
【指非形式化描述
】
- 语法:对语言结构的定义。
- 语义:描述了语言的含义。
- 语用:从使用的角度去描述语言。
2.2 形式语言的基本概念
- 字母表:元素的非空有穷集合,指出了该语言中允许出现的一切字符。
- 字(符号串):符号的有穷序列。
- 空符号串:不包含任何符号的符号串。用ε表示,其长度|ε|为0。规定 任意符号串 0 ^0 0=ε。
- 空集合:不包含任何符号串的集合,用∅或{}表示。规定 集合 0 ^0 0={ε}。
- 集合A的闭包A ∗ ^* ∗比正闭包A + ^+ +多包含一个空符号串。
2.3 对形式语言的描述方法
- 枚举(字面意思)
- 文法:借鉴了递归函数、数学归约的类似思想。
2.3.1 文法
-
概念:是规则的非空有穷集合,通常表示成四元组G=(V N _N N, V T _T T, P, S)。
字汇表V=V N _N N∪ V T _T T∪{ε}。(有说不用∪{ε}的,存在争议)- 规则:又称产生式,通常写作“符号→符号串”(
意为“规则左部 定义为/生成 规则右部”
),作用是告诉我们如何用规则中的符号串生成语言中的序列。
一组规则规定了一个语言的语法结构。符号
:- 非终结符:规则左部的符号。
- 终结符:其他符号。它是组成语言的基本符号,是不可再分的。
- S:一个非终结符,称为文法的开始符号或识别符号。
- 规则:又称产生式,通常写作“符号→符号串”(
-
规定:①第一条规则的左部是识别符号;②描述文法G时只需显式地写出P,不需要写出四元组。
-
性质:对于一个给定的语言,描述该语言的文法不是唯一的。(存在等价文法)
设计的文法不能超出所定义的语言的范围,也不能缩小。 -
已知语言确定文法:分析语言中符号串的结构特征,设计文法。
-
已知文法确定语言:由识别符号出发,推导句子,找出规律,用式子或自然语言描述出来。
- 直接推导:从符号串xAy推导出xαy仅使用一次规则A→α。用“⇒”表示。
- 推导:用“
⇒
+
\overset{+}{\Rightarrow}
⇒+”表示,依据是规则。表示经一次或若干次直接推导,次数称为推导的长度。(
注:推导符号的LaTeX:\overset{+}{\Rightarrow}
) - 广义推导:用“ ⇒ ∗ \overset{*}{\Rightarrow} ⇒∗”表示,长度大于等于0。
- 句型:若S ⇒ ∗ \overset{*}{\Rightarrow} ⇒∗x,x∈(V N _N N∪V T _T T) ∗ ^* ∗。
- 句子:若S ⇒ ∗ \overset{*}{\Rightarrow} ⇒∗x,x∈V T ∗ _T^* T∗。
- 语言:文法G[S]产生的所有句子的集合,记作L(G[S])={x|S
⇒
+
\overset{+}{\Rightarrow}
⇒+x且x∈V
T
∗
_T^*
T∗}。
→ 文法能从结构上唯一地确定语言。
→ L(G)只是V T ∗ _T^* T∗的子集。 - 规范推导:即最右推导,每一步直接推导,都是对符号串最右非终结符进行替换。
- 规范归约:规范推导的逆过程,即最左归约。
2.4 递归
-
规则具有递归性:规则的左部和右部具有相同的非终结符的规则。使我们能用有限的规则定义无穷集合的语言。
- 规则左递归:A→A…
- 规则右递归:A→…A
- 规则递归:A→…A…
-
文法具有递归性:存在 非终结符 ⇒ + \overset{+}{\Rightarrow} ⇒+含非终结符的符号串 的文法。
- 文法左递归:A ⇒ + \overset{+}{\Rightarrow} ⇒+A…
- 文法右递归:A ⇒ + \overset{+}{\Rightarrow} ⇒+…A
- 文法递归:A ⇒ + \overset{+}{\Rightarrow} ⇒+…A…
- 当一个语言是无穷集合时,定义该语言的文法一定是递归的。
2.5 短语
- 概念:若S ⇒ ∗ \overset{*}{\Rightarrow} ⇒∗αAδ且A ⇒ + \overset{+}{\Rightarrow} ⇒+β,则β是相对于非终结符A的句型αβδ的短语。
- 直接短语:S ⇒ ∗ \overset{*}{\Rightarrow} ⇒∗αAδ且A ⇒ {\Rightarrow} ⇒β的β。由于A ⇒ \Rightarrow ⇒β表示有文法规则A→β,故每个直接短语都是某个规则右部。
- 句柄:一个句型的 最左 直接短语。
- 语法树:对句型的推导过程的一种图形表示。其结点用V中的一个符号标记。
- 子树:由某一非末端结点连同所有分支组成的部分。
- 简单子树:只有单层分支的子树。
- 短语:子树的末端结点形成的符号串是相对于子树根的短语。
- 直接短语:简单子树的末端结点形成的符号串是相对于简单子树根的直接短语。
- 句柄:最左简单子树的末端结点形成的符号串。
2.6 文法的二义性
- 概念:存在某个句子对应两棵不同的语法树(或不同的最左(最右)推导)。
- 消除:利用文法的等价性,把排除二义性的规则合并到原有文法中,改写原有的文法。
或添加语法的非形式规定,如运算符的优先顺序和结合顺序。 - 语言的二义性(先天二义性语言):不存在无二义性的文法的语言。
2.7 文法的分类
- 0型:无限制文法。规则左部是至少含一个非终结符的符号串,右部为任意符号串,可为空。
- 1型:上下文有关文法。规则右部不可为空,且形式为αAβ→αuβ。
上面的介绍是华中大版本的,但正常的介绍应该如是:
(1)式子左边可以有多个字符,但必须有一个终结符
(2)式子右边可以有多个字符,可以是终结符,也可以是非终结符,但必须是有限个字符
(3)左边长度必须小于右边(α→ε例外)
否则2型文法将不是1型文法的子集。
- 2型:上下文无关文法。通常定义程序设计语言的文法。A→β,β可为空。
- 3型:正规文法。通常定义词法规则的文法。分为左线性文法和右线性文法,右部可为空。
右线性:A→αB或A→α,A,B∈V N _N N,α∈V T ∗ _T^* T∗。
2.8 实际使用时的限制
- 不能含有有害规则,如A→A。
- 不能含有多条规则,指用不到或推不出任何终结符号串的。
第3章 词法分析与有穷自动机
3.1 词法分析概念
词法分析程序又称词法分析器或扫描器,以字符串形式的源程序作为输入,以单词符号或单词符号表示的源程序作为输出。它通常被设计为语法分析程序的子程序。
3.2 单词符号
- 概念:是具有独立意义的最小语法单位,是程序语言的基本语法单位。
- 分类:关键字、运算符、界符通常是有限的。标识符和常数的个数不确定。标识符一般统归为一种,常数可归为一种,也可以按类型分种类。
- 关键字(又称基本字)
- 标识符
- 常数
- 运算符
- 界符
- 表示形式:二元式(单词种别, 单词自身的值)。其中单词种别是语法分析所需,单词自身的值是其他阶段所需,若一种一个,则不需值。
- 定义方式:正规文法、正规式。正规式所表示的符号串的集合是正规集,这些符号串是正规式可以表示的单词符号。
- 正规式中包含3种运算符号:连接“·”、或“|”、闭包“*”,其中闭包优先级最高,连接符号可略。
- ① L(e 1 _1 1|e 2 _2 2)=L(e 1 _1 1)∪L(e 2 _2 2)
- ② L(e 1 _1 1e 2 _2 2)=L(e 1 _1 1)L(e 2 _2 2)
- ③ L((e 1 _1 1) ∗ ^{*} ∗)=(L(e 1 _1 1)) ∗ ^{*} ∗
- ④规定L(∅)={},L(ε)={ε},L(a i _i i)={a i _i i}。
- 性质:或运算满足交换、结合、分配律,连接运算满足结合律,三个均满足零一律,均左结合。(A ∗ ^{*} ∗) ∗ ^{*} ∗=A ∗ ^{*} ∗,闭包运算满足幂等性。
注:零一律在这指的是同一律+零律,我当时学离散的时候学的就叫做零一律,不同的书对此说法不同。
3.3 正规文法与正规式相互转换
- 正规文法→正规式:
- 将正规文法中每个非终结符表示成关于它的一个正规方程;(其中或运算可用’+'代替)
- 若x=αx+β,则x=α
∗
^{*}
∗β,
若x=xα+β,则x=βα ∗ ^{*} ∗,
- 正规式→正规文法:
- A→ab转换成A→aB和B→b;
- A→a ∗ ^{*} ∗b转换成A→aA|b。
- 应用①②使每条规则最多含有1个终结符为止,可以不去掉空规则。
3.4 有穷自动机
-
用途:可用来识别正规集。分为“确定的”和“非确定的”两类。
-
DFA:五元组M=(Q,∑,f,S,Z)。可由状态转换矩阵(或称转换表或状态转换图)表示。DFA所识别的符号串的全体记为L(M),称为DFA M所识别的语言。(
Q
是状态集,∑
是输入字母表,f
是Q×∑→Q的单值映射,S
∈Q是初态,Z
⊆Q是终态集。所识别
:指存在一条从初态结到终态结的道路。) -
NFA:它的f是多值映射,S是初态集,同一个符号串可由多条路来识别。
-
NFA可以确定化为DFA:①正规式构造NFA;②NFA确定化为DFA;③DFA化简。
- ①从X→Y开始,根据下图所示的规则拓展,保留X、Y为为全图唯一的初态结、终态结。
- ②子集法:
- 构造初态的ε-闭包,得到一个状态集,将它视为一个未标记的状态;
- 取未标记的状态A,求f(A, 任意输入)的ε-闭包作为新的映射f’(A, 输入),将非空集作为新的未标记状态,对A做标记。重复该步骤直至没有状态未标记。
- 用上述步骤涉及的状态和新的映射 作NFA确定化后的状态矩阵。
ε-闭包
:即ε-CLOSURE(I),表示 I 与 I经过任意条ε弧能到达的状态 的并集。- 合并等价状态。等价状态指对于任意输入,这些状态都只能在相互之间转化,不会转化成其他状态。并规定终态集和非终态集不等价。
- ①从X→Y开始,根据下图所示的规则拓展,保留X、Y为为全图唯一的初态结、终态结。
-
有穷自动机转换为正规式:用逆规则即可,其中有差别的规则如下图:
其中右线性文法转有穷自动机,需要新增末态;左线性文法需要新增初态,并将开始符号视为终态。
3.5 词法分析程序的自动生成工具Lex
- {name}引用,"+“表示正闭包,”
∗
*
∗"表示闭包,运行
flex 文件.l
得到lex.yy.c。 - 最长匹配:找到多于一个的匹配项,它会取最长匹配符号串,相等时取排在前面的规则。
第4章 语法分析
4.1 方法分类
-
分类:
- 自上而下分析法:从文法的开始符号出发,正向推导出给定的句子。
- 自下而上分析法:从给定的输入串开始,根据文法规则逐步进行归约,直到归约到开始符号。
-
自上而下分析法:
-
非确定的:穷举。
-
确定的:要求文法是无左递归和无回溯的。
- 消除直接左递归:
A→Aα|β
改成A→βA', A'→αA'|ε
。 - 更一般得消除直接左递归:A→Aα 1 _1 1|Aα 2 _2 2|…|Aα n _n n|β 1 _1 1|β 2 _2 2|…|β n _n n改成A→β 1 _1 1A’|β 2 _2 2A’|…|β n _n nA’, A’→α 1 _1 1A’|α 2 _2 2A’|…|α n _n nA’|ε。
- 接着消除回溯(不是所有都能消除):反复提取公共左因子:A→αβ 1 _1 1|αβ 2 _2 2|…|αβ n _n n改成A→αA’, A’→β 1 _1 1|β 2 _2 2|…|β n _n n。
简单的公共左因子不存在的判断方法:当且仅当对G中每个非终结符A的任何两个不同规则A→α|β满足SELECT(A→α)∩SELECT(A→β)=∅。
- 消除直接左递归:
-
FIRST(α)={a|α ⇒ ∗ \overset{*}{\Rightarrow} ⇒∗a…且a∈V T _T T}。若有规则α→a i ^i i个连续非终结符,且这些非终结符可以推导出ε,则这些非终结符的FIRST的非ε元素需加到FIRST(x)中。
-
FOLLOW(A)={a|S ⇒ ∗ \overset{*}{\Rightarrow} ⇒∗…Aa…且a∈V T _T T}。若有S ⇒ ∗ \overset{*}{\Rightarrow} ⇒∗…A,则规定
$
∈FOLLOW(A)。
为方便求解FOLLOW集合,有如下简便的规则:- 文法的开始符号S,
$
∈FOLLOW(S)。☆ - 若A→αBβ,则FIRST(β){ε}⊆FOLLOW(B)。
- 若A→αB或A→αBβ且β ⇒ ∗ \overset{*}{\Rightarrow} ⇒∗ε,则FOLLOW(A)⊆FOLLOW(B)。
- 文法的开始符号S,
-
SELECT(A→α)=FIRST(α),若α ⇏ ∗ \overset{*}{\nRightarrow} ⇏∗ε
SELECT(A→α)=FIRST(α){ε}∪FOLLOW(A),若α ⇒ ∗ \overset{*}{\Rightarrow} ⇒∗ε
⇏ ∗ \overset{*}{\nRightarrow} ⇏∗的LateX代码是
\overset{*}{\nRightarrow}
。 -
4.3 确定的自上而下分析法
- 递归下降分析法:一种确定的自上而下分析法,为文法中每个非终结符编写一个函数,去识别由该终结符所表示的语法成分。
- 预测分析法:另一种确定的自上而下分析法。又称LL(1)分析法。
- 预测分析器:由预测分析表(又称LL(1)分析表)、先进后出分析栈、总控程序组成。
- 构造预测分析表的规则:
- 计算文法的每一非终结符的FIRST集和FOLLOW集;
- 对文法的每个规则A→α,若a∈FIRST(α),置M[A,a]=A→α。
- 若ε∈FIRST(α),对任何b∈FOLLOW(A),置M[A,b]=A→α。
- 结合分析栈分析。分析时需考虑分析栈内容(默认右边是栈顶,规则右部倒着进栈)、输入串、所用规则。
- 总控程序根据栈顶符号和当前输入符号a来决定分析器的动作。
- 构造预测分析表的规则:
- LL(1)文法的分析表不会含多重定义元素。
- 预测分析器:由预测分析表(又称LL(1)分析表)、先进后出分析栈、总控程序组成。
4.4 自下而上分析法
-
原理:以“移进-归约”为原理,若栈中最后剩下右界符
$
和文法的开始符号,则分析成功,否则不是文法的句子。关键问题是如何定义可归约串。 -
算符优先分析法(又称OPG文法):借助优先关系矩阵寻找句型的可归约串。
- 算符优先文法:没有形如U→…VW…的规则。(非终结符不能相邻)
- 构造优先关系表:
-
计算每一非终结符的FIRSTVT集和LASTVT集。
FIRSTVT:最左端终结符及第二个终结符的集合。
LASTVT:最右端终结符及第二个终结符的集合。 -
逐条扫描文法规则。
- 若有αA,则α ⋖ \lessdot ⋖ FIRSTVT(A)。(横填)
- 若有Aα,则LASTVT(A) ⋗ \gtrdot ⋗ α。(竖填)
- 且
$
⋅ ‾ ‾ \overline{\underline{·}} ⋅$
,$
⋖ \lessdot ⋖ FIRSTVT(S), LASTVT(S) ⋗ \gtrdot ⋗$
。
⋖ \lessdot ⋖, ⋗ \gtrdot ⋗的LateX符号分别是:
\lessdot, \gtrdot
,参考LATEX Mathematical Symbols。
等于符号在华科的书上是两条横线中间一个点,没有对应的符号,用\overline{\underline{·}}
替代。
但同学(化名柑橘)说相同含义的符号在WiKi是\doteq
,即 ≐ \doteq ≐。 -
比较栈的最左素短语和当前输入符号的优先关系, ⋖ \lessdot ⋖移进, ⋗ \gtrdot ⋗归约, ⋅ ‾ ‾ \overline{\underline{·}} ⋅结束。栈初始为
$
。(素短语
:至少包含一个终结符的短语,且不含其他素短语。)
-
- 局限性:跳过了所有 产生式的右部只含有单个非终结符的产生式 之间的归约,可能导致把本来不是句子的输入串误认为是文法句子。
- 构造优先关系表:
- 算符优先文法:没有形如U→…VW…的规则。(非终结符不能相邻)
-
LR分析法:一种自下而上进行规范归约的语法分析方法,L指从左到右扫描,R是构造最右推导的逆过程。手工构造LR分析器的工作量相当大,“YACC”可自动构造LALR(1)语法分析器。规范归约分析法以句柄作为可归约串。
LR分析器由分析表、分析栈、总控程序组成。- 分析栈:需要存放历史和展望信息,这些都被抽象成状态。
- 分析表:包含4种可能的动作:移进S、归约r、接受acc、报错(空白)。由分析动作(ACTION)和状态转换(GOTO)两部分组成。
- 基本构造思想:构造识别文法所有规范句型活前缀的DFA,再将DFA转换成LR分析表。
- 活前缀:规范句型的前缀,不包含句柄右边的任何符号。(
规范句型:规范推导能推出来的句型。
) - 活前缀和句柄的关系:以•为当前输入串。①若有规则A→α•,说明可以归约;②有规则A→α
1
_1
1•α
2
_2
2,说明还要等α
2
_2
2出现,所以移进(α
1
_1
1可以为空)。所以对规则A→ε只有项目A→•。
其中②A→α 1 _1 1•α 2 _2 2,又可分为移进项目(A→α•aβ,期待a)和待约项目(A→α•Bβ,期待有什么能归约成B)。
①A→α•,又可分为归约项目(A→α•,就是一般的归约)和接受项目(S’→S•,acc)。 - LR(0)构造DFA的方法:
① 先拓展文法,加一条S’→S,并对所有规则编号。
② 从S’→•S开始构造CLOSURE({S’→•S})。(CLOSURE:指在当前输入串下,所有可能的相同状态的规则。比如S'→•S与S→•a是相同状态。即,若A→α•Bβ属于CLOSURE,那B→•r也属于。
)
③ 求状态转移GO,某状态接受某一文法符号作为输入后还剩的规则作为新的状态。
④ 直到所有状态的GO都求完了,或是句柄识别态了。(句柄识别态:只含归约项目。
)
这些状态称为这个文法的LR(0)项目集规范族。 - LR(0)分析表:不需要向前查看输入符号,只要有句柄就归约,不能解决又有归约又有移进的。
① 归约项目的ACTION填r 规则号 _{规则号} 规则号,(全部填);
② 移进项目的ACTION填S 状态号 _{状态号} 状态号,(跳转的那一个)
③ 待约项目的下一个是非终结符,填GO的状态号。
④ 接受项目的$ACTION填acc。 - SLR(1):简单的LR分析法,对含有冲突的项目集向前查看一个输入符号,解决冲突。(DFA与LR(0)画法一致)
- SLR(1)分析表:归约项目只有当那个属于被归约的文法符号的FOLLOW集才填。
- 局限:并不是FOLLOW集的每个元素都会出现在被归约项后面。(因为可能前面的字符串不一致)
- LR(1)的DFA:它不仅需要记录规则项目,还要向前扫视一个符号(搜索符)并记录它。若项目[A→α•Bβ, a]属于CLOSURE(I),B→r是文法的一条规则,b∈FIRST(β,a),则[B→•r, b]也属于CLOSURE(I)。【让α更有意义了,排除无效归约】
- LALR(1):将LR(1)同心项目集合并,搜索符取并集。
合并后只需要看有无“归约-归约”冲突,不可能有“移进-归约”冲突。因为I j _j j中 a 1 ∩ a = ∅ , a 2 ∩ a = ∅ {a_1}∩{a}=∅, {a_2}∩{a}=∅ a1∩a=∅,a2∩a=∅,在I k , j _{k,j} k,j中 ( a 1 ∪ a 2 ) ∩ a = ∅ ({a_1}∪{a_2})∩{a}=∅ (a1∪a2)∩a=∅。
- 活前缀:规范句型的前缀,不包含句柄右边的任何符号。(
-
LR类文法绝不是二义性文法。
-
错误恢复:① 跳过大量输入;② 符号串替换;③ 出错产生式;④ 全局纠正,只改尽可能少的。
-
YACC&Bison:“移进-归约”冲突默认移进。Flex&Bison是Lex&YACC的升级版。
第7章 代码优化
7.1 代码优化方法
- 删除公共子表达式(指计算结果相同的)。
- 代码外提(将循环中的不变运算提到循环体前面)。
- 强度削弱(将执行时间长的运算替换成执行时间短的)。
- 删除归纳变量(用循环体内另外的变量取代控制变量控制循环的次数)。
- 合并已知量(指常数或在编译时就能确定其值的变量参与运算)。
- 复写传播(值相同的语句右边都用同一个变量表示)。
- 删除无用赋值(在任何地方都不引用的值)。
7.2 局部优化
- 概念:应用于代码的线性部分优化。(
线性部分:代码中没有转入或转出语句,最大的线性代码序列是基本块。
) - 划分基本块:准确定义入口、出口语句。
- 删去不属于任何基本块的语句。
- 一般可进行 合并已知量、删除无用赋值、删除多余运算。
- 作出DAG图(有向、无环),(过程中注意合并结点),再用DAG图写出四元式,如果还要优化再进一步优化。
第5章 语法制导翻译技术和中间代码生成
- 输入:语法单位(边分析语法单位边做语义分析与处理)。
- 属性文法:在上下文无关文法的基础上,允许每个文法符号X根据处理的需要,定义与X相关联的属性。处理过程需遵循语义规则。
- 属性的断言就是与属性有关的语义规则。
- 属性分类:
- 综合属性:用于“自下而上”传递信息。
- 继承属性:用于“自上而下”传递信息。
- 中间语言便于编译后期代码优化,可使编译程序的结构在逻辑上更简单明确。
- 语法制导翻译并非一种形式系统,但它比较接近形式化。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)