编译原理概述
概述
1.1 什么是编译程序?
编译程序的必要性
- 机器语言:计算机只认识由0和1构成的机器语言,每台机器自己独特的指令系统即机器语言。
- 汇编语言
- 高级语言
- ????
编译程序概念
编译程序最初的定义是把一种高级语言设计的源程序(面向人的)翻译成另一种等价的低级程序设计语言(面向硬件的)即机器语言或汇编语言。
程序设计语言源程序的执行基本有两种方式
- 翻译 使用翻译程序,将源程序翻译成为低级语言目标程序,然后执行目标程序
- 解释 使用解释程序,对源程序逐个语句边解释边执行
可比喻为 译文—目标程序
- 翻译—笔译 (产生译文,可进行优化,一次翻译过后,多次使用)
- 解释—口译 (不产生译文,交互方便,节省空间,对重复部分要反复解释,效率低)
翻译程序按所处理源语言不同分为两种:编译程序,汇编程序
编译程序和解释程序
- Basic、Lisp、Sql解释程序、Unix命令语言解释程序及很多脚本语言Javascript等都解释执行的。
- C、C++、Pascal等语言是编译执行的。
- Java语言的处理环境既有编译程序,也有解释程序:
Java → 编译程序 → Bytecode →解释程序
编译过程和编译程序的结构
编译过程
编译过程可分为下面5个阶段
- 词法分析:1.分析有没有错别单词,2.输出内部表示(二元式)
- 语法分析:分析代码含义
- 语义分析和中间代码生成:输出中间结果
- 优化:改善目标代码质量
- 目标代码生成
第一阶段 词法分析
任务
- 输入源程序(字符串)
- 根据语言的词法规则对构成源程序的字符串进行扫描和分解
- 识别出一个个的单词
单词内部表示形式: 二元式 (class,value) (单词类型,单词值)
例某C语言源程序
main( ){
float sum,first,count;
…sum=first+count*10;
… }
输出结果
class value
保留字 main
界符-左括号 (
界符-右括号 )
界符-左花括号 {
保留字 float
标识符1-id1 sum
...
算符-乘号 *
整数 10
....
第二阶段 语法分析
任务
- 输入单词符号串
- 根据语言的语法规则对单词符号串进行扫描和分解
- 识别出各类语法单位
程序语言的语法单位:表达式、语句和程序等
例 X1= Y + 10Z;
C语言赋值语句构成规则
<赋值语句> → <标识符> = <表达式>;
<表达式>→<表达式> + <表达式>
<表达式>→<表达式> * <表达式>
<表达式>→<标识符> X1,Y,Z
<表达式>→<常数> 10
可以构成语法单位的单词符号:=,+,,X1,Y,Z,10
语法单位 表达式 Y,10,Z,10Z 赋值语句 X1=Y+10Z;
语法单位内部表示:语法树
例某C语言源程序
main( ){
float sum,first,count;
…sum=first+count10;…
}
<赋值语句>→<标识符>=<表达式>;
<表达式>→<表达式>+<表达式>
<表达式>→<表达式><表达式>
<表达式>→<标识符>
<表达式>→<常数>
第三阶段 语义分析与中间代码产生
任务
- 输入各类语法范畴
- 根据语言的语义规则,分析其含义,并进行初步翻译
- 产生中间代码
中间代码特点:
- 结构简单、含义明确的记号系统
- 介于高级语言与低级语言之间,与目标机无关
- 便于优化、移植,容易生成目标代码
- 形式有:三元式、四元式、树结构等。
例某C语言源程序
main( )
{float sum,first,count;
sum=first +count*10;
… }
中间代码生成(四元式(三地址指令))例:语义分析将 \(sum=first+count*10;\)
翻译成 如下的四元式序列:
(1) (int to float, 10, _, T1 )
(2) ( *, count,T1,T2 )
(3) ( +, first,T2,T3 )
(4) ( =, T3, _, sum)
其中,Ti为语义分析程序为存放中间结果而生成的临时变量
第四阶段 优化
任务
- 输入中间代码
- 进行等价变换
- 输出更高效的中间代码
目的
- 用以提高目标代码的时、空效率
- 也就是希望完成同样功能的程序,代码优化后比优化前运行的时间短,占用的存储空间少
- 有时二者不能同时达到,需根据实际情况取舍
优化后有两条代码:整数转换成实数在编译时完成,临时变量只用了一个T1
第五阶段 目标代码生成
任务
- 输入优化后的中间代码
- 变换成特定机器上的低级语言代码,实现最后的翻译
- 产生目标代码
特点
- 依赖与机器硬件系统
- 通常使用汇编语言作为目标程序的实现语言
为了生成高效的目标代码,需要了解机器指令
系统和可用计算机资源,
假设有两个可用寄存器R0和R1
优化后中间代码:1(,count,10.0,T1) 2(+,first,T1,sum)
生成的目标代码序列
(1) MOV count,R0:count值送R0
(2) MUL R0,#10.0:计算count10.0存于R0#表示立即数
(3) MOV first,R1:first值送R1
(4) ADD R1,R0:计算first+T1存于R1
(5) MOV R1, sum
表格管理和出错处理
表格管理 (符号表管理)
任务
- 在完成以上5个过程的同时
- 必须随时对符号表进行管理
- 记录源程序中使用的名字
收集每个名字的各种属性信息。如类型、作用域、存储分配信息等
例 count 变量 类型 float
first 变量 类型 float 地址
出错处理
任务
发现源程序中的错误
检查词法、语法和语义中的错误(静态)
编译程序的处理能力,如存储空间越界 (动态)
报告出错信息和位置
处理和恢复
编译程序的结构
(7个或8个部分组成)
- 词法分析程序
- 语法分析程序
- 语义分析程序与中间代码产生器
- 优化器
- 目标代码生成器
- 表格管理
- 出错处理
编译阶段的组合
(一)、前端和后端
- 前端 完成分析工作(与机器无关):词法分析、语法分析、语义分析
与机器无关,与源代码有关 - 后端 完成综合工作(与机器相关):优化、目标代码生成
与机器有关,与源代码无关
分为前后端的 目的: 便于移植
(二)、遍: 从头到尾对源程序及其内部表示:扫描一次,并作有关的加工处理
- 从源程序扫描是第一遍输入
- 每前一遍的输出是后一遍的输入
注: 分遍的原则按实际情况而定
- 多遍(结构清晰、少占内存、读写次数多,耗时)
- 一遍(多占内存,速度快)
编译程序在系统软件中的所在层: 操作系统之上,应用软件层之下
文法和语言
2.1 文法的直观概念
2.2 符号和符号串
2.3 文法和语言的形式定义(重点)
2.4 文法的类型
2.5 上下文无关文法及其语法树(重点)
补充实例:小C语言源程序及其文法(重点)
2.6 句型的分析(重点 第5章讲解)
语言(由句子组成的集合,由一组记号所构成)
自然语言(人与人的通信工具)
汉语——所有符合汉语语法的句子的全体。
英语——所有符合英语语法的句子的全体。计算机语言(计算机软件使用的通信工具)
程序设计语言——所有该语言的程序的全体。研究语言
每个句子构成的规律 语法 形式语言
每个句子的含义 语义 形式语义
每个句子和使用者的关系 语用 形式语义
本章目的:为语言的语法描述寻求工具。
(二)、符号串和符号串集合
规则或产生式
文法的定义
(直接)推导和 (直接)归约
句型和句子
文法描述的语言
文法的等价性