编译原理知识汇总

编译原理

引论

编译程序

在计算机上执行一个高级语言程序一般要分为两步:第一步,用一个编译程序把高级语言翻译成机器语言程序; 第二步,运行所得的机器语言程序求得计算结果。

编译程序 : 通常所说的翻译程序是指这样的一个程序,它能够把某一种语言程序(称为源语言程序)转换另一种语言程序(称为目标语言程序),而后者与前者在逻辑上是等价的

如果源语言是诸如FORTRAN、Pascal、 C、Ada、 Smalltalk或Java这样的“高级语言",而目标语言是诸如汇编语言或机器语言之类的“低级语言”,这样的一个翻译程序就称为编译程序。

解释程序 : 一个源语言的解释程序是这样的程序,它以该语言写的源程序作为输入,但不产生目标程序,而是边解释边执行源程序本身。实际上,许多编译程序的构造与实现技术同样适用于解释程序。

编译过程

编译程序的工作过程一般主要划分为词法分析,语法分析,中间代码生成,代码优化,目标代码生成等几个基本阶段,同时还会伴有表格处理出错处理

如果编译程序生成的目标程序是机器代码程序,则源程序的执行分为两个阶段:编译阶段运行阶段。如果编译程序生成的目标程序是汇编语言的程序,则源程序的执行分为三个阶段:编译阶段汇编阶段运行阶段

编译程序的结构

请添加图片描述

高级语言及其语法描述

文法和语言

  • 语法是一组规则,可用来产生合乎语法的程序,也可用来分析一个程序是否合乎语法。

  • 程序设计语言的语义包括静态语义动态语义

    • 静态语义是一系列限定规则,用来确定哪些合乎语法的程序是正确的;
    • 动态语义称为运行语义或执行语义,表示程序要做什么,要计算什么。

文法的概念 : 描述语言的语法结构的形式规则

  • 文法是阐述语法的一个工具
  1. 字母表-符号集:是字母的有穷非空集合。

  2. 符号串—字母表的符号组成的任何有穷序列。

  3. 空符号串:用ε表示,长度为0(不含任何符号)

  4. 符号串的连接:

    设x,y是符号串,连接 x y xy xy是y符号写在x符号之后。

    例:x=ab, y=MN 则 x y = a b M N xy=abMN xy=abMN

  5. 符号串的方幂:

    设x是符号串,则z=xx……xx,称z为x的方幂,

    z = x n z=x^n z=xn

    因此$ x^0=ε, x^1=x, x^2=xx, x^3=xxx $

    显然n>0时, 有 x n = x ⋅ x n − 1 = x n − 1 ⋅ x x^n =x·x^{n-1} = x ^{n-1}·x xn=xxn1xn1x

  6. 符号串的集合:

    ​ 若集合A中的一切元素都是某字母表上的符号串,则称A为该字母表上的符号串集合。

    ​ 两个符号串集合A、B乘积定义:

    A B = { x y ∣ x ∈ A 且 y ∈ b } AB=\{xy| x∈A且y∈b\} AB={xyxAyb}

    例:A={a,b},B={c,d}

    A B = { a c , a d , b c , b d } AB= \{ac,ad,bc,bd\} AB={acadbcbd}

  7. 闭包( ∑ ∗ ∑^*

    字母表 ∑ ∑ ,用 ∑ ∗ ∑^* 表示 ∑ ∑ 上所有有穷长的串集合, ∑ ∗ ∑^* 称为 ∑ ∑ 的闭包。

    例:字母表∑={0,1}

    ∑ ∗ = { ε , 0 , 1 , 00 , 01 , 10 , 11 , 000 , 001 , 010 … … } ∑^*=\{ε,0,1,00,01,10,11,000,001,010……\} ={ε,0,1,00,01,10,11,000,001,010}

    = ∑ 0 ∪ ∑ 1 ∪ ∑ 2 ∪ . … ∪ ∑ n =∑^0∪∑^1 ∪ ∑^2∪. …∪∑^n =012.n

  8. 正闭包(∑+)

    ∑ + = ∑ 1 ∪ ∑ 2 ∪ . … ∪ ∑ n ∑^+ =∑^1 ∪ ∑^2∪. …∪∑^n +=12.n

    ∑ + ∑^+ + ∑ ∑ 的正闭包。

    显然: ∑ ∗ = ∑ 0 ∪ ∑ + ∑^*= ∑^0∪∑^+ 0+

    ∑ + = ∑ ∑ ∗ = ∑ ∗ ∑ ∑^+ = ∑∑^*=∑^*∑ +

文法和语言的形式定义

  1. 产生式(规则、重写规则、生成式)

    形如 α → β \alpha \rightarrow \beta αβ ( → \rightarrow 的叫法:“定义为”)

    a 称规则的左部,β称规则的右部。

    注意: → \rightarrow : 表示"定义为" ; 而 ⇒ \Rightarrow : 表示"推导" , 用于语法分析中。

  2. 文法定义 : 描述语言语法结构的形式规则

    文法G 定义为四元组 ( V N , V T , P , S ) (V_N, V_T, P, S) (VN,VT,P,S)

V N V_N VN:非终结符号集(一般用< > 或大写字母表示)

V T V_T VT :终结符号集 ,不能分割,即单词符号

P P P :产生式(规则)

S S S :开始符号或称作识别符号,它是一个非终结符,至少要在一条规则中作为左部出现。

​ 规定:(1) V N , V T , P V_N ,V_T,P VNVTP是有穷非空集合;

​    (2) V N ∩ V T = ∅ V_N∩V_T=\emptyset VNVT (不含公共元素)

注意 :一般希腊字符代表”全世界“,即既可以代表终结符也可以代表非终结符, 它可以代表任意符号或符号串 。

  1. 直接推导的定义

    α → β \alpha \rightarrow \beta αβ 是文法 G = ( V N , V T , P , S ) G=(V_N ,V_T ,P,S) G=VNVTPS的规则,

    γ \gamma γ δ \delta δ V ∗ V^* V中的任意符号,若有符号串 V , W V,W VW满足:

    V = γ α δ V= \gamma \alpha \delta V=γαδ W = γ β δ W=\gamma \beta \delta Wγβδ 则说V是直接产生WW是V的直接推导W直接规约到V, 记作 V ⇒ W V \Rightarrow W VW

​ 若存在直接推导的序列:

​    V = W 0 ⇒ W 1 ⇒ W 2 ⇒ … W n = W ( n > 0 ) V=W_0 \Rightarrow W_1 \Rightarrow W_2 \Rightarrow … W_n =W (n>0) V=W0W1W2WnW(n>0)

​ 则称V推导W (或W规约到V) ,记 V ⇒ + \stackrel{+}{\Rightarrow} +W (一步或若干步推导)

​ 若有V ⇒ + \stackrel{+}{\Rightarrow} +W ,或 V = W ,则记作 V ⇒ ∗ \stackrel{*}{\Rightarrow} W ( 零步或若干步推导)

  1. 句型的定义

    假定G是一个文法, S为开始符号, 如果 S ⇒ ∗ α S \stackrel{*}{\Rightarrow} \alpha Sα 则称 α \alpha α是一个句型。 仅含终结符号的句型是一个句子。

句子一定是句型,句型不一定是句子


  • 状态转换图的功能:识别(接受)一定的符号串(单词)

  • 状态转换图的程序实现的思路:为每个状态结点都编写一个子程序

  • 字母表的概念:一般用∑表示

  • 闭包的概念:闭包V*中的每个字都是由V中的字经过若干次连接而成的

  • 正则闭包V+的概念:是V上所有符号串的集合

  • ∑ ∗ ∑^* (闭包)定义:表示 ∑ ∑ 上所有字的全体,空字ε也包括在其中

  • ∑ + ∑^+ + : (正闭包)空字ε不包含,非ε

  • ε,{ },{ε}之间的区别

  • ε所对应的正规集为{ε}

  • 正规式与正规集的定义:知道如何用正规式表示一个正规集

  • 简述 N F A NFA NFA D F A DFA DFA的定义与区别

  • 若M的某些结点既是初态结点又是终态结点,或者存在一条从某初态结点到某个终态结点的ε通路,那么空字ε可为M所识别

  • 正规式与优先自动机的等价性

  • 定理2.对于∑上的每一个正规式V,存在一个∑上的DFA M,使得L(M)=L(V)

  • D F A DFA DFA M的化简的概念和方法:终态和非终态是可区别的,因为终态可以读出空字ε,而非终态不能读出空字ε

  • 构造一个 D F A DFA DFA,它接受∑={x,y}上所有倒数第二个字符为y的字符串


词法分析

1.状态转换图的功能: 识别(接受)一定的符号串(单词)

请添加图片描述

上图是一个很简单的状态转换图。上图代表:状态0通过X弧可以转换到状态1,通过Y弧可以转换到状态2

2.字母表的概念:一个由有限元素组成的集合,每个元素称为一个符号或一个字,一般用∑表示一个字母表

例: ∑ = {a , b , c}

​ 元素:a,b,c

字母表中的字可拼接在一起构成一个序列,如aa,ab,bc,bbc等,符号的顺序不同所代表的序列也不同。

不包含任何字符的序列称为空字,用ε来表示

另外有几个概念必须先了解:

字(符号串)的连接

设x和y是两个字(符号串),则定义xy为他们的连接

例:ab和ba连接是abba

注: (1) ε(空字)是连结运算的恒等元素εx = xε= x

​ (2)字(符号串)的n次连接

x n = x x x … x x^n = xxx…x xn=xxxx

​ 规定 x 0 = ε x^0 = ε x0=ε

x 1 = x , x 2 = x x , x 3 = x x x x^1= x,x^2=xx,x^3= xxx x1=xx2=xxx3=xxx

集合的(连接)积

设U和V是两个“字(符号串)的集合,

则定义UV为他们的(连接)积

​ UV={xy|x∈U且y∈V}

例:设U={a, ab}, V={b, ba},

U V = { a b , a b a , a b b , a b b a } UV=\{ab, aba, abb, abba\} UV={ab,aba,abb,abba}

集合V的n次(连接)积记为:

V n = V V V … V V^n = V V V…V Vn=VVVV

​ n个 V

​ 规定 V 0 = { ε } V^0= \{ε\} V0={ε}

例:设V={a, b},那么

V 0 = { ε } V^0= \{ε\} V0={ε}

V 1 = { a , b } V^1= \{a,b\} V1={a,b}

V 2 = V V = { a a , a b , b a , b b } V^2=VV=\{aa,ab,ba,bb\} V2=VV={aa,ab,ba,bb}

V 3 = V V V = V 2 V = { a a a , a b a , b a a , b b a , a a b , a b b , b a b , b b b } V^3=VVV=V^{2}V=\{aaa,aba,baa,bba,aab,abb,bab,bbb\} V3=VVV=V2V={aaa,aba,baa,bba,aab,abb,bab,bbb}

  1. 闭包的概念

设V是一个字(符号串)的集合,

则V的闭包定义为V*,

​ V* = V 0 ∪ V 1 ∪ V 2 ∪ … V^0∪V^1∪V^2∪… V0V1V2

注:闭包V* 中的每个字都是由V中的字经过有限次连接而成的

正则闭包 V + V^+ V+的定义为

V + = V V ∗ V^+ = VV^* V+=VV

闭包与正则闭包的差别在于,闭包里是含有ε的,因为闭包里有集合 V 0 V^0 V0,而正则闭包由于在闭包的基础上又连接了一个V,所以正则闭包里是没有空字ε的。

∑ ∗ ∑^* 定义:表示 ∑ ∑ 上所有字的全体,空字ε也包括在其中

∑ + ∑^+ +表示 ∑ ∑ ​上所有字的全体,但不包括ε

  1. ε,{ },{ε}之间的区别

ε 空字:表不包含任示何字符的序列称

{ }:表示一个空集

{ε}: 表示含有空字ε的集合

5.正规式与正规集的定义:

我们可以把具有相同特征的字放在一起组成一个集合,即所谓的正规集;然后使用一种形式化的方法来表示正规集,即所谓的正规式。

  • 正规式是描述单词结构的一种形式;
  • 正规集是该类单词的全集。

举例

对于下面的例子,应该好好思考一下后面4个的含义,对做大题是很有帮助的。做大题时,题目通常会给你一个实际问题,你需要先把他要实现的功能抽象成一个正规集,再用正规式表达出来,才能继续做后面的步骤。

请添加图片描述

ε所对应的正规集为{ε}

6.简述有限自动机NFA和DFA的定义与区别

  • NFA代表非确定的有限自动机;DFA代表确定的有限自动机

  • 所谓的有限自动机,其实他并不代表任何实体的机器,只是一种数学模型而已。就像函数、数列是一种数学模型一样。函数通过函数表达式实现他的功能:你给他一个自变量,他能根据表达式求出因变量的值。而有限自动机是通过状态转换图来实现功能,你给他一个初始状态和一个输入符号,他能根据你输入的这个符号将原状态转换到另一个状态,用他来模拟计算机的识别功能。

下面简单介绍一下DFA(确定的有限自动机)的五元式表示法:(重要)

定义:一个确定有限自动机(DFA) M M M是一个五元式:

M = ( S , ∑ , f , S 0 , F ) M = (S, ∑, f, S_0, F) M=(S,,f,S0,F)​,其中

  1. S是一个有限的状态集合,它的每个元素我们称为一个状态

  2. ∑是一个有穷的输入符号的字母表,它的每个元素我们称为一个输入字符

  3. f f f是从 S × ∑ → S S×∑ →S S×S的单值部分映射

  4. S 0 S_0 S0 S S S的一个元素,为初始状态,它是唯一的

  5. 状态集合 F F F是终止状态的集合,它是 S S S的子集(可空)

一个非确定有限自动机(NFA)

M M M是一个五元式 : M = ( S , ∑ , f , S 0 , F ) M = (S, ∑, f, S_0, F) M=(S,,f,S0,F),其中

S S S是一个有限的状态集合,它的每个元素我们称为一个状态

⑵∑是一个有限的输入符号的字母表,它的每个元素我们称为一个输入字符

f f f是从 S × ∑ ∗ → 2 S S×∑^*→2S S×2S 的部分映射,其中, 2 S 2S 2S表示 S S S的幂集合(所有 S S S的子集组成的集合)( f f f是非单值的M是非确定)

⑷状态集合 S 0 S_0 S0是初始状态集合,它是 S S S的子集

⑸状态集合 F F F是终止状态的集合,它是 S S S​的子集

注:DFA和NFA的区别在于(3)和(4),其他几点都差不多,要记住他们的区别和联系

  1. DFA的识别功能

对于∑*中任何字α,如果存在一条从初态结点到某个终态结点的道路,这条路上所有的标识符连成的字等于α ,则α可被DFA M所识别(接受,读出)

若M的某些结点既是初态结点又是终态结点,或者存在一条从某初态结点到某个终态结点的ε通路,那么空字ε可为M所识别

8.状态转换图的分裂规则(大题步骤)

请添加图片描述

例子:(这里Y有两个圈圈代表他是最终状态的点)

请添加图片描述
请添加图片描述

请添加图片描述
请添加图片描述

划到最后要求每条弧上都只有一个字母或者数字

  1. ε _ C L O S U R E ( I ) ε\_CLOSURE(I) ε_CLOSURE(I)​​​ 和 I a = ε _ C L O S U R E ( J ) I_a =ε\_CLOSURE(J) Ia=ε_CLOSURE(J)​​的构造方法(大题步骤)

这里先需要了解几个定义

我们假设有某个状态集I,这个集合中含有不同的状态。

定义1 状态集I的a弧转换:

  • m o v e ( I , a ) move( I, a ) move(I,a) 是一个状态集,是从 I I I中的状态出发经过一条 a a a弧到达的状态的全体。

定义2 状态集I的ε(空字)闭包:

  • ε _ C L O S U R E ( I ) ε\_CLOSURE(I) ε_CLOSURE(I)是一个状态集,由两部分组成:
    • 状态集 I I I中的所有原状态。
    • I I I中的状态出发经过任意条ε弧,所能到达的状态的全体。

定义3 I a = ε _ C L O S U R E ( m o v e ( I , a ) ) I_a =ε\_CLOSURE( move( I, a ) ) Ia=ε_CLOSURE(move(I,a))是一个状态集。

下面给出一个实例:

例:有如下一个状态转换图假定 I={1, 2},求Ia = ?

请添加图片描述

J=move(I,a)={5,4,3}

I a = ε _ C L O S U R E ( J ) = { 5 , 4 , 3 , 6 , 2 , 7 , 8 } I_a=ε\_CLOSURE(J) = \{5,4,3,6,2,7,8\} Ia=ε_CLOSURE(J)={5,4,3,6,2,7,8}

(即先做a弧转换,将求得的状态再求空字闭包)


10.如何用子集法将非确定的有限自动机确定化(大题步骤)

方法:先画一张表

IIaIb
ε _ C L O S U R E ( S 0 ) ε\_CLOSURE(S_0) ε_CLOSURE(S0) ABC
BDE
CFG

1.这张表的首行上首列上固定是大写字母 I I I

2.表格后面有几列,取决于这个有限自动机的输入符号数量,有几个输入符号就有几列,这里假设 I a I b I_a I_b IaIb 的下标a b代表这个有限自动机的输入符号

3.第二行的第一列也是固定的, S 0 S_0 S0代表的是这个有限自动机的初始状态,即求 S 0 S_0 S0的空字闭包,我们假设求出来的状态集合是A

4.将A所对应的 I a I b I_a I_b IaIb 分别求出来,我们假设是B和C

5.如果B和C都分别于A不同,需要将B,C作为新的状态集合加入到第一列中

6.继续求出B和C所对应的 I a I b I_a I_b IaIb ,再检验:对于DEFG这四个状态集合,有没有与ABC是不同的,如果有,加入到第一列的下面,再继续计算,如果与前面的ABC相同就不再需要加入了。

7.按照这样的方法一直进行下去,知道第一列不再有新的状态集合加入了,这个表就构造好了。

8.再画一张表,与上面的表相对应

Sab
0
1
2
3
4
1
3
4
2

2
4
3
1

9.对于上面这种表的构造方法很简单,大家也可以不另外画表,而直接标在原来的表中

这种表来源是,在原来表的第一列上分别表上s01234···,a和b不变,然后按照第一列中数字所对应的状态集,依次对应在后面的列上标上相应数字。例如第一列中B对应1,C对应2,那么将第二列第二行中的B也标上1,第三列第二行中的C标上2,等等。

10.画出下面的这个表或在原表中标好后,就可以按照这个表画出状态转换图了,例如,0状态通过a弧转换成1状态,通过b弧转换成2状态;1状态通过a弧转换成3状态,通过b弧转换成4状态,等等。画出这个状态转换图后,就完成了一个非确定有限自动机的确定化。

11.有限自动机DFA的化简

整体的思路如下:

​ 1.将第10步中得到的已经确定的DFA中的所有状态分为两组,一组为终态节点,一组为非终态节点。需要补充的是,在上一步构造的表格中,s那一列的节点哪些是终态哪些是非终态呢?这需要看你最初构造的正规式中的哪个是终态节点了。例如在下面的12中,Y为终态节点,那么在以上的表格中只要是含有Y元素的状态集合都将成为终态集。

2.将每个分组检验,看他们是否还能分割,检验的方法实在难以用文字描述清楚,请大家看下面的实际例题,自己领会。

3.每个分组都不能再分割后,若还含有大于2个元素的分组,则这个分组中的所有状态都是等价的,可以用其中的一个代替他们,代替的方法是:假设用状态1代替状态2,则把状态2及其引出去的弧全部删去,并把原来指向状态2的弧指向状态1

例:请添加图片描述
请添加图片描述

请添加图片描述

12.

例题:构造一个DFA,它接受∑={x,y}上所有倒数第二个字符为y的字符串

上面这道题的分析思路是

1.根据他所描述的功能,构造出一个正规式,正规式先给大家:(x|y)*y (x|y)

2.构造一个初始状态X和和最终状态Y,将正规式写在他们的转换弧上。

请添加图片描述

3.按照第8点中的分裂规则对他进行分裂,分裂直到每一条转换弧上都只含有一个字符

4.分裂结束得到的一个状态转换图实际上就是一个NFA(非确定的有限自动机)

5.在掌握了第9点知识的前提下,就可以按照第10点说的步骤,将求得的NFA确定化

6.得到确定化之后的状态转换图,剩下的事情就是化简了。也就是第11点当中的只是


语法分析

(1)基本定义

  1. 上下文无关文法的定义

  2. 句型、句子的概念

  3. 文法和语言的对应关系,给出文法构造语言,文法G产生的句子的全体是该文法的语言

  4. 语法分析树与二义性:判断文法的二义性方法:如果一个文法含有二义性的句子(对应两棵不同的语法树),则称该文法是二义性文法

  5. 3型文法是正规文法、正则文法、线性文法

  6. 2型文法也称为称为上下文无关文法

  7. 若一个文法是递归的,则由它产生的语言的句子个数是无限的

(2)自上而下

  1. 文法左递归的定义

  2. 消除文法的左递归的方法:直接左递归

  3. 消除回溯的方法:提取公共左因子

  4. 递归下降分析法的概念,应满足什么条件?

  5. 递归下降法对文法的每个非终结符构造一个相应的子程序

  6. 预测分析法:给文法构造预测分析表:消除左递归、消除回溯、First集、Follow集。举例子时,便成S→a|aS|(T)

(3)自下而上

  1. 短语、直接短语的概念

  2. 句柄的概念(一个句型的最左直接短语)

  3. 规范归约(最左)、规范推导(最右)、规范句型

  4. 规范归约的关键问题是寻找句柄

  5. 在规范归约中,可归约串必出现在栈顶

  6. 算符文法、算符优先文法的概念,如何判断

  7. 构造算符优先关系表、Fisrtvt、lastvt集合,可不考虑#号

  8. 素短语:算符优先归约的关键问题是寻找最左素短语

  9. 算符优先法尤其适用于表达式的分析

  10. 给出文法G(P)

   X → jYj

  ​ Y → kZ | i

  Z → Yid

  ​ 该文法是否为算符优先文法?请根据FIRSTVT、LASTVT集合构造算符优先关系表说明之?

  1. 欲构造行之有效的自上而下分析器,则必须消除文法中含有的左递归

  2. LR分析法属于自底向上分析方法

  3. 从文法出发构造LR(0)分析表的步骤


1)基本定义

  1. 上下文无关文法的定义

文法:是描述语言的语法结构的形式规则(或称语法规则)

上下文无关文法概念:

它所定义的语法范畴(或语法单位)是完全独立于这种范畴可能出现的环境的(与它所在的上下文无关)

上下文无关文法G可定义为一个四元式 ( V T , V N , S , P ) (V_T,V_N,S,P) (VTVNSP)

V T V_T VT是终结符号集合,它的每个元素称为终结符号,用小写字母表示。

V N V_N VN是非终结符号集合,它的每个元素称为非终结符号,用大写字母表示。

S S S是一个开始符号,是一个非终结符,至少在一个产生式作为左部出现

P P P是一个产生式的集合,它的每个元素称为一条产生式,可以表示为: P → α ∣ b P→α| b Pαb,其中P 是非终结符,叫做产生式的左部,α和b分别叫做这个产生式的一个侯选式,他们既可以是终结符,也可以是非终结符,也可以是他们的组合。

  1. 句型、句子的概念(小题)

设G是一个文法,S是它的开始符号,如果S ⇒ ∗ \stackrel{*}{\Rightarrow} ​α,且 α ∈ ( V N ∪ V T ) ∗ α∈(V_N∪V_T) ^* α(VNVT)​ 则称α是G的一个句型;如果S ⇒ + \stackrel{+}{\Rightarrow} +​α,且 α ∈ V T ∗ α∈ V_{T} ^{*} αVT​ ,则称α是G的一个句子;句子实际上是仅含有终结符号的句型

  1. 文法和语言的对应关系:

一个文法G所产生的句子的全体就是一个语言。给定一个文法,就能从结构上唯一确定其语言;给定一种语言,能找到其文法,但该文法不是唯一的

  1. 语法分析树与二义性:

用一棵树来表示句型的推导,简称语法树。若一个文法的一个句子对应两棵不同的语法树,则称该句子是二义性句子如果一个文法含有二义性的句子,则称该文法是二义性文法。

  1. 3型文法是正规文法、正则文法、线性文法(用于词法分析)

  2. 2型文法也称为上下文无关文法(用于语法分析)

  3. 1型文法也称为上下文有关文法

若一个文法是递归的,则由它产生的语言的句子个数是无限的

(2)自上而下

8. 文法左递归的定义

一个文法中如果存在某个产生式 P→Pα(即有某个侯选式的最左边的符号是这个产生式左部非终结符本身),则此文法是有左递归的。

9. 消除文法的左递归的方法

只要求消除直接左递归,方法见下面的例子。

设有产生式 P→Pα|β

其中β不以P开头,α不为ε,那么,我们可以把P的规则改为如下的非直接左递归形式:

​ P→βP’

​ P’→αP’|ε

这样就消除了P→Pα|β这个式子的左递归。

(提示:在做题时,要把整个文法的每个产生式都逐一检验,有时含有左递归的产生式是不只一个的,需要逐个消除。)

  1. First集合Follow集的构造方法(较抽象)

First集的构造方法:

对于任意一个符号X,构造他的frist集的方法是:

​ (1)若X∈VT (终结符),则FIRST(X)={X}.

​ (2)若X∈VN(非终结符),且有产生式X→a…(小写a代表任意一个终结符号,他是侯选式左边的第一个字符),则把a加入到FIRST(X)中;若X→ε也是一条产生式,则把ε也加到FIRST(X)中。

​ 若有产生式X→Y…(大写Y代表任意一个非终结符号,他是侯选式左边的第一个字符),则把FIRST(Y)中所有非ε元素都加到FIRST(X)中;

FOLLOW集的构造方法:(书上的表述很难懂,大白话表述)

(1)对于文法中给定的开始符号S,置#与FOLLOW(S)中;

(2)将所有产生式侯选式中的非终结符都标出来,并从前往后挨个检查

为方便讨论,我们假设A→αBC是一个产生式,(这里B和C代表非终结符,α代表终结符)

1.先检验这个非终结符的右边还有没有别的符号(不管这个符号是终结符还是非终结符),在这,B是我们检查的第一个非终结符,它右边是有符号C的,

如果检验到的某个非终结符右边有别的符号,例如这里的B,那么检验他右边符号的FIRST集合,这里是FIRST(C)。先将FIRST(C)中非空字ε的元素加入到FOLLOW(B)中;注意,如果FIRST(C)中含有空字ε,还要把FOLLOW(A)中的元素也加入到FOLLOW(B)中(如果不含空字就不这么做)

2.如果检验到的终结符右边没有别的符号了,例如这里的C,那么,直接将FOLLOW(A)中的元素加入到FOLLOW(C)中。

在这里,α的存在是无关痛痒的。也就是说,我们在检验某个非终结符时只要看他的右边就好了,左边有没有有什么都是无所谓的。大家按照上面的方法,将每一个侯选式中的非终结符都这样检查一遍,最后就能求得所有非终结符的FOLLOW集了

11. 递归下降分析法的概念,应满足什么条件?

能够用递归下降分析法分析的文法是LL(1)文法,要成为这种文法,必须满足以下条件:

(1)文法不含左递归(在这里提一句:欲构造行之有效的自上而下分析器,则必须消除文法中含有的左递归

(2)对于文法中每一个非终结符A的各个产生式的候选式的FIRST集两两不相交。即,若

​ A→α1|α2|…|αn

​ 则 FIRST(αi)∩FIRST(αj)=Φ (i≠j)

(3)对于文法中的每个非终结符A,若它的某个候选式的FIRST集中包含ε,则必须满足

​ FIRST(A)∩FOLLOW(A)=Φ

12. 预测分析表的构造

构造预测分析表的算法是:
(1)先画一张表格,表的首行是文法中所有的终结符号,首列是所有产生式的左部)

  (2)检验文法中每个产生式的每一个侯选式。我们先假设这里有一个产生式为A→α|b,若FIRST(α)中含有终结符a,则把“A→α”写入(1)中构造的表中的M[A,a]项(M[A,a]表示以产生式左部A为行,终结符a为列所对应的表格);若FIRST(b)中含有终结符β,则把“A→β”写入(1)中构造的表中的M[A,β]项(M[A,β]表示以产生式左部A为行,终结符β为列所对应的表格);按照这样的方法依次执行下去,直到把每一个产生式的每一个侯选式都检验完并对应填入表格。

 (3)特别地,若某个产生式侯选式的FIRST集中包含有空子ε:我们接着引用上例进行说明。在A→α|b中,假设FIRST(α)里还包含有ε,则找出 FOLLOW(A)中的所有终结符元素,我们假设其中一个是β,那么把“A→α”写入M[A,β]中,按照此方法将FOLLOW(A)中的所有元素逐一检验,并将“A→α”填入对应的表格中去即可。

  1. 实际大题

给出一个文法,要你最终构造出他的预测分析表,整个过程的步骤如下:

1.消除文法左递归

2.构造每个产生式左部(即->符号左边的非终结符)的First集、Follow集

3.构造每个产生式的每个侯选式的first集

4.证明文法是一个LL(1)文法

5.构造出预测分析表。

例:设有文法 G ( V T , V N , S , P ) G(V_T,V_N,S,P) G(VTVNSP)

其中 VT={a, ∧ ,, ,(,) };VN={S,T};S = S

P:

​ S → a | ∧ | (T)

​ T → T,S | S

(1)消除其产生式的左递归.

(2)经改写后的文法是否是LL(1)的?给出它的预测分析表

解:

(1)消除其产生式的直接左递归

对于T → T,S | S (按照第9点中介绍的知识,这里P=T,α=,S ,β=S)

​ 所以变成

T→ST’

​ T’→,ST’|ε

所以文法改写后变为:

​ S → a | ∧ | (T)

​ T→ST’

​ T’→,ST’|ε

(2)经改写后的文法是否是LL(1)的?给出它的预测分析表。

(这里的整体思路是按照第十点的知识构造出相应的FIRST集 和FOLLOW集 再按照第十一点的知识证明他是一个LL(1)文法,最后再用第十二点中知识求出预测分析表)

解: (先求所有产生式左部那个非终结符号的FIRST集,用的是第十点中关于FIRST集求法的(2)中的方法)

FIRST( S )={ a ∧ ( };

​ FIRST( T )={ a ∧ ( };

​ FIRST( T’)={ , ε };

(紧接着求所有的侯选式的FIRST集,方法是:如果这个侯选式的开头字符是终结符,也就是某个小写字母,又或者是空字,那么这个侯选式的FIRST集就是那个小写字母或者空字ε;如果侯选式开头是非终结符,就将那个非终结符的FIRST集中除空字ε以外的元素变为侯选式本身FIRST集的元素)

FIRST(ST’)={ a ∧ ( }; (S的FIRST集中除空字以外的元素)

​ FIRST(,ST’)={ , }; (, 本身)

​ FIRST(a)={ a }; (a 本身)

​ FIRST(∧)={ ∧ };

​ FIRST((T))={ ( };

FIRST(ε)={ε} (ε本身)

(接着求所有产生式左部那个非终结符号的FOLLOW集,方法在第十点中已经说得很清楚了,这里我再说明一下。大家做题时,可以在所有的侯选式中把出现非终结符的位置都标出来,然后挨个按照规则检查,就不会错了。有时在求某个非终结符的FOLLOW集时,发现其中还包含着其他非终结符FOLLOW集的元素,但那个FOLLOW集却还没有求出来,此时可先记下来,接着往下做,做到最后一定会找到某个终结符的FOLLOW集时与其他非终结符是无关的,把他写出来后,再回头把前面空出来的填完就好了。)

FOLLOW(T)={ ) };

FOLLOW (T’)={ ) };

FOLLOW (S)={ # , } };

完事之后要证明他是LL(1)文法,用到第十一点中的知识。

证明:

S → a | ∧ | (T)

​ T→ST’

T’→,ST’|ε

(1)文法已经消除了左递归

(2)FIRST(a)∩FIRST(∧) ∩FIRST((T))={a}∩{∧} ∩{(}=Φ

FIRST(,ST’) ∩FIRST(ε)=Φ

(3)在T’→,ST’|ε中,FIRST(ε)={ε},里面含有空字,所以需要检验:

FIRST( T’)∩FOLLOW (T’)={ ,,ε}∩{ ) }=Φ

接下来构造他的预测分析表

a()#
SS → aS → ∧S →(T)
TT→ST’T→ST’T→ST’
T’T’→ εT’→,ST’

(3)自下而上

14. 短语、直接短语的概念

归约是指根据文法的产生式规则,把产生式的右部替换成左部符号。实际上,我们在(2)中研究的自上而下是从产生式左部推导到右部的过程。也就是说,推导和归约其实是两个相逆的过程

15. 句柄的概念

一个句型的最左直接短语是这个句型的句柄

16. 规范归约、规范推导、规范句型

规范归约(最左归约)是一个关于**规范推导(**最右推导)的逆过程

(提示:在(2)自上而下的讨论中,事实上我们一直使用的是最左推导,即总是先把侯选式最左边的非终结符推导为终结符,请大家回想FIRST集的求法,事实上就是最左推导的过程)

由规范推导推出的句型称为规范句型

由于规范句型是由规范推导推出的句型,故该句型的句柄右边只含有终结符号(因为他是最右推导,右边的非终结符一定被推导成终结符了)

规范归约的关键问题是寻找句柄

在规范归约中,可归约串必出现在栈顶

19. 算符文法、算符优先文法的概念,如何判断

一个文法,如果它的任一产生式的右部都不含两个相继(并列)的非终结符,即不含如下形式的产生式右部:…QR… 则我们称该文法为算符文法,也称OG文法

算符之间的优先关系表示:(重要)

  1. a =. b 当且仅当文法G中含有形如P→…ab…或P→…aQb…的产生式;
  2. 2.a <. b 当且仅当G中含有形如P→…aR…的产生式, 而R -> b…或R->Qb…;
  3. 3.a>.b 当且仅当G中含有形如P→…Rb…的产生式,而 R->…a或R->…aQ

(这里大家先不必记住三种情况需要满足的条件,在后面求FIRSTVT和LASTVT集合时大家自然会看到是和这些规则对应上的。这里需要注意的是,算符之间的优先级关系有三种,请注意=.<.>. 这三个符号右下角的那一点是不能少的,(正确的写法应该是将点写在那三个符号的里面,word不好弄,大家可以看看课本上的正确写法)这不同等于数学上简单的等于大于和小于,出现a<.a的情况都是可能的,而且即使有a <. b,却并不意味着有b>.a,这看起来很荒谬,但是做题时却非常重要,这里大家一定要记住,以后如果求得算符之间的优先关系是a <. b,千万不要自作聪明写成b>.a,否则就全错了,切记切记!)

如果一个算符文法G中的任何终结符对(a,b)至多只满足下述三关系之一:

​ a=.b

​ a>.b

​ a<.b

则称G是一个算符优先文法(OPG文法)。如果有某两个算符之间的关系不只一种,那么它就不是一个算符优先文法

20. 素短语

素短语是指一个句型的短语,它至少包括有一个终结符号且除去它本身之外不再含任何更小的素短语

最左素短语: 处在句型最左端那个素短语成为最左素短语

算符优先归约的关键问题是寻找最左素短语

算符优先法尤其适用于表达式的分析

  1. Firstvt集合和lastvt集合的构造方法

Firstvt集合构造方法:

(1) 若有产生式P→a…或P→Qa…,

​ 则aÎFIRSTVT§;

(2)若aÎFIRSTVT(Q),且有产生式P→Q…,

​ 则aÎFIRSTVT§。

lastvt集合的构造方法

(1) 若有产生式P→… a或P→… aQ ,

​ 则aÎ LASTVT§;

(2)若aÎ LASTVT(Q),且有产生式P→… Q ,

​ 则aÎ LASTVT§。

(解析:授课老师认为这两个集合的构造方法要比FIRST和FOLLOW集合简单得多。针对以上的书面说法,说一些我个人的理解和方法。构造某个产生式左部的Fisrtvt或者lastvt集合,其实都是从他的产生式里去找。对于firstvt,无非两种情况,1.他的某个侯选式的第一个字母就是终结符,如P→a…,或者第一个字母是非终结符而第二个字母是终结符如P→Qa…,那么就把这个a加入到P的firstvt集合中去;2.他的某个侯选式中的第一个字母就是非终结符,如P→Q…,那么就把Q的firstvt中的元素加入到P中去(请注意,这里没有除去ε这一说,与FIRST集的构造方法是不同的)。对应的LASTVT集的构造其实是和firstvt是刚好相反的,大家想想就很容易明白,这里不赘述了。需要注意的是,当某个侯选式只有一个字符时,如P→a或P→Q,a和Q既算第一个也算最后一个,在构造两个集合时都应该予以考虑)

22.算符优先关系表的构造方法

这个方法是建立在你已经学会了上面所说的两个集合的构造方法基础上的,有了那两个集合,我们就可以根据他们计算出文法当中所有终结符之间的优先关系了,方法如下:

(1)假定有个产生式的一个候选形为···ab····或aPb····,有a=.b

(2)假定有个产生式的一个候选形为(a代表终结符,P代表非终极符)

…aP…

那么,对任何bÎFIRSTVT§,有a <. b。

(3)假定有个产生式的一个候选形为

Pb

那么,对任何aÎLASTVT§,有a >. B

(解析:(1)的情况很简单,对(2)和(3),这里的方法概括起来说就是,找到侯选式中所有一个终结符紧挨着一个非终结符的情况,如aP或者Pa,如果是前者,那么得出a<.P的所有FIRSTVT集合中的元素;如果是后者,那么得出P的所有LASTVT集合中的元素>.a 只要把所有候选式里的这两种情况都考虑完,所有算符之间的优先关系也就找到了。还是请大家注意,a<.P的所有FIRSTVT集合中的元素这句话,并不等同于P的所有FIRSTVT集合中的元素>.a,千万别反过来写,一定把两种情况的顺序记清楚,a是在前面还是在后面。)

当把所有终结符的优先关系找出来后,就可以构造一张算符优先关系表了。表的首行首列分别都是文法的所有终结符,请注意,首行和首列写出来终结符的顺序一定要是一致的。(请看下面的表)将算法优先关系的三个符号>.<.=.按照前面找到的各算符之间的优先关系依次填入表格就可以了。填入时要注意,一定要先读列,再读行。即首列上的终结符对应的应该是符号左边的那个元素,首行上的终结符对应的应该是符号右边的那个元素。

a%<>!
a>.<.<.<.
%>.>.<.<.>.
<>.>.>.
><.<.<.=.
!>.>.>.

当列完表格后,需要进行判断:如果在上面的表格中任意一个空里都至多只有一个符号,那么写:由于本文法中任意两个终结符之间都至多只满足>.<.=.中的一个,由此可以看出本文法是一个算符优先文法;如果有任意一个空多余一个符号,那么写:由于本文法中任意某两个终结符之间有两种优先级关系,由此可以看出本文法不是一个算符优先文法

例:给出文法G(P)

X → jYj

Y → kZ|i

Z → Yid

该文法是否为算符优先文法?请根据FIRSTVT、LASTVT集合构造算符优先关系表说明之

  1. LR分析法属于自底向上分析方法

    1. 从文法出发构造LR(0)分析表的步骤

(1)构造文法G的拓广文法G’

(2)构造LR(0)项目

(3)构造G’的项目集规范族(CLOSURE和GO函数)

(画出一个确定的有限自动机DFA)

(4)构造分析表


语义分析

综合属性和继承属性概念

综合属性

用于“自下而上”传递信息

在语法树中,一个结点的综合属性的值由其子结点的属性值确定。

因此,通常使用自底向上的方法在每一个结点处使用语义规则计算综合属性的值。

仅仅使用综合属性的属性文法称S—属性文法五、中间代码生成

继承属性

用于“自上而下”传递信息。

在语法树中,一个结点的继承属性由此结点的父结点和/或兄弟结点的某些属性确定。

用继承属性来表示程序语言结构中的上下文依赖关系很方便。

中间代码生成

  1. 中间代码是一种面向语法,易于翻译成目标代码的代码

  2. 后缀式(逆波兰式)的概念

  3. 逆波兰式中各运算法出现的顺序与实际运算顺序一致

  4. 后缀式与抽象语法树(表达式树)的关系

  5. DAG的含义

  6. 四元式表示方法,联系时通过临时变量,可以翻译各种语句

  7. 将赋值语句表示成后缀式和四元式


1. 中间代码:

是一种面向语法,易于翻译成目标代码的代码

中间语言的形式有三种:后缀式、图表示法(包括抽象语法树和有向无环图(DAG)两种)、三地址代码

2. 后缀式(逆波兰式)的概念

把运算量(操作数)写在前面,把算符写在后面。

例如:a+b,写成ab+

逆波兰式中各运算法出现的顺序与实际运算顺序一致

(1) a*(-b+c)

(2) a+b*(c+d/e)

(3) -a+b*(-c+d)

(4) not A or not (C or not D)

(5) (A and B) or (not C or D)

(6) (A or B) and (C or not D and E)

解:

(1) ab-c+*

(2) abcde/+*+

(3) a-bc-d+*+

(4) A not C D or not or not

(5) A B and C not D or or

(6) A B or C D not E and or and

3. 后缀式与抽象语法树(表达式树)的关系

后缀式其实是抽象语法书的线性表示形式,并且是按后根序遍历得到的。

4. 将赋值语句表示成后缀式和四元式

这里不介绍什么方法了,后缀式的求法已经在上面介绍过,关于四元式,大家看看这个例子相信自然就能够明白。

将表达式a:=(b+c)*e+(b+c)/f分别表示成后缀式、四元式(这道题2012年考的是原题)

解:

1.后缀式:a b c + e * b c + f / + :=

  1. 四元式

(1) ( +, b, c, T1 )

(2) ( *, T1, e, T2 )

(3) ( +, b, c, T3 )

(4) ( /, T3, f, T4 )

(5) ( +, T2, T4, T5 )

(6) ( :=, T5, , a )

再给一个例子:

表达式-(a+b)*(c+d)-(a+b+c)分别表示成四元式

解:1. 四元式

(1) ( +, a, b, T1 )

(2) (-, T1, , T2 )

(3) ( +, c, d, T3 )

(4) ( *, T2, T3, T4 )

(5) ( +, a, b, T5 )

(6) ( +, T5, c, T6 )

(7) ( -, T4, T6, T7)


代码优化

  1. 简述代码优化的原则与优化的级别,并列举三种常用的优化技术

  2. 基本块、流图的概念,如何画、节点对应基本块

  3. 局部优化的方法,DAG是对基本块进行优化的有效工具

  4. 不变运算的代码外提的条件

  5. 循环优化中的强度削弱的含义

1. 简述代码优化的原则与优化的级别,并列举三种常用的优化技术**(小题)**

三个原则:

¨ 等价原则:经过优化后不应改变程序运行的结果;

¨ 有效原则:使优化后所产生的目标代码运行时间较短,占用的存储空间较小;

¨ 合算原则:应尽可能以较低的代价取得较好的优化效果

优化级别:

¨ 局部优化

¨ 循环优化

¨ 全局优化

常用的优化技术:

¨ 删除公用子表达式

¨ 代码外提

¨ 强度消弱

2. 基本块、流图的概念,如何画、节点对应基本块、要求进行局部和循环优化

一:首先要了解两种语句的概念和特征,对于后面的做题方法很重要

1.转移语句:如果某个句子中含有goto··语句,那么他就是一个转移语句

转移语句又分为两种:1.条件转移语句:形如ifgoto的语句2.无条件转移语句:只有goto,没有if的语句

2.停语句:halt 这样的语句被称为是停语句。

二:接着要知道入口语句的求法:有三种语句是入口语句

  1. 程序的第一个语句,

  2. 能由条件转移语句或无条件转移语句转移到的语句(就是GOTO后面指向的语句,例如(3)号语句里有GOTO(8),那么(8)就是入口语句)

  3. 紧跟在条件转移语句后面的一个语句。

三:划分四元式程序为基本快的方法:(这里看起来比较抽象,大家跟着看后面的例题就会理解)

对求出的每个入口语句,确定其所属的基本块。它是由

A一个入口语句到下一入口语句(不包括该入口语句)之间的语句序列

B一个入口语句到一转移语句(包括该转移语句)之间的语句序列

C 一个入口语句到一停语句(包括该停语句)之间的语句序列组成的

四:流图的画法:(这里看起来也比较抽象,大家跟着看后面的例题就会理解)

每个流图以基本块为结点。如果一个结点的基本块的入口语句是程序的第一条语句,则称此结点为首结点。如果在某个执行顺序中,有B1和B2 两个基本块,如果存在以下两种情况中的任意一种

1.有一个条件或无条件转移语句从B1的最后一条语句转移到B2的第一条语句;

2.在程序的序列中,B2紧接在B1的后面,并且B1的最后一条语句不是一个无条件转移语句

我们就说B1是B2的前驱,B2是B1的后继,并从B1画一条有向边到B2

五:给出实际的例题(这是复习PPT上的例题)

给出程序的四元式表达形式,画出基本块和流图

(1) read C

(2) A:=0

(3) B:=1

(4) A:=A+B

(5) If B>=C goto (8)

(6) B:=B+1

(7) goto (4)

(8) write A

(9) halt

解:

第一步是找出入口语句:(1)为程序的第一句; (4)为(7)的GOTO得来; (6)为(5)的后一句;(8)为(5)的GOTO得来

第二步画基本块:(画基本块的方法是用方框把语句框起来,这里不好画,我没有框)

(1)(2)(3)为一基本块(对应三种A的方法) (4)(5)为一基本块(对应B) (6)(7)为一基本块(对应B) (8)(9)为一基本块(对应C)

第三步画流图:

请添加图片描述

3. 局部优化的方法

DAG是对基本块进行优化的有效工具

利用DAG可以实现局部优化

(1)合并已知量

(2)删除多余运算

(3)删除无用赋值

4. 不变运算的代码外提的条件

不变运算所在的结点是循环L所有出口结点的必经结点.

对于循环不变运算A:=B op C,只有A在循环中其他地方未再定值,才能把A:=B op C外提;

循环中所有A的引用点只有S中的A的定值才能到达。

5. 循环优化中的强度削弱的含义

把程序中执行时间较长的运算转换为执行时间较短的运算

强度消弱主要是对与归纳变量有线性关系的变量赋值进行;

经过强度消弱后,循环中可能出现一些新的无用赋值;

对于消弱下标变量地址计算的强度非常有效


目标代码生成

编译程序生成的目标程序种类(309)

目标代码一般有以下三种形式:

  • 能够立即执行的机器语言代码所有地址已经定位;

  • 待装配的机器语言模块执行时,由连接装配程序把它们和某些运行程序连接起来,转换成能执行的机器语言代码;

  • 汇编语言代码尚须经过汇编程序汇编,转换成可执行的机器语言代码。

总结

编译原理这门课的知识点还是挺多的, 也十分难学, 学习这门课只能说拓展视野, 要想自己造一个编译器还是十分困难的, 并且上述总结的知识点是结合上课老师讲解和老师提供的资料结合而成, 可能有部分错误,如有发现欢迎指正. 这里只是编译原理的部分知识, 也可以说算是核心基础知识, 若要深入学习, 还需看额外参考书。

这里提供两本参考书 :
编译原理 - 陈国旺 pdf版链接:https://pan.baidu.com/s/1o5rxO-ycQ7gymVA_khrK4Q
提取码:6666

编译原理 ‘‘龙书’’ pdf版链接:https://pan.baidu.com/s/1Ka6Izw24A3PWUsg1i25CjQ
提取码:6666

  • 11
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值