编译程序构造与实践教程第二章
编译程序构造原理和实现技术
编译程序构造原理和实现技术1.什么是编译程序编译程序是一种将源代码翻译成目标代码的程序。
编译程序的主要目的是将源代码转换成机器可以执行的指令,这样计算机就能够正确地执行源代码的功能。
编译程序的工作过程一般包括词法分析、语法分析、语义分析、代码生成和代码优化等几个阶段。
2.编译程序构造原理编译程序的构造原理主要涉及到编译原理、计算机组成原理和数据结构等学科的知识。
在编译程序的构造中,最关键的是语法分析和代码生成。
2.1语法分析语法分析就是对源代码进行词法分析、语法分析和语义分析等处理,将源代码转换成语法树或抽象语法树。
语法树可以帮助编译器识别代码的结构,为后面的代码生成提供有用的信息。
在语法分析中,编译器需要实现一些类似递归下降分析和LR分析的算法,以实现对源代码的解析。
语法树和抽象语法树还可以用来进行代码调试和优化。
2.2代码生成代码生成是将语法树或抽象语法树转换成目标代码的过程。
在这个过程中,编译器需要实现目标代码的生成和优化。
目标代码生成的具体方式取决于编译器的实现以及编译器的目标平台。
3.实现编译程序的技术在实现编译程序时,需要借助一些工具和技术。
下面介绍一些常用的编译程序实现技术。
3.1词法分析器和解析器生成器词法分析器和解析器生成器是实现编译器的重要工具。
它们通常可以根据语法规则自动生成针对特定语言的词法分析器和解析器,这极大地简化了编译器的实现和维护。
在词法分析和解析器生成器中,Flex和Bison是两个常用的工具。
其中Flex是一个用来生成词法分析器的工具,而Bison是一个用来生成解析器的工具。
3.2代码生成器代码生成器是实现编译器的另一个重要工具。
在代码生成器中,通常会实现许多针对不同目标平台的编译器前端,以帮助开发人员快速生成高效的目标代码。
在代码生成器中,常用的工具有LLVM和GCC等。
其中LLVM是一个开源的编译器框架,支持多种语言,可以用来构建可扩展的编译器前端和后端。
计算机编译程序构造与实践
术语: 汇编程序:把汇编语言程序翻译成 等价的机器语言程序 编译程序:把高级语言程序翻译成 等价的低级语言程序
源程序
目标程序
源语言
目标语言
运行子程序
源程序
编译程序
目标程序
输入数据
目标程序 运行子程序
输出结果
编译原理课程基本内容 • 高级程序设计语言是一种符号语言 编译程序是符号处理的工具 • 编译原理讨论: 编译程序构造的基本原理、技术和方法 • 三个方面 ·高级程序设计语言的定义和相关概念 ·与编译实现相关的形式语言理论基本概念 ·编译程序构造的原理、技术和方法
程序设计语言描述 print ("Input values of a, b and c"); read (a ); read (b ); read (c ); sum=a+b+c; print("sum=", sum);
C语言描述 printf(" … "); scanf("%d",&a); scanf("%d",&b); scanf("%d",&c); sum=a+b+c; print("sum=", sum);
计算机编译原理
编译程序构造与实践
第一章 概述 1.1 编译程序的引进
1.1.1 高级程序设计语言与程序
程序是什么?
程序设计语言是什么?
程序的概念 程序:要求依序执行的一系列工作。
英语描述 Please input values of a,b and c. Type a value for a. Type a value for b. Type a value for c. Find the sum of a, b and c. Output the value of the sum. 中文描述 请输入a,b和c的值。 输入一值作为a的值。 输入一值作为b的值。 输入一值作为c的值。 求a, b和c之和的值。 输出该和的值。
C++理论与实战 第2章 零基础开始学习——C++的程序结构
命名空间可以是全局的,也可以位于另一个命名空间之中,但是不能位于类和代码 块中。所以,在命名空间中声明的标识符,默认具有外部链接特性(除非它引用了 常量)。
2.3 输入和输出数据
2.4 命名空间
2.4.1 命名空间的定义 2.4.2 using关键字 2.4.3 命名空间std
2.4.1 命名空间的定义
在C++中,名称(name)可以是符号常量、变量、宏、函数、结构、枚举、类和 对象等。在大规模程序的设计中,以及在程序员使用各种各样的C++库时为了避免 ,这些标识符的命名发生冲突,标准C++引入了关键字namespace(命名空间/名 字空间/名称空间/名域)3;+的预处理(preprocess),是指在C++程序源代码 被编译之前,由预处理器(preprocessor)对C++程序 源代码进行的处理。虽然预处理命令不是C++语言的一 部分,但是它有扩展C++程序设计环境的作用。
提示:预处理命令是C++统一规定的,但是它不是C++ 语言本身的组成部分,不能直接对它们进行编译(因为 编译程序不能识别它们)。
第2章 零基础开始学习——
C++的程序结构
本章内容
2.1 分析C++程序的结构 2.2 编译前的预处理 2.3 输入和输出数据 2.4 命名空间 2.5 实战演练——经典的入门程序
编译原理教程课后习题答案第二章
第二章 词法分析2.1 完成下列选择题:(1) 词法分析器的输出结果是。
a. 单词的种别编码b. 单词在符号表中的位置c. 单词的种别编码和自身值d. 单词自身值(2) 正规式M1和M2等价是指。
a. M1和M2的状态数相等b. M1和M2的有向边条数相等c. M1和M2所识别的语言集相等d. M1和M2状态数和有向边条数相等(3) DFA M(见图2-1)接受的字集为。
a. 以0开头的二进制数组成的集合b. 以0结尾的二进制数组成的集合c. 含奇数个0的二进制数组成的集合d. 含偶数个0的二进制数组成的集合【解答】(1) c (2) c (3) d图2-1 习题2.1的DFA M2.2 什么是扫描器?扫描器的功能是什么?【解答】 扫描器就是词法分析器,它接受输入的源程序,对源程序进行词法分析并识别出一个个单词符号,其输出结果是单词符号,供语法分析器使用。
通常是把词法分析器作为一个子程序,每当词法分析器需要一个单词符号时就调用这个子程序。
每次调用时,词法分析器就从输入串中识别出一个单词符号交给语法分析器。
2.3 设M=({x,y}, {a,b}, f, x, {y})为一非确定的有限自动机,其中f 定义如下:f(x,a)={x,y} f {x,b}={y}f(y,a)=Φ f{y,b}={x,y}试构造相应的确定有限自动机M ′。
【解答】 对照自动机的定义M=(S,Σ,f,So,Z),由f 的定义可知f(x,a)、f(y,b)均为多值函数,因此M 是一非确定有限自动机。
先画出NFA M 相应的状态图,如图2-2所示。
图2-2 习题2.3的NFA M 用子集法构造状态转换矩阵,如表表2-1 状态转换矩阵1b将转换矩阵中的所有子集重新命名,形成表2-2所示的状态转换矩阵,即得到 M ′=({0,1,2},{a,b},f,0,{1,2}),其状态转换图如图2-3所示。
表2-2 状态转换矩阵将图2-3所示的DFA M ′最小化。
第2节课第二章
图1-3 以语法分析程序为中心的编译程序逻辑结构
• 显然,由于整个编译程序只对源程序进行一
次扫描,故不必产生中间代码。 • 对于某些程序语言,例如PASCAL和C,用一 遍扫描的编译程序去实现比较困难,宜于采 用多遍扫描的编译程序结构。
本章内容结束
第2章 前后文无关文法和语言
• 在20世纪50年代,N.Chomsky首先对语言的描 述问题进行了探讨。他提出了一种用来描述语 言的数学系统,并以此定义了四类性质不同的 语言,称为语言(文法)的Chomsky分类。
• 此处所说的“遍”,是指对源程序或其内部表示 从头到尾扫视一次,并进行有关的加工处理工作。
• 例如,对于要求经一遍扫描就能完成从源程
序到目标代码翻译的编译程序,我们可以语 法分析程序为中心来组织它的工作流程。
源程序
开始
词法分析 程序
语法分析 程序
语义分析及 代码生成程序
整理目标程序
目标程序
停机
是语法上合法的句子。
为得到文法的严格定义,对前面的规则进
行如下的概括:
• 含有一系列需要定义的语法范畴,通常我们把
它们的名字称为非终结符号。 • 由这些非终结符号组成的集合称为非终结符号 集,用 VN 记之。对于上例,我们有: VN = {〈句子〉,〈主语短语〉,〈动词短语〉,
〈宾语短语〉,〈名词〉,〈动词〉,〈冠词〉}
编译程序的构成
• 编译程序主要由八个部分构成: 1.词法分析程序(扫描器 scanner) 2.语法分析程序(分析器 parser) 3.语义分析程序 4.中间代码生成程序 5.代码优化程序 6.目标代码生成程序 7.错误检查和处理程序 8.各种信息表格的管理程序
1.2
编译程序的逻辑结构
计算机编译原理-编译程序构造实践课程设计
计算机编译原理-编译程序构造实践课程设计1. 课程设计简介计算机编译原理-编译程序构造实践是一门旨在培养学生编写编译程序的能力的课程,通过本课程的学习,学生将掌握如何使用编译器生成目标代码,并了解编译程序的工作原理。
2. 实验环境本课程实验环境选择了Windows 10操作系统和C++编程语言。
学生需要安装Visual Studio 2019开发环境,并熟悉使用C++编程语言进行开发。
此外,学生需要掌握汇编语言,并能使用汇编语言来实现一些基本的程序功能。
3. 实验流程在本课程中,我们将通过以下几个实验环节来让学生掌握编译程序的构造方法。
3.1 实验一:词法分析器词法分析器是一个编译程序中重要的组成部分,它的主要作用是将输入的字符流分解成一系列的标记(token),并识别它们的类型。
在本实验中,我们要求学生开发一个简单的词法分析器,用于识别输入程序中的关键字、标识符、运算符等元素。
3.2 实验二:语法分析器在本实验中,我们要求学生使用自顶向下的LL(1)分析方法,构建一个简单的语法分析器。
学生需要使用产生式规则来表示程序语言的语法规则,并使用递归下降法或LL(1)分析法来识别程序语言中的各种语法结构。
3.3 实验三:中间代码生成器在本实验中,我们要求学生将识别出的程序语法结构转化为中间代码。
中间代码是一种类似于汇编语言的中间表示形式,它通常比源代码更简单,更易于优化,同时也比目标代码更容易移植。
3.4 实验四:目标代码生成器在本实验中,我们要求学生将中间代码转化为真正的目标代码。
目标代码是可以直接在计算机上运行的二进制代码,它是编译程序的最终产物。
学生应当学会如何将中间代码转化为目标代码,并优化目标代码的生成过程。
3.5 实验五:整合实验在本实验中,我们要求学生将前四个实验所涉及的功能整合到一个完整的编译器中。
学生需要将前四个实验的成果逐步组合,完成一个完整的编译器。
4. 实验评分本课程的总分为100分,其中实验评分占70分,考试成绩占30分。
编译原理与实践第二章答案
The exercises of Chapter Two2.1 Write regular expression for the following character sets, or give reasons why no regular expression can be written:a. All strings of lowercase letters that begin and end in a. [Solution]a[a-z]*a | ab. All strings of lowercase letters that either begin or end in a ( or both)both: a(a|b|c|…|z)* ac. All strings of digits that contain no leading zeros[Solution][1-9][0-9]*d. All strings of digits that represent even numbers(0|1|2|…|9)*(0|2|4|6|8)e. All strings of digits such that all the 2’s occur before all the 9’s [Solution]a=(0|1|3|4|5|6|7|8)r=(2|a)*(9|a)or[^9]*[^2]*or[^9]*2(1|[3-8])*9[^2]*g. All strings of a’s and b’s that contain an odd number of a’s or an odd number of b’s(or both)[Solution]r1=b*a(b|ab*a)*--------odd number of a’sr2= a*b(a|ba*b)*-------odd number of b’sr1|r2|r1r2|r2r1orb*a(b*ab*a)*b*|a*b(a*ba*b)*a*i. All strings of a’s and b’s that contain exactly as many a’s as b’s [Solution]No regular expression can be written, as regular expression can not count.2.2 Write English descriptions for the languages generated by the following regular expressions:a. (a|b)*a(a|b|ε)[Solution]All the strings of a’s and b’s that end with a, ab or aa.OrAll the strings of a’s and b’s th at do not end with bb.b. All words in the English alphabet of one or more letters, which start with one capital letter and don ’t contain any other capital letters.c. (aa|b)*(a|bb)* [Solution]All the strings of a’s and b’s that can be divided into two sub-stings, where in the left substring, the even number of consecutive a’s are separated by b’s while in the right substring, the even number of consecutive b’ are separated by a’s.d. All hexadecimal numbers of length one or more, using the numbers zero through nine and capital letters A through F, and they are denoted with a lower or uppercase “x ” at the end of the number string.2.12 a. Use Thompson’s construction to convert the regular expression (a|b)*a(a|b|ε) into an NFA.b. Convert the NFA of part (a) into a DFA using the subset construction.[Solution]a.b. The subsets constructed as follows: { 7 } = { 7, 5,1,3,8,9} { 7 }a = {2, 10}{ 7 }b = {4}{2,10} = {2,6,5,1,3,8,9, 10,17,11,13,15,16,18}{2,10}a = {2, 10, 12} {2,10}b ={4, 14}a{2,10,12} = {2,6,5,1,3,8,9,12,18,10,17,11,13,15,16} {2,10,12}a = {2,10,12} {2,10,12}b = {4, 14}{4,14} = {4,6,5,1,3,8,9,14,18} {4,14}a = {2,10} {4,14}b = {4}{4} = {4,6,5,1,3,8,9} {4}a ={2,10} {4}b ={4}2.15Assume we have r* and s* according to figure 1 and 2:Consider r*s* as followThis accepts, for example, rsrs which is not in r*s*. I. e., in this case we cannot eliminate the concatenating ε transition.2.16 Apply the state minimization algorithm of section 2.4.4 to the following DFAs: a.[Solution]a. Step 1: Divide the state set into two subsets:{1, 2, 3}{4, 5} Step 2: Further divide the subset {1,2,3} into two new subsets:{1}{2, 3}Figure 2 r*s*Step 3: Can not divide the subsets any more, finally obtains three subsets: {1}{2, 3}{4, 5}Therefore, the minimized DFA is:[Solution]b. Step 1: Divide the state set into two subsets:{1, 2}{3, 4, 5}Step 2: Further divide the subset {1,2} into two new subsets:{1}{2}Step 2: Further divide the subset {3,4,5} into two new subsets:{3}{4, 5}Step 4: Can not divide the subsets any more, finally obtains three subsets: {1}{2}{ 3}{4, 5}Therefore, the minimized DFA is:。
《编译原理》教学课件 第2章-一个微小的编译器
4. ToyL语言解释器
• interpreter(){ ( 一遍扫描解释器)
• rp = 0; op = 0;pp = 0; mp = -1; dsp= -1; osp = 0;
•
OS[0]= HEAD; token(BEGIN);
•
while( !=END ){
if OS[top]< then push(OS, )
else
Process
d1= pop(DS,1) ; d2= pop(DS,1); op= pop(OS,1) ; v= d2 op d1;
goto L; push(DS,v) ;
• RE=[#]
:
while OS[top] [ ] do
Process
// = OS[top’] pop(DS,2) pop(OS,1) push(DS,T)
•
token(CLOSE);
•
break;
•
case IDEN:
token(ASS);
•
update (tk.seman,evaluate_expr());
•
break;
•
default :
error()
•
}
•
next_token(tk)
•}
•}
5. ToyL语言编译器
• 目标代码功能:把表达式的值计算出来 ,并存到某临时变量,我们称此临时变 量为结果变量。
虚拟输入器: – 为描述read(x)语句解释执行过程,需要设置程序的输入数据所在 的介质,我们称其为输入介质,或简称为虚拟输入器,并记为Inp 。 – 可用整型数组来模拟
虚拟输出器: – 为描述Write(E)语句解释执行过程,需要设置程序的输出数据所 在的介质,我们称其为输出介质,或简称为虚拟输出器,并记为 Out 。 – 也用整型数组来模拟
第2章 词法分析-编译原理及实践教程(第3版)-黄贤英-清华大学出版社
=> 0 >
1=
2
>
3=
4
其他
Hale Waihona Puke 其他6*5*
识别>、>=、>>、>>=四个单词的状态转换图
数值型常量的识别
0~9
1~9
=> 0
1
其他
* 2
0
十进制整型数
=> 0
0~7 0 3 其他 4 *
八进制整型数
=> 0 0
0~9
0~9 |a~f
|a~f |A~F
3 x/X 5 |A~F 6 其他 7 *
十六进制整型数
字母或数字
* 0 字母 1 其它 2
识别标识符的转换图
一个状态图可用于识别一定的字符串,大多数程序 设计语言的单词符号都可以用转换图来识别。
字母或数字
* 0 字母 1 其它 2
识别过程是:从初始状态0开始,若读入一个字母, 转入1状态,若再读入字母或数字,仍处于1状态, 否则转向2状态,结束一个标识符的识别过程。状 态上的*表示多读入一个符号。
错误处理程序
源 程 序
词
语
语
法
法
义
分
分
分
析单 析 语
器
词 记
器
法 单
析 器
语 法 单
中 间 代 码 生 成 器
中 间 代
代 码 优 化
器
中 间 代
目 标 代 码 生 成
器
目 标 代 码
号
位
位
码
码
表格管理程序
2.1 词法分析器概述
• 功能:
源程序
词法分析程序 Token串 语法分析程序
实践教程第二章第二版
API函数: API函数: 函数
为使程序员在编写应用程序时实现这些特征, 为使程序员在编写应用程序时实现这些特征, Windows提供了一个应用程序编程接口,称Windows 提供了一个应用程序编程接口 提供了一个应用程序编程接口, API(Application Programming Interface),这是 ( ) Windows支持的函数定义、参数定义和消息格式的集 支持的函数定义、 支持的函数定义 可供应用程序调用。 合,可供应用程序调用。 这上千个API函数包含了各种窗口类和系统资源 API函数 这上千个API函数包含了各种窗口类和系统资源 内存管理、文件、线程等等)。 )。利用这些函数就可以 (内存管理、文件、线程等等)。利用这些函数就可以 编出具有Windows风格的程序。 Windows风格的程序 API也是 编出具有Windows风格的程序。Windows API也是 Windows操作系统自带的在Windows环境下运行的 操作系统自带的在Windows环境下运行的软件开 Windows操作系统自带的在Windows环境下运行的软件开 发包(SDK) 程序员总是直接或间接引用API API进行应用 发包(SDK)。程序员总是直接或间接引用API进行应用 程序的开发,所以Windows Windows应用程序就有大致相同的用 程序的开发,所以Windows应用程序就有大致相同的用 户界面。 户界面。
2.1 传统的 传统的Windows 编程
标准Win32 API 函数分类: 函数分类: 标准
1) 系统服务 2) 通用控件库 3) 图形设备接口 4) 网络服务 5) 用户接口 系统Shell 6) 系统Shell 7) Windows 系统信息
2.1 传统的Windows 编程 传统的
编译原理第二章-课后题答案
第二章3.何谓“标志符”,何谓“名字”,两者的区别是什么答:标志符是一个没有意义的字符序列,而名字却有明确的意义和属性。
4.令+、*和↑代表加、乘和乘幂,按如下的非标准优先级和结合性质的约定,计算1+1*2↑2*1↑2的值。
(1)优先顺序(从高到低)为+、*和↑,同级优先采用左结合。
(2)优先顺序为↑、+、*,同级优先采用右结合。
答:(1)1+1*2↑2*1↑2=2*2↑2*1↑2=4↑2*1↑2=4↑2↑2=16↑2=256(2)1+1*2↑2*1↑2=1+1*2↑2*1=1+1*4*1=2*4*1=2*4=86.令文法G6为N-〉D|NDD-〉0|1|2|3|4|5|6|7|8|9(1)G6的语言L(G6)是什么(2)给出句子0127、34、568的最左推导和最右推导。
答:(1)由0到9的数字所组成的长度至少为1的字符串。
即:L(G6)={d n|n≧1,d∈{0,1,…,9}}(2)0127的最左推导:N=>ND=>NDD=>NDDD=>DDDD=>0DDD=>01DD=>012D=>0127 0127的最右推导:N=>ND=>N7=>ND7=>N27=>ND27=>N127=>D127=>0127(其他略)7.写一个文法,使其语言是奇数集,且每个奇数不以0开头。
答:G(S):S->+N|-NN->ABC|CC->1|3|5|7|9A->C|2|4|6|8B->BB|0|A|ε[注]:可以有其他答案。
[常见的错误]:N->2N+1原因在于没有理解形式语言的表示法,而使用了数学表达式。
8.令文法为E->T|E+T|E-TT->F|T*F|T/FF->(E)|i(1)给出i+i*i、i*(i+i)的最左推导和最右推导。
(2)给出i+i+i、i+i*i和i-i-i的语法树,并给出短语,简单短语和句柄。
习题参考答案-编译原理及实践教程(第3版)-黄贤英-清华大学出版社
附录部分习题参考答案第1章习题1. 解释下列术语。
翻译程序,编译程序,解释程序,源程序,目标程序,遍,前端,后端解答:略!2. 高级语言程序有哪两种执行方式?阐述其主要异同点。
描述编译方式执行程序的过程。
解答:略!3. 在你所使用的C语言编译器中,观察程序1.1经过预处理、编译、汇编、链接四个过程生成的中间结果。
解答:略!4. 编译程序有哪些主要构成成分?各自的主要功能是什么?解答:略!5. 编译程序的构造需要掌握哪些原理和技术?编译程序构造工具的作用是什么?解答:略!6. 复习C语言,其字母表中有哪些符号?有哪些关键字、运算符和界符?标识符、整数和实数的构成规则是怎样的?各种语句和表达式的结构是什么样的?解答:略!7.编译技术可应用在哪些领域?解答:略!8. 你能解释在Java编译器中,输入某个符号后会提示一些单词、某些单词会变为不同的颜色是如何实现的吗?你能解释在Code Blocks中在输入{后,会自动添加},输入do 会自动添加while()是为什么吗?解答:略!第2章习题1. 判断题,对下面的陈述,正确的在陈述后的括号内画√,否则画×。
(1) 有穷自动机识别的语言是正规语言。
()(2) 若r1和r2是Σ上的正则表达式,则r1|r2也是。
()(3) 设M是一个NFA,并且L(M)={x,y,z},则M的状态数至少为4个。
()(4) 令Σ={a,b},则所有以b开头的字构成的正规集的正则表达式为b*(a|b)*。
()(5) 对任何一个NFA M,都存在一个DFA M',使得L(M')=L(M)。
()1解答:略!2.从供选择的答案中,选出应填入下面叙述中?内的最确切的解答。
有穷自动机可用五元组(Q,V T,δ,q0,Q f)来描述,设有一有穷自动机M定义如下:V T={0,1},Q={q0,q1,q2},Q f={q2},δ的定义为:δ (q0,0)=q1δ (q1,0)=q2δ (q2,1)=q2δ (q2,0)=q2M是一个 A 有穷状态自动机,它所对应的状态转换图为 B ,它所能接受的语言可以用正则表达式表示为 C 。
编译原理第二章:一个微小编译器
z1=x1+56;
printf(“%f”,z1+2.3);
scanf(“%f”,&x1)
}
2021/3/7 北京化工大学信息科学与技术学院计算机系 13
2.1 Micro语言描述
Micro语言的定义
P begin VDL;SL end. VDL VD | VD ; VDL VD var id : T SL S | S ; SL S id:= E | write(E) | read(id) T int | real E id | num | E + E | E * E |(E)
端
Target Code Generator
文字表 Literal Table
符号表 Symbol Table
错误处理 Error Handler
目标程序 Target Code
2021/3/7 北京化工大学信息科学与技术学院计算机系 4
编译器的分析/综合模式
编 译 器
分 析 ( 前 端 )
综 合 ( 后 端 )
2.1 Micro语言描述
Micro语言(称Micro, Pascal语言的子集)
begin
Pascal
var x1:real;
var z1:real;
x1:=0.5;
z1:=x1+56;
write(z1+2.3);
read(x1)
end.
Main(){
C
float x1;
float z1;
x1=0.5;
2021/3/7 北京化工大学信息科学与技术学院计算机系 11
第2章 一个微小编译器
2.1 Micro语言描述 2.2 Micro语言的词法分析 2.3 Micro语言的语法分析 2.4 Micro语言的语义分析 2.5 Micro语言的目标代码
编译原理教程 第二章
第2章 词法分析
状态(即结点)数是有限的,其中必有一初始状态以及若 干终止状态,终止状态(终态)的结点用双圈表示以区别于其 它状态。图2-3给出了用于识别标识符、无符号整数、无符 号数的状态转换图,其初始状态均用0状态表示。
第2章 词法分析
(a) 标识符;(b) 无符号整数;(c) 无符号数
第2章 词法分析
对于给定的字母表Σ,正规式和正规集的递归定义如下: (1) ε和Ф都是Σ上的正规式,它们所表示的正规集分别 为{ε}和Ф。 (2) 对任一个a∈Σ,a是Σ上的一个正规式,它所表示的 正规集为{a}。 (3) 如果R和S是Σ上的正规式,它们所表示的正规集分 别为L(R) 和L(S),则: ① R∣S是Σ上的正规式,它所表示的正规集为 L(R)∪L(S); ② R·S是Σ上的正规式,它所表示的正规集为L(R) L(S); ③ (R)*是Σ上的正规式,它所表示的正规集为(L(R))*; ④ R也是Σ上的正规式,它所表示的正规集为L(R)。
第2章 词法分析
为了理解正规式与正规集的含义,我们以程序语言中的 标识符为例予以说明。程序语言中使用的标识符是一个以字 母开头的字母数字串,如果字母用letter表示,数字用digit表 示,则标识符可表示为
letter (letter∣digit)* 其中,letter与 (letter∣digit)*的并置表示两者的连接;括号 中的“∣”表示letter或digit两者选一;“ * ”表示零次或多 次引用由“ * ”标记的表达式;(letter∣digit)*是letter∣digit 的零次或多次并置,即表示一长度为0、1、2、…的字母数 字串;letter (letter∣digit)*表示以字母开头的字母数字串, 也即标识符集。letter (letter∣digit)*就是表示标识符的正规 式,而标识符集就是这个正规式所表示的正规集。
编译原理及实践教程第2章参考答案
第2章参考答案:1:解答:略!2.解答:字母表:是元素的有穷非空集合Σ字母表:是元素的有穷非空集合Σ符号串: 由字母表中的符号组成的任何有穷序列称为符号串,推导: 连续使用产生式右部去替换左部某个非终结符的过程,得到的连续序列称为一个推导。
句型:设G(s)是一文法,如果符号串x是从开始符号推导出来的,即有s=>x,则称x是文法G(s)的一个句型。
(在语法树的推导过程中的任何时刻,没有后代的端末结点自左至右排列起来就是一个句型)句子:若x仅由终结符号组成,则称x为G(S)的句子最左推导: 在整个推导过程中,任何一步推导α=>β都是对α中最左边的非终结符进行替换。
如果一个文法存在某个句子对应两棵不同的语法树,则说这个文法是二义的语法树:推导的形式化表示,有助于理解句子语法结构的层次3.解答:略!4. 解答:A:① B:③ C:① D:②5. 解答:用E表示<表达式>,T表示<项>,F表示<因子>,上述文法可以写为:E → T | E+TT → F | T*FF → (E) | i最左推导:E=>E+T=>E+T+T=>T+T+T=>F+T+T=>i+T+T=>i+F+T=>i+i+T=>i+i+F=>i+i+iE=>E+T=>T+T=>F+T=>i+T=>i+T*F=>i+F*F=>i+i*F=>i+i*i最右推导:E=>E+T=>E+F=>E+i=>E+T+i=>E+F+i=>E+i+i=>T+i+i=>F+i+i=>i+i+iE=>E+T=>E+T*F=>E+T*i=>E+F*i=>E+i*i=>T+i*i=>F+i*i =>i+i*ii+i+i和i+i*i的语法树如下图所示。
编译原理第2版第二章PL0编译程序
词法分析如何把单词传递给语法分析 type symbol=(nul,ident,number,plus,…,varsym,procsym);
3个全程量 SYM:symbol; ID:alfa; NUM:integer;
通过三个全程量 SYM 、ID和NUM 将识别出的单词信息传递给语 法分析程序。 SYM:存放单词的类别 如:有程序段落为: begin initial := 60;end 对应单词翻译后变为: begin beginsym, initial ident, ‘:= ‘ becomes, 60 number, ‘;’ semicolon, end endsym 。 ID: 存放用户所定义的标识符的值 如: initial (在 SYM中放ident,在ID中放initial) NUM:存放用户定义的数 如:60 (在SYM中放number,在NUM中放60)
OPR 0 12 OPR 0 13
次栈顶是否大于栈顶,退两个栈元素,结果值进栈 次栈顶是否小于等于栈顶,退两个栈元素,结果值进栈
OPR 0 14 OPR 0 15 OPR 0 16
栈顶值输出至屏幕 屏幕输出换行 从命令行读入一个输入置于栈顶
const a=10; var b,c; procedure p;
出错处理程序 表格管理程序
PL/0编译程序的结构
PL/0源程序 词法分析程 序 语法语义分析程序
代码生成程序
目标程序
PL/0编译程序的总体设计
以语法、语义分析程序为核心 词法分析程序和代码生成程序都作为一个过程, 当语法分析需要读单词时就调用词法分析程序, 而当语法、语义分析正确,需要生成相应的目标 代码时,则调用代码生成程序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
G1= ( VN, VT, P1, S1 ) VN={S1, A, B} VT={a, b, c} P1: S1::=S1c| Bc B ::=Bb | Ab A ::=Aa | a L(G1)={ ai bj ck | i, j, k≥1} G2= ( {S2, A}, {a, b, c}, P2, S2 ) P2: S2::=S2c | Ac A ::=aAb | ab L(G2)={ ai bi ck | i, k≥1}
2. 从推导构造语法分析树 的推导: 句子 Nanjing is a beautiful city 的推导: <句子 句子>=> <主语 主语> <复合谓语 复合谓语> 句子 主语 复合谓语 => <名词 名词> <复合谓语 复合谓语> 名词 复合谓语 => Nanjing <复合谓语 复合谓语> 复合谓语 => Nanjing <系动词 <表语 系动词> 表语 表语> 系动词 => Nanjing is <表语 表语> 表语 => Nanjing is <冠词 <形容词 <名词 冠词> 形容词> 名词> 冠词 形容词 名词 => Nanjing is a <形容词 <名词 形容词> 名词> 形容词 名词 => Nanjing is a beautiful <名词 名词> 名词 => Nanjing is a beautiful city 如何为它构造语法分析树? 如何为它构造语法分析树?
从该语法分析树可明显看出: 从该语法分析树可明显看出:Nanjing是名词 是名词 作主语, 是系动词 是系动词, 作主语 is是系动词,与后面的表语构成复合谓语 ,等等。 可写出 等等。 相应的文法规则如下: 相应的文法规则如下: <句子 句子>::=<主语 复合谓语 主语><复合谓语 句子 主语 复合谓语> <主语 主语>::=<名词 名词> 主语 名词 <名词 名词>::=Nanjing |Hangzhou |Beijing |city 名词 <复合谓语 复合谓语>::=<系动词 表语> 系动词><表语 复合谓语 系动词 表语 <系动词 系动词>::=is | was 系动词 <表语 表语>::=<冠词 形容词 名词 冠词><形容词 名词> 表语 冠词 形容词><名词 <冠词 冠词>::=a | an |the 冠词 <形容词 形容词>::=beautiful | great |wonderful 形容词
2. Chomsky文法类与程序设计语言 文法类与程序设计语言 上下文无关文法定义 (1) 程序设计语言一般用上下文无关文法定义 : 程序设计语言一般用上下文无关文法 U::=u (2) 但语言一般是上下文有关的 a. <标号 标号>::=<标识符 标识符> <变量 变量>::=<标识符 标识符> 标号 标识符 变量 标识符 标号>::=goto <标识符 标识符> goto <标号 标号 标识符 <标号 语句 标号>:<语句 语句>::=<标识符 标识符>:<语句 语句> 标号 标识符 语句
7i 12i
对照: 对照: 从推导构造语法分析树: 从推导构造语法分析树: 不断添加分支的过程 从语法分析树构造推导: 从语法分析树构造推导: 不断剪去分支的过程
相应地有4类 语言: 相应地有 类Chomsky语言: 语言 0型语言(短语结构语言 型语言( 型语言 短语结构语言PSL) ) 1型语言(上下文有关语言 型语言( 型语言 上下文有关语言CSL) ) 2型语言(上下文无关语言 型语言( ) 型语言 上下文无关语言CFL) 3型语言(正则语言RL) 型语言(正则语言 ) 型语言 注意: 注意: a. 一般,程序设计语言都用上下文无关文法定义。 一般,程序设计语言都用上下文无关文法定义。 b. 2型文法规则 型文法规则U::=u中,u∈(VN∪VT)+ 型文法规则 中 ∈ 有时对2型文法,扩充有ε规则与 句子: 有时对 型文法,扩充有 规则与ε句子 型文法 规则与 句子 ε规则 : U ::= ε ε句子 : Z =>* ε 规则 句子 * 因此, ∈ 因此, u∈(VN∪VT)*。 例如, 语句 语句>::=if(<表达式 表达式>)<语句 语句><else部分 部分> 例如,<if语句 表达式 语句 部分 <else部分 部分>::=else <语句 语句> 部分 语句 <else部分 部分>::=ε 部分
概括起来,从推导构造语法分析树的过程如下: 概括起来,从推导构造语法分析树的过程如下:以识 别符号为根结点, 别符号为根结点,从它开始关于每一个直接推导画一个分 这一分支的名字是直接推导左边被替换的非终结符号。 支。这一分支的名字是直接推导左边被替换的非终结符号。 而分支的分支结点符号串是直接推导右边所替换的符号串。 而分支的分支结点符号串是直接推导右边所替换的符号串。 重要性质: 重要性质: 分支的分支结点符号串是相应句型中相对于分支名字 分支的分支结点符号串是相应句型中相对于分支名字 结点的简单短语 简单短语。 结点的简单短语。 Z=>* xUy => * xuy U=>u
2.3 句型分析 2.3.1 句型分析与语法分析树 句型分析:关于某个文法,识别一个输入符号串是 句型分析:关于某个文法, 否其句子的过程称为句型分析。 否其句子的过程称为句型分析。 对于程序设计语言,句子是程序, 对于程序设计语言,句子是程序,句型分析的问题 就是识别输入符号串是否是语法上正确无误的程序。 就是识别输入符号串是否是语法上正确无误的程序。 为了有利于句型分析,引进一种辅助工具语法分 为了有利于句型分析,引进一种辅助工具 析树,简称语法树。语法分析树是句型分析的好工具。 析树,简称语法树。语法分析树是句型分析的好工具。 句型分析的好工具
G3=( {S3, B, C, D}, {a, b, c}, P3, S3 ) P3: S3 ::=abC | aS3BC CB::=CD CD::=BD BD::=BC bB::=bb bC::=bc cC::=cc L(G3)={ ai bi ci|i≥1} G4=( {S4, A, B, C, D, E}, P4 : S4 ::=ACaB CB::=DB aD::=Da aE::=Ea L(G4)={ a2
可画出相应的语法分析树如图所示。 可画出相应的语法分析树如图所示。
1E
2E
3+4TFra bibliotek5T8T
9*
10 F
6F
11F
13 i
7i
12 i
对照输入符号串 的推导, 对照输入符号串i+i*i的推导,构造语法分析树的步骤 输入符号串 的推导 如下。 如下。 步骤1 以识别符号E为根结点 为根结点, 步骤 以识别符号 为根结点,对应于第一个直接推 向下作分支, 三条边连同三个分支结点E、 导E=>E+T向下作分支,即,三条边连同三个分支结点 、 向下作分支 +与T。 与 。 步骤2 对应于下一个直接推导E+T=>T+T,把E替换 步骤 对应于下一个直接推导 , 替换 为分支名字结点, 为T,以E为分支名字结点,从它向下画一个分支,这时 , 为分支名字结点 从它向下画一个分支, 是一个边连同边上的结点T。 是一个边连同边上的结点 。 步骤3 类似地,每次对应于一个直接推导, 步骤 类似地,每次对应于一个直接推导 从左边被 替换的非终结符号所对应的结点出发向下画分支 分支, 替换的非终结符号所对应的结点出发向下画分支,相应的 分支结点符号串正是替换该非终结符号的符号串 。如此 继续, 继续,重复步骤 3,画出相应于直接推导的分支,直到推 ,画出相应于直接推导的分支, 导结束。最后得到的语法分析树就是所求。 导结束。最后得到的语法分析树就是所求。
以简单实例为例讨论语法分析树的构造。 以简单实例为例讨论语法分析树的构造。 设有文法G 设有文法 [E]: : E::=E+T|T T::=T*F|F F::=(E)|i 对于输入符号串i+i*i可有下列推导: 可有下列推导: 对于输入符号串 可有下列推导
E=>E+T=>T+T=>F+T=>i+T=>i+T*F=>i+F*F=>i+i*F=>i+i*i
1. 语法分析树 借用英语等课程的语法分解图,引进语法分析树。 借用英语等课程的语法分解图,引进语法分析树。 语法分析树由边和结点组成。 句子 句子> 语法分析树由边和结点组成。<句子 术语: 术语: <主语 主语> <复合谓语 复合谓语> 结点 主语 复合谓语 根结点 末端结点 <名词 <系动词 名词> 系动词 系动词> <表语 表语> 边 名词 表语 分支 <冠词 <形容词 <名词 冠词> 形容词 形容词> 名词 名词> 分支名字结点 冠词 分支结点 a beautiful city 分支结点符号串 Nanjing is 末端分支 子树 子树末端结点符号串 树 末端结点符号串 注意:结点用小圆表示,但为简单起见,一般不画小圆。 注意:结点用小圆表示,但为简单起见,一般不画小圆。
2.2.3 文法和语言的分类 1. Chomsky文法类与语言类 文法类与语言类 对文法四要素概括与抽象。 对文法四要素概括与抽象。 定义: 文法G=( 定义:Chomsky文法 (VN, VT, P, Z) 文法 其中: VT P Z 其中 VN 文法及例: 文法及例: L={ aibjck | i,j,k≥1} G[S]: S::=Sc |Bc B::=Bb |Ab A::=Aa |a G'[S]: S::=ABC A::=Aa |a B::=Bb |b C::=Cc |c