编译过程大概的过程为:
没错,编译程序的过程就是一个IPO过程,那么具体的过程则为:
词法分析
词法分析,就是依据语言构词规则,从输入的源程序(字符串)中识别出一个个单词(符号)。
首先,单词的种类有:
- 关键字:for if while
- 运算符:+ - × /
- 分割符: , ;() { }
- 标识符:a1 a2 pi
- 常数: 9 1024 4.8 6E6
其中,前三个为有穷集合(程序设计语言确定了,那么这些就确定了),后三个则为无穷集合。
词法分析工作由词法分析器完成,又称扫描器(scanner)。词法分析器输出为等长度的单词符号串。
例如,给定如下输入:
position = initial + rate * 60
词法分析器将识别出7个单词符号
position, =, initial, +, rate, *, 60
语法分析
依据语言的语法规则,把词法分析器提供的单词符号组合成各种语法单位(语法范畴),如“短语”、“句子”、“分程序”、“程序”等。
方法则是:语法分析器利用输入的单词符号创建一棵语法树(syntax tree),同时进行语法检查。
语义分析与中间代码产生
针对各类不同的语法范畴,按语言的语义规则进行语义分析(检查)和初步翻译工作,产生某种形式的中间代码(即一种结构简单、含义明确的记号系统)
通常包括两个方面的工作:
- 静态语义检查
- 代码翻译
其中,静态语义检查中最重要的是类型检查,如一个int类型的常数与一个double类型的变量做加法,编译器可能会将int类型的常数进行类型提升至double类型,或者直接报错。
而代码翻译部分则常用的是将代码翻译成四元式序列:
优化
对前阶段产生的中间代码进行加工变换,以期在最后阶段能产生出高效(节省时、空)的目标代码,这一任务是由优化器来完成的。
目标代码生成
把中间代码翻译成目标代码,如汇编代码或机器代码。这一过程涉及到内存管理、寄存器调度、指令选择等工作,因此与计算机系统的体系结构、CPU指令集、OS等密切相关。
编译过程的前端和后端
为了便于设计,通常将编译程序的五个阶段进一步划分为前端和后端:
- 前端:主要由与源语言有关而与目标机无关的部分组成,包括词法分析、语法分析、语义分析和中间代码产生。与目标机无关的代码优化一般也包含在前端。
- 后端:主要由与目标机有关的部分组成,包括目标代码生成和与目标机有关的优化等。
划分的好处
划分前端和后端,就可以仅改写后端而生成不同目标机上的目标程序,当然也可考虑对不同语言仅稍加改变前端而产生相同的中间代码,经同一后端生成相同目标机的目标代码。
典型的便是Java的虚拟机,实现一个程序多处执行,便是只修改了后端部分以适配不同的机型。