480 likes | 701 Views
编译原理. 西安电子科技大学 计算理论与技术研究所 田聪 c.tian.xdu@gmail.com. 课程简介. 程序设计语言 C, C++, Java, … 语法有相似处,也有不一样的地方 都属于高级语言 计算机只能识别低级的机器语言. 高级程序设计语言. C. C++. Java. 处 理 过 程. 处 理 过 程. 处 理 过 程. 处 理 过 程. 编译 (解释). 计算机能够识别的语言. 2. 课程简介. 翻译. 汉语普通话. 课程简介. 高级程序设计语言. C. C++. Java. My PL.
E N D
编译原理 西安电子科技大学 计算理论与技术研究所 田聪 c.tian.xdu@gmail.com
课程简介 程序设计语言C, C++, Java, … 语法有相似处,也有不一样的地方 都属于高级语言 计算机只能识别低级的机器语言 高级程序设计语言 C C++ Java 处 理 过 程 处 理 过 程 处 理 过 程 处 理 过 程 编译 (解释) 计算机能够识别的语言 2
课程简介 翻译 汉语普通话
课程简介 高级程序设计语言 C C++ Java My PL 处 理 过 程 处 理 过 程 处 理 过 程 处 理 过 程 处 理 过 程 编译 (解释) 计算机能够识别的语言
课 程 简 介 介绍编 译器的 原理和 基本实 现方法 5
课 程 简 介 目标: 能够自己定义一个程序设计语言 并实现该语言的编译器
课程简介 • 相关知识点 • 程序设计基础:程序设计基本结构、算法与问题求解、基本数据结构、递归、事件驱动程序设计 • 程序设计语言(PL):程序设计语言概论、虚拟机、语言翻译简介、声明和类型、抽象机制、面向对象程序设计、函数程序设计、语言翻译系统、类型系统、程序设计语言的语义、程序设计语言的设计
课程简介 • 效果 • 了解PL的基本要素、工作原理、语言翻译的基本方法 • 用不同的PL进行程序设计,即自学计算机语言的能力 • 课程特点 • 提高自学能力; • 理论与实践并重; • 理论的演变是缓慢的、理论基础是相通的; • 相同的原理可应用于不同的技术; • 适应飞速变化的技术的根本是注重基础理论学习。
课程简介 • 教材 • 刘坚 编译原理基础 西电出版社 • 参考书目 • A. V. Aho, M. S. Lam, R. Sethi, and J. D. Ullman, Compilers: Principles, Techniques, and Tools , 2nd edition, Addison-Wesley, 2007 • Aho等,编译原理技术与工具,人民邮电出版社 • 陈意云、张昱,编译原理,高等教育出版社,2008 • Hopcroft等,自动机理论、语言和计算机导论,机械工业出版社(中英文)
课程简介 • 学习方法 • 预习 • 作笔记 • 多思考,勤发问 • 多实践、以用促学 • 合理使用参考解答 • 作业与上机 • 课后作业+随堂练习(上课要求带课本) • 上机作业:验收上机题,并交上机报告
往届学生报告 编译原理是四大天书中的天书,事实上没有那么恐怖。 第二、三章只要多看书,勤做作业,学好也不难。第四、五章尽管没有涉及算法,但是它与程序的运行方面有很大关系,理解起来比较吃力。 由于平时编程方面的欠缺,对于程序如何组织,如何编写,总感觉无从下手。
往届学生报告 函数绘图语言采用的分析方法是递归子程序,优点是分析方法非常简单易懂,但涉及到大量栈存储空间操作,大大降低了分析的效率。 实际中的编译器和解释器的构造方法通常采用自动化工具(Lex/Yacc),其语法分析大部分采用LALR(1)文法,其驱动器具有通用性,与文法无关,效率高,但分析表十分复杂,难于手工构造。
第一章 引言 1.1 从面向机器的语言到面向人类的语言 • 面向机器的语言:机器指令、汇编语言 • 面向人类的语言:通用程序设计语言、非过程式语言 • 计算机语言举例 [例1]通用程序设计语言与汇编语言(包括机器指令) Pascal语句: x := a+b; C++语句: x = a+b; 汇编指令: 十六进制代码汇编指令 A10002 MOV AX, [A] 8B1E0202 MOV BX, [B] 01D8 ADD AX, BX A30402 MOV [X], AX
1.1 从面向机器的语言到面向人类的语言 [例2]SQL:查询003号学生所选课程与成绩 SELECT 学号, 姓名, 课程名, 成绩 FROM 学生, 选课 WHERE 学生.学号="003"; 对吗?
1.1 从面向机器的语言到面向人类的语言 [例3] Lex和Yacc Lex的正规式:char(char|digit)* return id Yacc的产生式:E : E '+' E | E '*' E | id [例4]Unix的shell命令 SHELL=/bin/sh # include env_precomp.mk CPDIR = /u/pbsrc/chp ORAHOME = /oracle/app/oracle/product/734 .....
1.1 从面向机器的语言到面向人类的语言 • 按范型划分的程序设计语言 • Simple Procedural Languages:FORTRAN C • Block-Structured Procedural Languages:Pascal • Object-Based Languages:Ada C++ Smalltalk • Functional Languages:LISP ML • Logic Programming Languages:Prolog CC2002-PL • 过程式语言、面向对象语言:通用程序设计语言,如FORTRAN、Pascal、C/C++、Ada83/Ada95、Java等; • 函数语言:面向特点领域的、递归特性,如Lisp; • 说明性、非算法式语言:浓厚的数学特征,如LEX/YACC、SQL等; • 脚本式语言:仅是一种安排,没有复杂的逻辑关系,如shell语言,XML等。
1.1 从面向机器的语言到面向人类的语言 • 其他面向特定应用领域的语言 • 计算机辅助设计:MATLAB • 集成电路设计:VHDL、Verilog • 虚拟现实与人机交互:VRML • …… 问题:如何将形形色色的语言翻译成可以在计算机上运行的0、1串?
1.2 语言之间的翻译 习惯称法 • 汇编语言-机器指令:汇编(或交叉汇编) • 程序设计语言-汇编语言或机器指令:编译(或解释) • 高级语言之间:转换(或预编译) • 逆向:反汇编、反编译
编译器 源程序 目标程序 源程序 解释器 输出 输入数据 目标程序 输入数据 输出 编译器 目标程序 P P 解释器 x=3 目标程序 3 x=3 3 1.3 编译器与解释器 • 语言翻译的两种基本形态 先翻译后执行 边翻译边执行 [例5]假设有源程序P:x=3;
编译器 源程序 目标程序 源程序 解释器 输出 输入数据 目标程序 输入数据 输出 1.3 编译器与解释器 • 特点 • 编译器:工作效率高,即时间快、省空间;交互性与动态特性差、可移植性差。被大多数PL的翻译所采用; • 解释器:工作效率低,即时间慢、费空间;交互性与动态特性好、可移植性好。早期的Basic和现在的Java等。 • 基本功能:二者相同; • 采用技术:从翻译的角度来讲,两种方式所涉及的原理、方法、技术相似。
1.4 编译器的工作原理与基本组成 • 通用程序设计语言的主要成份 • 从语言抽象的演变看: 过程→抽象数据类型(ADT,程序包)→ 类 • 共同特点:两大部分组成,声明+操作=完整定义 • 以过程式语言为例: • 声明性语句:提供操作对象的性质,如数据类型、值、作用域等; • 操作性语句:确定操作的计算次序,完成实际操作。 • 过程头+过程体=过程定义 • 编译器对两类语句的翻译: • 声明:生成相应的环境,一般是配置存储空间; • 操作:生成可执行的代码序列。
1.4 编译器的工作原理与基本组成 [例6] 一Pascal的过程如下: (1) procedure sample(y: integer); {过程头} (2) var x : integer; {过程体(开始)} (3) begin x := y; (4) if x>100 then x := 0 (5) end; {过程体(结束)} (1):声明,提供调用信息,如过程名、参数、返回值等。(接口) (2)至(5):过程体,可含声明或操作。(实现)。 编译器对声明性语句的处理一般是生成相应的环境(存储空间),对操作性语句则是生成此环境中的可执行代码序列。 为便于编译器的处理,操作性语句中使用的每个操作对象,均应在使用前声明,即符合先声明后引用的原则。
1.4 编译器的工作原理与基本组成 • 以阶段划分编译器 • 自然语言的翻译过程: • 识别单词 • 识别句子结构 • 理解意思 • 译成中文并修饰 • 编译器的工作过程: • 词法分析 • 语法分析 • 语义分析 • 目标代码生成 • 编译器的阶段(逻辑模块) • 中间代码的重要作用
1.4 编译器的工作原理与基本组成 C语言赋值语句: position = initial + rate 60
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 本章小结
1.7 作业 • 解释下列名词 • 源语言、目标语言、翻译器、编译器、解释器 • 典型的编译器可以划分成几个主要的阶段?各阶段的功能是什么?