1. 词法分析Lexical Analysis
从左到右一个字符一个字符的读入源程序,对构成源程序的字符串进行扫描和分解,从而识别出一个个单词(也称单词符号或简称符号)
例如某源程序片段如下:
var
sum, first, count :real ;
begin
sum := first + count * 10 ;
end.
词法分析阶段通过对该程序片段的扫描、分解,将会把组成这段程序的字符识别为如下单词序列:
1.保留字 var 2.标识符 sum 3.逗号 , 4.标识符 first 5.逗号 , 6.标识符 count 7.冒号 : 8.保留字 real 9.分号 ; 10.保留字 begin 11.标识符 sum 12.赋值号 := 13.标识符 first 14.加号 + 15.标识符 count 16.乘号 * 17.整数 10 18.保留字 end 19.界符 .
我们用id1,id2和id3分别表示sum, first和count三个标识符的内部形式,那么分析后, sum:= first + count * 10 可表示为: id1:= id2 + id3 * 10
2. 语法分析Syntax Analysis
在词法分析的基础上将单词序列分解成各类语法单位,如“表达式” ,“语句”,“分程序”,“程序” 等等,例如,上例中的赋值语句通过语法分析可用以下语法树( Parse tree )表示出来。
3. 语义分析Syntactic Analysis
语义分析是在语法分析程序确定出语法单位后,审查有无语义错误,并为代码生成阶段收集类型信息。
(1)语法分析和语义分析是以密切合作的方式工作的。
(2) 语义分析的重要工作之一是进行语义检查,并为代码生成收集类型信息(类型检查、变量是否声明、类型是否一致、变量是否已有值等)。
4. 中间代码生成Generation of intermediate code
完成语法分析和语义处理工作后,编译程序将源程序变成一种内部表示形式,这种内部表示形式叫做中间语言或称中间代码,它是一种结构简单、含义明确的记号系统。
例如,四元式的形式为:
(算符,运算对象1,运算对象2,结果)
对于赋值语句:position:= initial + rate * 60
可以生成如下所示的四元式:
5. 代码优化 Optimization of code
为了使生成的目标代码更为高效,可以对产生的中间代码进行变换或进行改造,这就是代码的优化。
代码优化工作可以在不同的编译阶段进行,其中对中间代码的优化尤其重要。
对于前面提到的四元式,优化后:
6. 代码生成 Generation of code
目标代码生成阶段的任务就是是把中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码。
对于上面所述源程序:position :=initial +rate * 60对应的中间代码可生成下面的某汇编代码:
编译器生成的目标程序代码可以有多种形式:
- 汇编语言形式
- 可重定位二进制代码形式
- 内存形式
7. 符号表
主要应用于以下情况:
- 收集符号的属性信息
当分析到标识符的说明部分时,收集有关标识符的属性,并存于符号表中; - 作为进行语法的合法性检查的依据
同一个标识符可能在程序的不同地方出现,有关符号的属性是在不同的情况下收集的,需要检查标识符在上下文中的一致性和合法性,而符号表正是进行这种检查的依据; - 作为目标代码生成阶段地址分配的依据
每个变量在目标代码生成时都需要确定其对应的存储地址,编译程序在完成了对变量的地址分配后,将其存于符号表中,可以通过符号表获取每个变量对应的存储地址。
8. 错误检测
源程序中常常存在各种各样的错误:即使对一个熟练的程序员来说,也很难做到一次上机就能得到预期的结果。所以,对于源程序错误处理的程度,是作为衡量一个编译程序良莠的主要标准之一。一个好的编泽程序应将源程序中的错误尽可能多地诊察出来,如果有可能的话,对错误进行适当的校正。这样就可以使程序员及时发现和改正错误,从而减少上机编译的次数,以节约机时,节省费用;
错误检测处理与符号表管理工作一样,贯穿整个编译过程。