第1章 引论
1.1 什么是编译程序
编译程序就是编程语言的翻译程序,将高级程序语言编写的代码翻译成机器能够执行的机器代码。
1.2 编译过程和编译程序的结构
1.2.1 编译过程概述
典型的编译过程划分为词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成6个阶段。
- 词法分析
从左到右读入源程序,识别出一个个的单词,如标识符、保留词、算符、界符等。- 语法分析
在词法分析的基础上将单词序列分解为各类语法短语,如程序、语句、表达式等。可以表生成语法树的形式。- 语义分析
语义分析是审查源程序有无语义错误,为代码生成阶段收集类型信息。- 中间代码生成
中间代码是一种结构简单、含义明确的记号系统,重要的设计原则有两点:容易生成和容易翻译成目标代码。很多翻译程序采用了一种近似“三地址指令”的“四元式”的中间代码,形式为(运算符,运算对象1,运算对象2,结果)。- 代码优化
对中间代码进行变化和改造,目的是使生成的目标代码更为高效。如公共子表达式的删除、强度削弱、循环优化等。- 目标代码生成
把中间代码变换成特定机器上的绝对指令或可重定位的指令代码或汇编指令代码。该阶段与硬件系统结构和指令含义有关。
上述的阶段的划分是一个典型的逻辑划分,在实际的程序中并不一定所有的都需要。
1.2.2 编译程序的结构
编译程序除了上述六个组成部分以外,还有表格管理和出错处理程序,这两个程序与上述6个阶段都有联系。
表格处理程序相当于一个小型的数据库,存放程序整个编译程序处理过程中的各种数据。
1.2.3 编译阶段的组合
编译的过程又可以被分为前端和后端,前端的工作主要依赖于源语言而与目标机没有关系。后端指的是依赖于目标机而一般不依赖于源语言的工作。
有点类似于软件开发中的前后端分离,这样同一个前端,配备多个后端,就可以为一种语言生成多种机器语言。
1.3 解释程序和一些软件工具
1.3.1 解释程序
解释程序不需要在运行前先把源程序翻译成目标代码。它的工作模式是一个个的获取、分析并执行源程序语句,执行结束立马会有结果,适合交互工作方式。
python就是解释型语言,而java、C都是编译型语言。
程序的解释非常慢,有时一个高级语言源程序的解释会比运行等价的机器代码程序慢100倍。当运行速度非常重要时,是不能采用解释方式的。另外,解释语言的空间开销也很大。
解释语言的好处是编写的程序易于调试。
1.3.2 处理源程序的软件工具
语言的结构化编辑器
语言程序的调试工具
程序格式化工具
语言程序测试工具
程序理解工具
高级语言之间的转换工具
这些工具很多集成开发环境里面就有。
1.4 PL/0 语言编译系统
PL/0 语言编译系统是将PL/0源程序语言转化为类P-code的目标语言。本书给出的此编译程序的编程语言是C语言。
对PL/0和类P-code语言不太了解。百度上说PL/0是pascal的一个子集。
1.4.1 PL/0语言编译系统构成
PL/0语言编译系统由编译程序和解释程序两部分组成,分别称为PL/0编译程序和类P-code解释程序。PL/0语言程序被PL/0编译程序转换为等价的类P-code程序,当编译程序正常结束时,PL/0语言编译系统会调用解释程序,解释执行所生成的目标程序。
PL/0的编译程序并不是直接编程机器代码,而是编译成了类P-code代码,这个类P-code代码还需要解释程序解释才能执行。
1.4.2 PL/0 语言
PL/0语言的是Pascal的一个子集。
实践中,程序语言的语法描述常采用一种称为扩展巴克斯范式(EBNF)的形式来描述。
ENBF是描述程序语法的,也是是该语言构造程序遵循的规则。
1.4.3 类P-code语言
类P-code语言可看成是类P-code虚拟机的汇编语言。
类P-code虚拟机是一种简单的纯栈式结构的机器,有一个栈式存储器,有4个控制寄存器。
类P-code程序运行期间的数据存储和算术及逻辑运算都在栈顶进行。类P-code虚拟机的指令格式如下:
F L A
F表示指令的操作码;L:起作用表示引用层与声明层之间的层次差,不起作用置为0; A:不同的指令含义不同。
类P-code类似汇编语言。直接在寄存器上进行操作。
1.4.4 PL/0 编译程序
PL/0编译程序采用单遍扫描方式的编译过程,由词法分析程序、语法分析程序以及代码生成程序3个独立的过程组成。PL/0编译程序以语法语义分析程序为核心,当语法分析需要读单词时就调用词法分析程序,而当语法语义分析正确生成相应语言成分的目标代码时,就调用代码生成程序。
1.4.5 PL/0语言编译系统的驱动代码
所谓驱动代码,就是程序的主函数,在主函数中将编译程序的各个部分串联起来。