250 likes | 431 Views
上机 安排. 1.4 编译器的工作原理与基本组成. C 语言赋值语句: position = initial + rate 60. MOV F id3, R2 MUL F #60.0, R2 MOV F id2, R1 ADD F R2, R1 MOV F R1, id1. C 语言赋值语句: position = initial + rate 60. 符 号 表. 1. position. 2. initial. 词法分析器. 3. rate.
E N D
上机 安排
1.4 编译器的工作原理与基本组成 C语言赋值语句: position = initial + rate 60 MOVF id3, R2 MULF #60.0, R2 MOVF id2, R1 ADDF R2, R1 MOVF R1, id1
C语言赋值语句: position = initial + rate 60 符 号 表 . . . 1 position . . . 2 initial . . . 词法分析器 3 rate id, 1=id, 2+id, 360 1.4 编译器的工作原理与基本组成 字符流 记号流 词法分析:扫描构成源程序的字符流,按词法规则把它们组成记号流
1.4 编译器的工作原理与基本组成 • 记号是一个二元组: <记号名,属性值> • 记号名是同类词法单元公用的名称 • 属性值是一个词法单元有别于同类词法单元的特征值
position = initial + rate 60 符 号 表 . . . 1 position . . . 2 initial . . . 词法分析器 3 rate id, 1=id, 2+id, 360 1.4 编译器的工作原理与基本组成 • 标识符position形成的记号是<id, 1> • id是标识符的总称 • 1代表position在符号表中的条目 • 符号表的条目用来存放标示符的各种属性 • 赋值号=形成的记号是<assign> • 该记号只有一个实例,不需要属性值来区分实例 • 为了直观,记作<=> • 标识符initial形成的记号是<id,2> • 加号形成的记号是<+> • 标识符rate形成的记号是<id,3> • 乘号*形成的记号是<*> • 60形成的记号是<60>
id, 1=id, 2+id, 360 语法分析器 语法树 1.4 编译器的工作原理与基本组成 语法分析按照语言的语法规则检测词法分析输出的记号流是否符合语法规则,并用树的形式描述该记号流的语法结构 记号流
id, 1=id, 2+id, 3 60 符 号 表 . . . 1 position 语法分析器 . . . 2 initial . . . 3 rate = + id, 1 id, 2 60 id, 3 1.4 编译器的工作原理与基本组成 记号流 语法树
1.4 编译器的工作原理与基本组成 语义分析阶段使用语法树和符号表中的信息, 依据语言定义检测源程序的语义一致性,以保 证程序各部分能有意义地结合在一起。 • 语义分析的一个重要内容是类型检查 例如:当实数作为数组下标时,编译器报错 • 运算类型隐式转换 例如:算数运算作用于一个整数和一个实数时, 编译器会把其中的整数转换为实数
符 号 表 . . . 1 position . . . 2 initial 语义分析器 . . . 3 rate = = + + id, 1 id, 1 id, 2 id, 2 60 inttofloat id, 3 id, 3 60 1.4 编译器的工作原理与基本组成 语法树 语法树
1.4 编译器的工作原理与基本组成 • 中间表示需要具备的性质:易于产生,易于翻译成目标程序 • 三地址代码(常用的中间表示) • 三地址代码由三地址指令序列组成,每条指令最多有三个操作数 中间代码生成:将源程序表示为更低级的显式中间表示
= + id, 1 id, 2 符 号 表 inttofloat id, 3 . . . 1 position . . . 60 2 initial 中间代码生成器 . . . 3 rate t1 = inttofloat(60) t2 = id3 t1 t3 = id2 + t2 id1 = t3 1.4 编译器的工作原理与基本组成 语法树 三地址中间代码
t1 = inttofloat(60) t2 = id3 t1 t3 = id2 + t2 id1 = t3 符 号 表 . . . 1 position . . . 2 initial . . . 3 rate 代码优化器 t1 = id3 * 60.0 id1 = id2 + t1 1.4 编译器的工作原理与基本组成 代码优化:试图改进中间代码,以便产生较好 的目标代码 三地址中间代码 三地址中间代码
t1 = id3 * 60.0 id1 = id2 + t1 符 号 表 . . . 1 position 代码生成器 . . . 2 initial . . . 3 rate MOVF id3, R2 MULF #60.0, R2 MOVF id2, R1 ADDF R2, R1 MOVF R1, id1 1.4 编译器的工作原理与基本组成 代码生成:把中间代码映射到目标程序 三地址中间代码 汇编代码
1.4 编译器的工作原理与基本组成 各阶段工作的归纳 • 词法分析:识别单词,并分类:关键字(保留字)、标识符、字面量、特殊符号; • 语法分析:得到语言结构,并以树的形式表示; • 语义分析:考察结构正确的句子是否语义合法,修改树结构; • 中间代码生成(可选):生成一种既接近目标语言,又与具体机器无关的表示,便于优化与代码生成;
1.4 编译器的工作原理与基本组成 • 中间代码优化(可选):局部优化、循环优化、全局优化等;优化实际上是一个等价变换,变换前后的指令序列具有完成相同的功能,但在占用的空间上和程序执行的时间上都更省、更有效。 • 目标代码生成:不同形式的目标代码-汇编; • 符号表管理:合理组织符号,便于各阶段查找、填写等; • 出错处理:错误的种类-词法错、语法错、静态语义错、动态语义错。
1.4 编译器的工作原理与基本组成 • 编译器的分析/综合模式 • 前端:语言结构和意义的分析; • 后端:语言意义处理; • 中间代码:前端与后端的分界;
1.4 编译器的工作原理与基本组成 • 编译器扫描的遍数 每个阶段将程序完整分析一遍的工作模式称为一遍扫描。 确定扫描遍数的因素有: • 软、硬件条件,如内存太小,或全局优化 • 语言结构,如规定标识符的先声明后引用 x := f(a); … function f(a:integer):integer; • 编译技术,如拉链-回填 goto lab1; … lab1: …
1.5 编译器的编写 • 直接使用汇编语言和程序设计语言; • 利用编译器编写工具:词/语法、语法制导翻译、代码生成、数据流分析等; • 基于编译器基础架构的编译器构造系统(开放式编译器,如GCC、SUIF等)。 GCC Home Page. http://gcc.gnu.org. Gasta Homepage. http://gasta.sourceforge.net SUIF Compiler System Home Page. http://suif.stanford.edu
1.6 编译器技术的应用 高级语言的实现 高级编程语言易于编程,但程序运行较慢 低级语言编程时可实施更有效的控制方式,得到更有效的代码,但难编写、易出错、难维护 流行编程语言的大多数演变都是朝着提高抽象级别的方向 每一轮编程语言新特征的出现都刺激编译器优化的新研究
1.6 编译器技术的应用 支持用户定义的聚合数据类型和高级控制流,如数组和记录、循环和过程调用:C、Fortran 面向对象的主要概念是数据抽象和性质继承,使得程序更加模块化并易于维护:Smalltalk、C++、C#、Java 类型安全的语言:Java没有指针,也不允许指针算术。它用无用单元收集机制来自动地释放那些不再使用的变量占据的内存
1.6 编译器技术的应用 针对计算机体系结构的优化 计算机体系结构的迅速演化引起对新的编译器技术一种不知足的需要 并行化 编译器重新整理指令,使得指令级并行更有效 编译器从传统的串行程序自动生成并行代码,使之运行于多处理器上 内存分层 编译器优化历来集中在优化处理器的执行上,但是现在更强调要使内存分层更有效
1.6 编译器技术的应用 程序翻译 二进制翻译 编译器技术可用于把一种机器的二进制代码翻译成另一种机器的代码,以运行原先为别的指令集编译的代码 数据库查询解释器 数据库查询由一些谓词组成,这些谓词由包含关系运算的布尔表达式组成,可以被解释执行,也可以被编译成搜索数据库的命令
1.6 编译器技术的应用 提高软件开发效率的工具 源于编译器中代码优化技术的程序分析一直在 改进软件开发效率 类型检查 类型检查是一种捕捉程序中前后不一致的成熟而有效的技术 边界检查 数据流分析技术可用来定位缓冲区溢出 内存管理 自动的内存管理删除内存泄漏等内存管理错误
语言与语言的翻译 编译器的基本组成 编译器的分析/综合模式(编译器基础架构) 扫描遍数 编译器的编写 1.6 本章小结
课堂练习 • score=exam*0.7+homework*0.3+reward (score, exam, homework为float类型) (reward整型)