第一章 引论
首先,什么是编译?
将高级语言翻译成汇编语言或机器语言的过程。
在这个过程中,高级语言又称为源语言,汇编语言或机器语言又称为目标语言。
从汇编语言到机器语言的过程叫做汇编。
1.1什么叫编译程序
计算机执行高级语言程序z的步骤是:翻译和执行。
利用翻译程序,先将源语言程序翻译维目标语言程序,再进行执行。
翻译程序主要有两种:编译程序和解释程序。
编译和解释的主要区别:是否产生目标代码。
解释程序
源代码经过解释程序解释执行。
边解释边执行。如python。
编译程序
编译程序是在计算机系统中的位置较接近于“硬件”。
高级语言经过宿主机上的编译程序翻译为目标机上的机器语言程序,运行得到结果。
编译程序主要有四类:
诊断编译程序:
发现错误,帮助排错。不关心效率
优化编译程序:
更关注目标程序效率。
交叉编译程序:
一般来说,宿主机跟目标机是一个机器。 如果一个编译程序产生不同于宿主机的机器语言程序,称为交叉编译程序。
可变目标编译程序
只要改变和目标机有关的部分,就可以生成适应不同的平台的程序。
1.2编译过程概述
编译的工作过程:词法分析,语法分析,语义分析及中间代码产生,优化,目标代码生成。
1.2.1 词法分析
规则:依循构词规则
规则描述工具:正规式和有限自动机(FA)
任务:输入源程序,对构成源程序的字符串进行扫描和分解,识别出一个个的单词符号,如基本字(语言提前规定好的有特殊含义的单词,也叫关键字)、标识符、常数、算符、界符等。将识别出的单词转换成统一的机内表示——词法单元(token)形式。
1.2.2 语法分析
规则:依循语法规则
规则描述工具:上下文无关文法
任务:在词法分析的基础上,根据语言的语法规则,对单词符号串进行语法分析,识别出各类语法单位(语法范畴),最终判断输入串是否构成语法上正确的“程序”。
1.2.3 语义分析和中间代码产生
规则:语义规则
规则描述工具:属性文法
任务:对语法分析器识别出的各类语法单位,分析其含义并进行初步翻译(产生中间代码)。
中间代码:一种独立于具体硬件的记号系统,更接近于机器代码 。如三元式,四元式,分析树,…
四元式:
序号作为标识。第一元表示运算符,第二元表示第一操作数,第三元表示第二操作数,第四元表示结果
大致可以分为两个工作部分:
1、对每种语法范畴进行静态语义检查
2、若语义正确,则进行中间代码翻译
1.2.4 优化
规则: 等价变换规则(变换前后的程序在功能上是完全等价的)
任务:对中间代码进行加工变换,以期在最后阶段能产生出更为高效(省时间和空间)的目标代码。
主要包括:
公共子表达式的提取、循环优化、删除无用代码等。
示例:
1.2.5 目标代码生成
任务:把中间代码变换成特定机器上的低级语言代码,实现最后的翻译
目标代码三种形式:
绝对指令代码: 可直接运行 (指令的地址部分是绝对的地址,即变量在存储单元的地址是定好的,可以调到内存直接执行)
可重新定位指令代码: 需要连接装配(地址是相对地址,可从内存中的任意位置进行装载。相对地址+装入的起始地址=绝对地址,称为链接)
优点:支持模块化开发,模块独立编译,模块之间互相链接,装配。
汇编指令代码: 需要进行汇编
1.2.6 编译前端与后端
1.3编译程序的结构
1.3.1 编译程序总框
1.3.2表格和表格管理
作用:解决各类地址到存贮地址上的映射
表格的作用:
登记源程序的各类信息和编译各阶段的进展状况。
常见的表格:
符号名表,常数表,标号表,入口名表,过程引用表。
1.3.3 出错处理
任务:设法发现错误,并把有关错误信息报告给用户
语法错误:源程序中不符合语法/词法规则的错误。
如:非法字符,括号缺失不匹配。
词法/语法分析时检测
语义错误:源程序中不符合语义规则的错误。
如:说明错误、作用域错误、类型不一致、…
语义分析/运行时检测出来
1.3.4 遍
对源程序或源程序的中间结果从头到尾扫描一次,并作有关的加工处理,生成新的中间结果或目标程序。
编译过程划分的阶段仅仅是逻辑功能上的一种划分,具体实现时,受各方面(如源语言、设计要求等)限制,往往组织成若干遍。
在每一遍扫描中完成不同的任务。单遍代码不太有效。
当一遍中包含若干阶段时,各阶段的工作是穿插进行的 。
1.3.5编译的前端和后端
从总框架看出,优化之前包括它的一部分都与源语言有关,之后的部分与目标机有关。所以根据中间语言将编译分为前端和后端。
优点:
程序逻辑结构更清晰
优化更充分
有利于编译程序移植(若前端不变,变后端)
体现,分解和权衡两种计算机思维
1.4编译程序与程序设计环境
程序设计环境:
编辑程序
编译程序
连接程序
调试工具
1.5编译程序的生成
1.5.1以机器语言和汇编语言为工具
1.5.2高级语言书写
利用已有的某种语言的编译程序实现另一语言的编译程序。
P1是可以直接在A机器上运行的,L1语言的编译器
有L1语言的编译器,就可以利用L1语言来写编译程序。
1.5.3移植方法
1.5.4自编译方式
通过自展途径而形成编译程序的方法叫做自编译过程。
如果需要一个L语言的编译程序,方法如下:
先对L语言的核心部分L1构造一个小的编译程序。L1相对简单,没有高级语言可以用低级语言实现。
之后以L1为工具,开发能够编译,翻译更多语言成分(比如L1+L2)的更复杂一点的编译程序。
不断拓展下去,最后能形成你所期望的整个L语言的编译程序。