当前位置:文档之家› 编译原理第一章

编译原理第一章


解释执行
① 不生成目标代码 ② 能支持交互环境(同增量式编译系统) 优点:交互方便,节省空间。 缺点:效率低。因对源程序的循环语句部分 要反复解释执行。 共同点:都需进行词法、语法、语义分析。 可比喻为: -编译是笔译(产生目标程序) -解释是口译(不产生目标程序) 很多语言如BASIC,LISP和PROLOG等等 最初都是解释执行的,后来也都有了编译系统 。号称最具生命力的JAVA环境同时需要解释 和编译系统的支持
特定机器上的绝对指令代码或可重定位的指令 代码或汇编指令代码。这是编译的最后阶段, 它的工作与硬件系统结构和指令含义有关,这 个阶段的工作很复杂,涉及到硬件系统功能部 件的运用、机器指令的选择、各种数据类型变 量的存储空间分配以及寄存器和后缓寄存器的 调度等。
23
24
上述编译过程的六个阶段的任务,再加上用表格
语法分析是编译过程的一个逻辑阶段。
语法分析的任务是在词法分析的基础上将单词序
列组合成各类语法短语,如“程序”,“语句”, “表达式”等等。语法分析程序判断源程序在结 构上是否正确。
源程序的结构由上下文无关文法描述。语法分析
程序可以用YACC等工具自动生成。
10
语法分析器的两个重要作用: ①根据词法分析器提供的记号流,为语法正 确的输入构造分析树(或语法树)。 ②检查输入中的语法(可能包括词法)错误, 并调用出错处理器进行适当处理。 下图是语法分析器在编译器模型中的位置:
式生成代码的,这种语言的编译程序至少分成两遍才容易
生成代码。另外机器的情况,即编译程序工作的环境也影 响编译程序的遍数的划分。一个多遍的编译程序可以较之
一遍的编译程序少占内存,遍数多一点,整个编译程序的
逻辑结构可能清晰些,但遍数多即意味着增加读写中间文 件的次数,势必消耗较多时间,显然会比一遍的编译要慢。
27
在实际的编译系统的设计中,编译的几个阶段的工作究竟
应该怎样组合,即编译程序究竟分成几遍,参考的因素主 要是源语言和机器(目标机)的特征。
比如源语言的结构直接影响编译的遍的划分; 像PL/1或
ALGOL68那样的语言,允许名字的说明出现在名字的使 用之后,那么在看到名字之前是不便为包含该名字的表达
高级语言书 写 的 程 序 (源程序) 编译程序 低级语言程序 (目标程序)
编译程序的重要性体现在它使得多数计算 机用户不必考虑与机器有关的烦琐细节,
使程序员和程序设计专家独立于机器。这
对于当今机器的数量和种类持续不断地增 长的年代尤为重要。
4
1.2编译过程和编译程序的结构
编译程序完成从源程序到目标程序的翻译工作,
语法分析的依据:语言的语法规则。
每种程序设计语言都有描述程序语法结构的规
则。例如,Pascal程序由程序块(又叫分程序) 构成,程序块由语句组成,语句由表达式组成, 表达式由记号组成等等。这些规则可以用上下 文无关文法或BNF范式(Backus-Naur Form) 描述。
15

具有集体含义。如:标识符、保留字(关键字
或基本字)、算符、界符等。
7
例. 某源程序片断如下: begin var sum , first , count : real ; sum := first + count * 10 end. 词法分析阶段将他们组成如 右图的单词序列.(注意:程 序代码中的空格在编译时 被过滤.) 如果使用id1,id2,id3分别表示 sum ,first ,count经过分 析后:sum := first + count * 10则表示为 id1:=id2+id3*10
本课程的考核:
平时作业:20% 平时考勤:10% 实验考核:20% 期末考试(闭卷):50%
2
第一章
引论
1.1 什么是编译程序? 从功能上看,一个编译程序就是一个语言翻译程序, 它把一种语言(称作源语言)书写的程序翻译成另一种 语言(称作目标语言)的等价的程序。 比如汇编程序是一个翻译程序,它把汇编语言程序翻 译成机器语言。如果把编译程序看成是一个“黑盒 子”,它执行的转化工作如下图:
17
又比如某些语言规定运算对象可以被强制,那么当二目运算
施于一整型和一实型对象时,编译程序将整型转化为实型而 不认为是源程序的错误,假如语句sum := first + count * 10中* 的两个运算对象: count是实型,10是整型,则在 语义分析阶段进行类型审查之后,在语法分析得到的分析 树上增加一语义处理结点,表示整型转化实型的一目运算 符inttoreal,其树如下:
19
20
5.代码优化
代码优化阶段的任务是对前阶段产生的中
间代码进行变换或进行改造,目的是使生 成的目标代码更为高效,即省时间和省空 间,或两者都有。
21
依据优化所涉及的程序范围,又可分为局部优化、 循环优化和全局优化三个不同的级别。
22
6.目标代码生成
目标代码生成阶段的任务是把中间代码变换成
16
3.语义分析
语义分析阶段的任务是审查源程序有无语义错误,为
代码生成阶段收集类型信息。比如,语义分析的一个 工作是进行类型审查。源程序中有些语法成分,按照 语法规则去判断,它是正确的,但它不符合语义规则。 比如使用了没有声明的变量;或者给一个过程名赋值; 或者调用函数时参数类型不合适或者参加运算的两个 变量类型不匹配等等。比如下边的程序片段: int arr[2],c; c = arr1 * 10 ; 其中的赋值语句是符合语法规则的,但是因为没有声 明变量arr1,而存在语义错。
(2) 语法树(syntax tree) 如果分析程序确实生成了语法树,它的构造通常
为基于指针的标准结构,在进行分析时动态分配 该结构,则整棵树可作为一个指向根节点的单个 变量保存。结构中的每一个节点都是一个记录, 它的域表示由分析程序和之后的语义分析程序收 集的信息。例如,一个表达式的数据类型可作为 表达式的语法树节点中的域。有时为了节省空间 ,这些域也是动态分配或存放在诸如符号表的其 他数据结构中,这样就可以有选择地进行分配和 释放。实际上,根据它所表示的语言结构的类型 (例如:表达式节点对于语句节点或声明节点都 有不同的要求),每一个语法树节点本身都可能 要求存储不同的属性。在这种情况下,可由不同 的记录表示语法树中的每个节点,每个节点类型 只包含与本身相关的信息。
1.3 解释程序和一些软件工具
1.3.1解释程序 为了实现在一个计算机上运行高级语言的程序,主要有两个途径: 第一个途径是把该程序翻译为这个计算机的指令代码序列,这就是我
们已经描述的编译过程。
第二个途径是编写一个程序,它解释所遇到的高级语言程序中的语句
并且完成这些语句的动作,这样的程序就叫解释程序。从功能上说, 一个解释程序能让计算机执行高级语言。它与编译程序的主要不同是 它不生成目标代码,它每遇到一个语句,就要对这个语句进行分析以 决定语句的含义,执行相应的动作。
又如一个C源程序片断: int a; a = a + 2; 词法分析后可能返回: 单词类型 保留字 标识符(变量名) 界符 标识符(变量名) 算符(赋值) 标识符(变量名) 算符(加) 整数 界符 单词值 int a ; a = a + 2 ;
2.语法分析(Syntax analysis或Parsing)
是一个复杂的整体的过程。从概念上来讲,一个 编译程序的整个工作过程是划分成阶段进行的, 每个阶段将源程序的一种表示形式转换成另一种 表示形式,各个阶段进行的操作在逻辑上是紧密 连接在一起的。
一般一个编译过程划分成词法分析、语法分析、
语义分析、中间代码生成,代码优化和目标代码 生成六个阶段,这是一种典型的划分方法。
5
编译程序的结构
源程序
词法分析器
单词符号
语法分析器
表 格 管 理
语法单位
语义分析与中间代码产生器
中间代码
出 错 处 理
优化器
中间代码
目标代码生成器
目标代码
1.词法分析
功能:从左到右读入源程序的每个字符,对构成
源程序的字符流进行扫描和分解,从而识别出 一个个单词(也叫单词符号或符号)。 单词:逻辑上紧密相连的一组字符 Nhomakorabea这些字符
管理程序建立变量、常量和过程标识符的说明与 引用之间的信息联系等,用出错处理程序对词法 和语法分析遇到的错误给出在源程序中出错的错 误性质、位置等,可分别由几个模块或程序完成, 它们分别称作词法分析程序、语法分析程序、语 义分析程序、中间代码生成程序、代码优化程序、 目标代码生成程序、表格管理程序和出错处理程 序。从而可给出一个典型的编译程序结构框图, 如图1-3-1所示
程序的结构通常是用递归规则表示的,例如: 表达式的表示: ①任何标识符是表达式。 ②任何常数(整常数、实常数)是表达式。 ③若表达式1和表达式2都是表达式,那么 表达式1+表达式2 表达式1*表达式2 (表达式1) 都是表达式。 类似地语句的表示: ①标识符:=表达式 是语句。 ②while (表达式) do 语句 和 if (表达式) then 语句 else 语句 都是语句。
26

一个编译过程可由一遍、两遍或多遍完成。所谓
“遍”,也称作“趟”,是对源程序或其等价的中间 语言程序从头到尾扫视并完成规定任务的过程。每一 遍扫视可完成上述一个阶段或多个阶段的工作。例如 一遍可以只完成词法分析工作;一遍完成词法分析和 语法分析工作;甚至一遍完成整个编译工作。对于多 遍的编译程序,第一遍的输入是用户书写的源程序, 最后一遍的输出是目标语言程序,其余是上一遍的输 出为下一遍的输入。
1.4 编译器中的主要数据结构
(1) 记号(t o k e n)
当扫描程序将字符收集到一个记号中时,它通常
相关主题