编译简介
编译由两部分组成:分析与综合。
分析部分将源程序切分成一些基本块并形成源程序的中间表示,综合部分把源程序的中间表示转换为所需的目标程序。
在分析期间,源程序所蕴含的操作将被确定下来并被表示成为一个称为语法树的分层结构。语法树的每个节点表示一个操作,该节点的子节点表示这个操作的参数。
###编译器的前驱与后继###
预处理器:源程序可能被分成模块存储在不同的文件中。把存储在不同文件中的程序模块集成为一个完整的源程序这个任务一般由预处理器的程序去完成。预处理器也能够把源程序中称为宏的缩写语句展开为原始语句加入到源程序中。
###源程序分析###
在编译中,源程序的分析由如下三个阶段组成:
1、线性分析(词法分析)。在线性分析中,从左到右地读构成源程序的字符流,而且把字符流分组为多个记号(token),而记号是具有整体含义的字符序列。
2、层次分析(语法分析)。在层次分析中,字符串或记号在层次上划分具有一定层次的多个嵌套组,每个嵌套组具有整体的含义。
3、语义分析。在语义分析中要进行某些检查,以确保程序各个组成部分确实是有意义地组合在一起的。
###编译的各个阶段###
编译器的一个基本功能室记录源程序中使用的标识符并收集每个标识符的各种属性信息。标识符的属性信息表明了该标识符的存储位置、类型、作用域(在哪段程序中有效)等信息。当一个标识符是过程名时,它的属性信息还包括诸如参数的个数与类型、每个参数的传递方法(如传递地址方式)以及返回值的类型等信息。
1、符号表管理:符号表是一个数据结构。每个标识符在符号表中都有一条记录,记录每个域对应于该标识符的一个属性。这种数据结构允许我们快速地找到每个标识符的记录,并在该记录中快速的存储和检索信息。
2、错误检测与报告:语法分析和语义分析阶段通常能够处理编译器所能检测到的大部分错误。
词法分析阶段能够检测出输入中不能形成源语言任何记号的错误字符串。语法分析阶段可以确定记号流中违反源语言结构(语法)规则的错误。语义分析阶段试图检测出具有正确的语法结构但对操作无意义的部分。
3、各分析阶段。
4、中间代码生成。
某些编译器在完成语法分析和语义分析以后,产生源程序的一个显式中间表示。我们可以将这种中间表示看成是某种抽象机的程序。源程序的中间表示应该具有两个重要性质。一是易于产生,二是易于翻译成目标源程序。
5、代码优化。
6、代码生成。
###编译器的伙伴###
1、预处理器。预处理器产生编译器的输入,一般具有以下功能:
(1)、宏处理。预处理器允许用户在源程序中定义宏。宏是被经常使用的较长结构的缩写。
(2)、文件包含。预编译器可以把头文件包含到程序正文中。
(3)、“理性”预处理器。这些处理器能把现代控制流和数据结构化机制添加到比较老式的语言中。例如:如果一种语言没有while语句和if语句这样的控制结构,理性预处理器可以用内部宏定义向用户提供这样的控制结构。
(4)、语言扩充。这类处理器通过大量的内部宏定义来增强语言的能力。
宏处理器处理两种类型的语句:宏定义和宏引用。
宏定义由具有惟一性的字符或者关键字来标识,如define或macro。宏定义包含被定义的宏的名字或构成其定义的体。通常,宏处理器允许宏定义中包含形式参数。宏的引用只需要提供宏名和实际参数。
2、汇编器
某些编译器产生汇编代码。汇编代码需要交给汇编器做进一步处理,有些编译器能够完成汇编器的工作,产生可重定位的机器代码,交给装配器(Loader)或链接编辑器(Link-editor)。
3、两遍汇编
最简单的汇编器对输入汇编源程序文件进行两遍扫描,每遍读输入文件一次。在第一遍扫描中,表示存储单元的所有标识符都被识别出来并出入符号表(汇编器的符号表和编译器的符号表是分开的)。一个标识符的存储单元式在它在第一次被遇到时分配的。
在第二遍扫描中,汇编器再一次从头扫描输入文件。这一次它将每个操作符翻译成机器语言中代表相应操作的二进制位序列,将代表存储单元的每个标识符 翻译成符号表中该标识符的地址。
第二遍扫描的输出时刻重定位的机器代码。可重定位指的是装入的起始地址可以使任意的内存单元L。也就是说,如果将L加到代码的所有地址上,整个程序对所有存储地址的引用都是正确的。为此,汇编器的输出必须说明哪些指令中引用了可重定位地址。
4、装配器和连接编辑器
通常,装配器完成程序的装入和连接编辑两项功能。装入过程包括读入可重定位机器代码,修改可重地位地址,并将修改后的指令和数据放到内存中适当的位置。
连接编辑器允许我们将多个可重定位机器代码的文件组装成一个程序。这些可重定位机器代码的文件可以使多次编译的结果,其中一个或多个可能是库程序文件。库程序文件时由系统提供的,可以被任何程序使用。
###编译器各个阶段分组###
1、前端与后端
编译器可以分为前端和后端两个大的阶段。前端依赖于源语言并在很大程度上独立于目标机器的某些阶段或者某些阶段的某些部分。前端一般包括词法分析、语法分析、符号表建立、语义分析、中间代码生成以及相关的错误处理。相当一部分的代码优化工作也在前端完成。
后端包括编译器中以来目标机器的阶段或某些阶段的某些部分。一般来说,后端完成的任务不依赖于源语言而只依赖于中间语言。后端主要包括代码优化、代码生成以及相关的错误处理和符号表操作。
2、编译器的遍
3、减少编译的遍数
###编译器的构造工具###
1、分析生成器。
2、扫描生成器。
3、语法制导翻译引擎。
4、自动代码生成器。
5、数据流引擎。