编译原理期末(软考)复习笔记(基础知识+例题+实验代码)

编译原理》完整笔记 阅读详情

目录

前言

第一章绪论

编译概述

编译程序的结构

第二章 高级语言及其语法描述

 符号以及符号串

上下文无关文法

语法树

第三章词法分析

3.1词法分析器的功能

3.2单词的类型和内部表示

3.2.1单词的类型:

3.2.2单词的内部表示

3.3词法分析器的设计

3.3.1总体设计

3.3.2详细设计

3.3.3状态转化图

 3.4正规表达式与有限自动机

1、正规式和正规集

正规式的运算:

 正规式的等价:

正规式转换为正规文法 

正规文法转换为正规式 

2、确定的有限自动机(DFA)

DFA的定义

​编辑 DFA的矩阵表示

有穷自动机如何识别字符串 

​编辑3、不确定的有限自动机

NFA定义

DFA与NFA的区别:

​编辑 ​编辑

NFA转化为等价的DFA

DFA的化简 



前言

刚好大三下这个学期在学编译原理,就随着教学进度来更新一篇十分全面的笔记。无论是备战期末考试还是面试,软考都可以看一看,网络上有很多全是基础概念定义的博客,老实说不是给自学的人看的,我想写一份可以看懂的笔记,因为我觉得这门课挺难的。毕竟是学生,能力有限,有任何纰漏和错误请评论提醒我,我一定会看,负责任的说,我觉得认真看完这篇帖子再做总结,期末考试肯定是可以轻松过的。大家一起学好基础,共勉!

参考书籍:编译原理与实践(北京邮电大学出版社)

例题:B站,学习通例题

第一章绪论

现在我们学习的大都是使用高级语言来编程,但是电脑是不懂高级语言的,所以如果想要真正在计算机上执行,我们必须要使用相应的翻译程序来将其翻译成机器语言。翻译程序的代表就是编译程序,而开发编译程序所涉及的原理,方法,技术就是这门课程所研究的。

编译概述

我们学习过操作系统,知道计算机系统的语言有机器语言,汇编语言,高级语言。 从机器到汇编到高级,其实是一个不断拉近人类思维与计算机语言的过程,使得我们可以方便清晰地编写自己想要的程序。但是我们编写的语言必须要在计算机上才可以运行,所以我们也必须要找一个方法来实现高级语言和汇编语言转化或机器语言的程序,这种方法就是翻译,也就是我们常说的翻译程序。编译器或编译程序这样的翻译程序可以将源程序转化为目标程序。源程序指代的是Java,c,c++这些我们在学校里会学习到的高级语言,而目目标程序就是汇编或者是机器语言这样的低级语言了。

高级语言除了可以编译执行外,还可以解释执行。如果考简答题的话需要重点掌握。

编译程序和解释程序的主要区别如下:

1、编译程序是将整个源程序翻译成目标程序之后再执行,而且目标程序可以反复执行。

2、解释程序对源程序逐句地翻译执行,不产生目标程序。如果需要再次执行,则必须重新解释源程序。

编译程序的结构

这个基本上就是咱们上课的目录啦。

编译程序的工作由上面的概述可知:输入源程序到输出目标代码。就是这么“简单”

下面是图示:

<为了有清晰地展示效果,我还去下载了一个drawio,不过下载速度实在太慢了,所以还是用网页版了>

从工作过程角度分析,可以将编译程序的工作划分为五个阶段:词法分析阶段、语法分析阶段、语义分析与中间代码生成阶段、代码优化阶段,目标代码生成阶段

这些阶段可以与图中的模块对应起来,各个阶段之间关系是十分紧密的。其实编译程序翻译源程序和人们翻译自然语言之前也是很相似的,下面有一个表格,可以让我们大概了解每一章的学习到底有什么作用。

词法分析是实现编译器的基础,语法分析是实现编译器的关键,也是核心功能。所以学校考试的重点也会放在这一方面,一定要认真学弄懂,一次学懂,期末完全不带怕的,实在不行学会做题也是很棒的。

第二章 高级语言及其语法描述

我们知道语法分析是编译程序的核心,词法分析已经语义分析都是围绕着语法分析而来的。实践证明,上下文无关文法在描述高级语言的语法结构方面具有极大的优势,本书讲重点讨论上下文无关文法的定义、语法分析树、文法的二义性,并对文法的分类做简单的描述。

 符号以及符号串


上下文无关文法

 文法是一种描述语言的语法结构的形式规则(即语法规则),这些规则必须准确且易于理解,同时应该具有相当强的描述能力,足以描述各种不同的语法结构。所谓的上下文无关文法是指这样一种文法,它所定义的语法范畴(或语法单位)是完全独立于这种范畴可能出现的环境的。简单来说就是我们在分析表达式时可以只用观察它的语法结构,而不用去考虑它的语境,也就是上下文。本门课无特殊说明,所说的文法均指上下文文法。

语法树

第三章词法分析

词法分析是编译程序的第一阶段,该阶段的主要工作是逐个扫描输入的源程序字符串,识别出字符串中的各个单词,并输出单词的内部表示符号,用以进行语法分析。这就是词法分析器或者直接叫做扫描器吧,这就是它的功能,它作为即将编译的源程序和编译器后续阶段的接口,从上面的编译器结构图也可以看出,源程序指向它,它指向了后面的语法分析,词法分析所做的工作很简单,就是扫描和识别嘛,就和夸克里面的拍照一样,拍一下就可以把某个物体的样子扫描进手机,然后识别出它是个什么东西。所以很简单,完全不用害怕,下面让我们来详细地学习它,并且自己做出来一个词法分析器。

3.1词法分析器的功能

词法分析器的输入是源程序字符串,而源程序是由程序设计语言的单词构成的,单词是程序设计语言不可分割的最小单位。<在英文中有很多字母嘛,这些字母就像是字符,连接起来就是字符串啦,有一些字母连接起来可以变成单词,它拥有实际上的意义,有的则是错误拼写。>词法分析器从左到右逐个字符地对源程序进行扫描,按照语言的定义规则,将字符拼接成为单词。每当识别出一个单词,就产生其种别码,这样源代码就变成了单词符号串的中间形式,然后提交给语法分析程序判别语法是否有问题。

在我们扫描前,我们首先要做一个预处理操作!预处理的工作也是很重要的,它要过滤出程序中一些无用的成分,比如说注释,空格,换行,这些都是给程序员看的,为的是便于阅读,美观简洁,但是他们对于生成目标代码没有任何作用。还有的就是检查有没有非法字符还有一些不符合构词规则的单词。非法符号就像是自然语言中的错字,你不可能自己创作一个字来使用吧,别人是没有办法理解的,当然编译器也无法理解非法的字符。

在编译程序中,词法分析器有两种实现模式:

1、完全独立模式:词法分析器作为编译程序的子系统独立运行一遍,扫描整个源程序,把识别出的单词使用统一的记号序列输出到中间文件,作为语法分析程序的输入。这是本篇文章所用的方法,它调理清晰,而且移植性强。

2、相对独立模式:词法分析器作为语法分析程序的子程序,每当语法分析程序需要一个单词时,就调用该子程序。词法分析程序每得到一次调用,就从源程序文件读入若干个字符,返回一个单词符号给语法分析程序。这种方法我们可以看出,没有中间文件,有利于提高编译程序的效率。

3.2单词的类型和内部表示

3.2.1单词的类型:

我们已经知道了单词是程序设计语言的最小单位,而不是字符,这一点我们需要区分。单词符号是最基本的语法单位,具有确定的语法意义。分为5类;

  1. 关键字:是程序设计语言定义的具有特定意义的名字。
  2. 标识符:用户在设计源程序时自己定义的名字。
  3. 常数:是程序设计语言或用户在设计源程序时定义的。
  4. 运算符:也叫算符,是程序设计语言中定义的符号,一般有逻辑运算符,算术运算符和关系运算符。
  5. 界符:是程序设计语言定义的符号,包括标点符号和一些特殊符号。

3.2.2单词的内部表示

词法分析器输入的是源程序,输出的是单词的内部表示。

其内部表示形式一般为二元式:(单词种别编码,单词的属性值),其中单词的种别编码在语法分析的时候使用,单词的属性值在语义分析和中间代码生成时使用。

单词的种别码表示单词的种类,一般都是用整数来表示的。单词怎么分类,怎么编写种别码没有统一的规定,如果你自己来做一个词法分析器的话,那么你就可以自己定义一个种别码,来表示不同单词属于哪个分类。但是要求就是不同的单词有可以彼此区分且唯一的表示。一般来说,一个程序设计语言的关键字,界符和算符都是固定的,可以采用一符一种的方式,标识符一般归统为一种,而常数按其类型进行分类(整型,实型,字符型,布尔型)。

3.3词法分析器的设计

恭喜你已经掌握了上述的基础知识,这个时候我们该学着做一个词法分析器了,这并不难,我们需要慢慢来。这一章我们还要学习一个很重要的知识——状态转化图

3.3.1总体设计

首先,将源程序输入到输入缓冲区,经过预处理子程序处理一定长度的字符串后送入扫描缓冲区,扫描器从扫描缓冲区识别出一个个单词。当扫描缓冲区中的字符串用完后,在调用预处理子程序,将一段新的字符串送入扫描缓冲区。预处理子程序的主要作用就是删除无用空格,回车键,换行符和注释等。扫描器的重要工作是通过读入的首字符串进行分类,然后继续通过读入的字符识别关键字,识别符,常数,算符,界符。扫描器是词法分析的主要组成部分。

3.3.2详细设计

详细设计这一块重要说的就是扫描器的工作原理啦,首先我们来讲讲预处理子程序,前面我们就知道了它的存在。空白符,回车键,换行符以及注释等字符对于执行程序来说没有实际的用处,所以在构造预处理子程序时我们可以将其删除,并且用一个空格来代替。

3.3.3状态转化图

状态转换图是设计词法分析程序一种很好的方法,它既可以描述单词的结构,也可以识别单词,只要用程序实现了识别单词的状态转换图就可以完成词法分析器。

状态转换图是一个有限图,结点用圆圈表示,称为状态,状态之间用带箭头的弧线连接,称为边。

一张状态转换图值包含有限个状态(结点),其中,有一个是初态(=>指向),至少有一个是终态(双圈表示)。从其实状态输入一个字符,它就会沿着这个字符的边进入下一个状态,重复执行输入,直到进入终结状态。如下面的第一个图,从初始态开始,输入a则进入1终态。从初始态开始输入b则进入2终态。

如果存在一个从起始状态到终结状态的路径,那么将路径上的标记用连接运算符连接在一起形成一个符号串,如果它和输入的符号串相同,则称这个输入符号串可以接受。如果不能进入任何一个终结结点,则称状态转换图不可以识别这个输入字符串。例如下面的第二个图是一个识别整数的状态转换图,从初始状态0开始,读入一个字符,如果是数字则进入状态1,否则标记识别失败,进入状态1后,如果输入是数字,则还在状态1(while循环),如果不是则转向状态2;标记着我们已经读完了一个字符串,但是此时我们多读入了一个不是数字的字符呀,所以我们输入指针必须要回退一个字符,将其退回给扫描缓冲区,因为它是属于下一个单词的,我们再给终态标上*号。

 3.4正规表达式与有限自动机

为了讨论词法程序的自动生成,通常是要引入正规式的概念。这一块我们一定要理解引入的目的到底是什么,这一块我常常怀疑这个东西到底有什么用,经过不断地学习终于找到了答案。

正规式是用表达式的形式来表示单词的构成;正规文法是从产生单词的观点来描述单词;

有限自动机是从识别的观点来描述单词,三者在单词的描述上是等价的。

1、正规式和正规集

字母表∑上的正规式用来描述一种称为正规集的语言。下面是定义

  1. ε和∅都是字母表∑上的一个正规式,他们所表示的正规集分别为{ε}和∅
  2. 对于任何的a∈∑,a是∑的一个正规式,它所表示的正规集为{a};
  3. 假设U和V都是∑上的正规式,它们所表示的正规集分别为L(U)和L(V),那么,(U|V)、(U•V)和U*也都是正规式,它们所表示的正规集有L(U)∪L(V,L(U)L(V),(L(U))*

 其中|读作或,.读作连接,*读作闭包,优先级为 * > •> |

正规式的运算:

 

 

 

 正规式的等价:

正则文法: 

正规式转换为正规文法 

 

正规文法转换为正规式 

2、确定的有限自动机(DFA)

有限自动机也叫做有穷自动机,是一种识别正规集的装置,它能够识别正规文法所定义的语言和正规式所表示的集合。 

DFA的定义

 DFA的矩阵表示

有穷自动机如何识别字符串 

3、不确定的有限自动机

NFA定义

DFA与NFA的区别:

不确定的有限自动机是确定有限自动机DFA的一般化,其定义与DFA类似,不确定的有限自动机的基本特征在于,当一个状态遇到同一个输入符号时,可能有多种不同的转换。

 

NFA转化为等价的DFA

我们可以看出DFA是NFA的特例,那么如何从NFA得到等价的DFA呢?这需要用到NFA的确认化技术。

我们知道,NFA M所能识别的字符串的全体记为L(M),对于任意的两个有限自动机M和N,若L(M)=L(N),则称它们是等价的。

对于每个NFA N,都存在着一个DFA M,使得L(N)=L(M);与某一NFA等价的DFA不唯一。


  从NFA构造等价的DFA,我们通常使用的是子集法,其基本的思路是:DFA的每一个状态与NFA的一组状态相对应,用DFA的一个状态去记录在NFA读入一个输入符号后可能达到的状态集合。下面先介绍一下与状态集合I有关的几个运算。

个人认为,这一块NFA转DFA的内容是比较难懂的,但是通过概念,我们可以得到一个有规律的执行步骤,梳理好这个我们再次用例题来彻底学会它。

重点:

第一个步骤:由于NFA的初态和终态结点可能有好几个,而且每条弧上的标记可能是∑*上的一个字符串,因此我们的目标就是改造成只有一个初态结点和一个终态结点,且每条弧上只能是单个输入符号或者ε的状态图。具体的做法是:

1、增加一个状态X和Y,使其成为唯一的初态结点和终态结点。我们不是有好几个嘛,那就全部导向它,然后就变成只有一个啦,很好理解。从X结点引弧ε到原来的初始结点,从原来的终态结点引ε到Y结点。

2、我们可以根据一个替换规则,不断重复,这样弧上面的字符串就变成一个单个字符或者ε。

这样我们就完成了第一步,十分简单,第二个步骤:后面就用我们上面学到的子集法对NFA进行确定化。具体做法如下:

1、对∑={a1,a2........ak},构造一个k+1列的状态转换表,列为状态,行为输入字符。是不是很像前面学习过的状态转换矩阵。我们将这个表的首行首列置为ε_Closure(X),X为第一步我们化简过后的那个开始状态。

2、若某行的第一列的状态已确认为I(状态集合),则计算第i+1(i=1,2,3....k)列的值为Iai(ai是下标哈),然后,检查该行上所有的状态子集,看其是否已经在第一列出现。若没有出现,则将其添加到后面的空行上。重复这一过程,知道所有的状态子集均在第一列中出现为止。

3、将每个状态子集视为一个全新的状态,即可得到一个DFA。初态就是首行首列的状态,终态即使含有原有终态的所有状态。

第二个步骤的定义我可以感觉到有一些晦涩,没关系,我们来看一道例题,你马上就可以掌握这个方法。

怎么样,是不是已经完全懂了它是什么意思,《编译原理与实践》这本书写得真不错,推荐需要学习的同学去买来看一看,也不是很厚。 

DFA的化简 

 DFA化简指的是,许找一个状态数最少得的DFA M',使得L(M)=L(M')。

每个正规集都可以用一个状态数最少得DFA所识别,如果不考虑状态名所带来的差异,可以说这个DFA是唯一的。

化简是消去DFA中多余或无用的状态,并且合并等价状态的过程。所谓多余状态是指,从初始状态出发,读入任何输入串都无法到达的那个状态,或者说没有通路可以到达终态。

好的,我们再来讲如何化简:化简的基本思想是DFA M的状态分成一些不相交的子集,使得任何不同子集中的状态都是可以区别的,而同一个子集中的状态都是等价的。是不是就是上面提到的分类合并。然后,从每个子集中选出一个状态作为代表,同时消去其他等价状态。这种方法被称为:“分割法”。具体过程是:

1、将M的所有状态分成两个子集,终态集和非终态集。

2、观察每个子集,若发现某个子集中的状态不等价,则将其划分为两个集合。

3、重复第二步,继续观察已得到的每个子集,知道没有任何一个子集需要继续划分为止。此时的DFA中的状态被分割成了若干个互不相交的子集。

4、从每个子集中选出一个状态作为代表,即可得到最简的DFA

很容易理解,我们来看一道例题

4月5日更新至此

大学编译原理试卷试题 编译原理期末试题(一) 一、是非题(请在括号内,正确的划√,错误的划×)(每个2分,共20分) 1.编译程序是对高级语言程序的解释执行。(× ) 2.一个有限状态自动机中,有且仅有一个唯一的终态。(×) 3.一个算符优先文法可能不存在算符优先函数与之对应。 () 4.语法分析时必须先消除文法中的左递归 。 (×) 5.LR分析法在自左至右扫描输入串时就能发现错误,但不能准确地指出出错地点。 () 6.逆波兰表示法表示表达式时无须使用括号。 () 7.静态数组的存储空间可以在编译时确定。 (×) 阅读详情

相关推荐

编译原理期末习题复习题目(重点三)

编译原理期末习题复习题目(重点三) 目录 编译原理期末习题复习题目(重点三) 三、是非题 四、简答题 三、是非题 (下列各题,你认为正确的,请在题干的括号内打“ √”,错的打“×”。) 1.计算机高级语言翻译成低级语言只有解释一种方式。 (X) 2.在编译中进行语法检查的目的是为了发现程序中所有错误。 (X) 3.甲机上的某编译程序在乙机上能直接使用的必要条件是甲机和乙机的操作系统功能完全相 同。 (X) 4.“用高级语言书写的源程序都必须通过编...

csq542586的博客 6721

编译原理笔记个人手写整理.pdf

编译原理笔记个人手写整理.pdf

编译原理期末复习(选择)

1.将编译程序分成若干个“遍”是为了(B ) A.提高程序的执行效率 B.使程序的结构更加清晰 C.利用有限的机器内存并提高机器的执行效率 D.利用有限的机器内存但降低了机器的执行效率 2.构造编译程序应掌握(D ) A.源程序 B.目标语言 C.编译方法 D.以上三项都是 3.变量应当(C ) A.持有左值 B.持有右值 C.既持有左值又持有右值 ...

weixin_54217081的博客 1万+

编译原理笔记1:概述编译相关的基本知识

拉链-回填实际上也是先引用后声明,但只需要扫描一遍——当第一次读到引用时,先把后面的目标位置填个问号,读到多次也都填上问号——因为引用了相同的东西,所以这个问号可以“拉成一条链”。语义分析这一步,要看语法结构正确的语法树的含义是否正确——这一步也可以做些附加的操作,比如这里对60的转换,这就是编译器为了简化语言而自动进行的附加工作——对类型进行了自动转换。这两个工具可以根据我们输入的词法 / 语法规则,自动生成相应的语法分析器、词法分析器,然后这些分析器就可以帮助我们简单地完成对源代码的词法、语法分析。

VengaZ的学习博客 1326

编译原理笔记整理

编译原理 笔记整理 1.1 《编译原理》引论 基本概念——发展 机器语言 汇编语言 高级语言 工具语言 基本概念——翻译程序 把某一种语言程序(称为源语言程序)等价的转换成另一种语言程序(称为目标语言程序)的程序 如:中英互译系统、DBMS语言(DDL、DCL) 基本概念——编译程序 把某一种高级语言程序等价的转换成另一种低级语言程序(如:汇编语言或机器语言程序)的程序 编译程序分类: 诊断编译程序&优化编译程序 交叉编译程序&可变目标编译程序运行 基本概念——解释程序

i_want_to_studyi的博客 9564

编译原理期末总结

编译原理期末总结

m0_51312071的博客 2955

编译原理期末复习重点

编译原理期末复习纲要 一、选判填 单选:5*1=5' 判断:5*=5' 填空:10*=10' 合计:20‘ 一、简答题 12选4,4*5'=20' 什么是编译程序? 编译程序是现代计算机系统的基本组成部件之一。从功能上看,一个编译程序就是一个语言翻译程序。 编译有哪几个过程? 词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成共6个过程。 编译和解释的区别? 两者主要是工作模式上的区别。编译是将源程序代码转换成目标代码,通常目标代码是汇编代码,然后需要将目标代码进一

热爱编程、热爱生活、热爱探索 5613

编译原理期末速成笔记

TYUT 编译原理期末速成,持续更新中。

m0_52861684的博客 1万+

期末复习编译原理

期末复习编译原理

小心星的博客 2632

编译原理】一篇就够了——学习笔记与课程实验超详细整理

编译原理学习笔记,一篇就够!,对应龙书的1-9章内容,详细介绍了相关方法原理与步骤。同时整理基于Java的词法分析与语法分析的课程实验

一棵灬大树的博客 1万+

编译原理课后习题答案(清华大学第三版)

第二章答案 第三章答案 第四章答案 第五章答案 第六章答案

xqmids99的博客 5万+

编译原理期末复习笔记

编译原理这门课通过证明是可以速成的。 我说的“速成”是平时还要支棱一只耳朵听课哦。 其实后面几次课听了之后仿佛掌握到了其中精髓。 还有就是这门课复习起来很爽,因为复习过程可以感悟到很多新的知识,有很多体会之类。(详情参见朋友圈) 引论 词法分析 FIRST集&FOLLOW集&FIRSTVT&FOLLOWVT 设计有穷自动机 嘿嘿,总之编译原理还是挺有意思的,学进去了就会发现其中乐趣~ 来看克鲁鲁跳舞! ...

BlingBling_An_的博客 8271

编译原理》-习题复习

博主近期开始了编译原理这门课的复习,在大致地过了一遍基础内容后,我决定开始对于题的练习,今天看了b站上的up主“废物点心v”的题目讲解后,做出了大致的总结。本篇文章仅充当学习分享,如有谬误尽情指正。ps:!!!!!!!!!!!!!!!!!!!!!第一章 绪论_哔哩哔哩_bilibili我今天的主要内容就是基于上面这个视频来的。up讲的很不错,方法很明了清晰!

m0_75114363的博客 6332

吉林大学编译原理期末复习整理

22级相比于21级题目难度有所提高,题型和内容总体换汤不换药,但是在细节上有加强22级无选择题,简答题涉及到的知识点(部分)包括:(1)编译方式与解释方式的根本区别(第一题)(2)画出程序运行到***时栈的内容(包括全部变量,静态变量)(3)写出while循环的目标代码(JMPF,地址回填)(4)画出驻留法(跳转法)的全局符号表还有一两道没印象的简答题但是不难大题了两道语法分析题,LL(1)和LR(1)各一道,画起来很麻烦时间会比较紧张。

m0_73654355的博客 1万+

编译原理复习

答:语法制导翻译直观上说就是为每个产生式配上一个翻译子程序(称语义动作或语义子程序),并且在语法分析的同时执行这些子程序。也即在语法分析过程中,当一个产生式获得匹配(对于自上而下分析)或用于归约(对于自下而上分析)时,此产生式相应的子程序进入工作,完成既定的翻译任务。

capture3333的博客 5954

编译原理笔记例题

编译原理笔记例题

weixin_40185366的博客 5193

编译原理 期末复习

期末试 判断 高级程序设计语言的代码在机器上运行可通过编译方式或解释方式实现,编译方式优于解释方式。错误 计算机只能识别机器代码,所以只能用机器语言实现编译程序。错误 不是所有句型都有规范推导。正确 递归文法的语言是无穷集。正确 “遍”是对源程序或源程序的中间结果从头到尾扫描一次,并做有关加工处理,生成新的中间结果或目标程序。一个编译程序所分遍数越多越好。错误 过程的活动...

Seven 1万+

编译原理期末复习

编译原理期末复习 1.问题1:如何转为DFA

zwz_chome的博客 3808
下一篇: 微服务项目中,不同部署环境的配置文件(dev、sit、uat、prod)
#樱井智树
博客等级 码龄6年 331粉丝 · 2原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值