编译器的工作原理

参考书籍

北京邮电大学出版社 《计算机软件基础》 秦金磊,李整编著

What’s 编译器

在计算机中,使用高级语言(如python、c++等)写出来的源程序,无法被计算机直接识别,高级语言必须经过翻译变成机器语言后才可被计算机所执行。这时候就要用到翻译器。而翻译器对高级语言翻译的方式一共有两种,分别为编译和解释,对应的翻译程序便称为编译器和翻译器。

高级语言的编译过程可以由下图展示出来

编译过程

编译器的工作原理

编译器的基本工作过程包括六大步骤

步骤一:词法分析

编译器会逐行扫描源代码,并识别符号串,主要为关键字、字面量、标识符(变量名和数据名)、运算符、注释、以及其他的特殊符号等。符号串会根据自身类别被归类并等待下一步的处理。

例如,语句 a = b + c/2中,编译器将语句读入后将会得到记号流 a(id1), =, b(id2), +, c(id3), /, 2。其中分别使用id1,id2,id3来表示实型变量a、b、c,语句中间的空格被省略。

步骤二:语法分析

得到记号流后,编译器中的语法分析器会将其分解成语法短语,如“程序”、“语句”、“表达式”等。这些语法短语可以表示成语法分析树。后根据所用语言的语法对每个分析树进行检查,若合法便以内部格式将其存起来。

语法分析树

步骤三:语义分析

语义分析的主要内容包括以下几个方面:运算符两端的类型是否兼容、该将哪些数据进行类型转换、是否控制转移到不该去的地方、是否存在重名或语义模糊的记号。如果存在上述问题则会进行处理,反之产生中间代码。

例如,步骤一中的那个例子中,a、b、c都是实型变量,而2是整型常量,在运算过程中需要将2转化为实型变量,再进行运算。

步骤四:生成中间代码

中间代码是源代码向目标代码转换过程中的一种过渡编码。其形式会尽可能与机器的汇编语言相似,从而有利于下一步代码的生成。采用中间代码的好处之一是可以再中间代码上进行代码优化。

很多编译程序生成的中间代码采用的是“四元式”的结构,四元分别为运算符、运算对象1、运算对象2、结果。eg. (* a1 a2 t1),将a1与a2相乘,后将结果储存到t1。

步骤五:代码优化

代码优化阶段是通过改进中间代码,以便产生具有运行更快、占用空间更小等优点的目标码。

代码优化分为局部优化和全局优化。局部优化包括合并冗余操作,简化计算等,如以“清零”的指令替换掉“x=0”这一赋值指令。而全局优化包括改进循环,减少调用次数,快速地址算法等。

不同的编译器对于中间代码的优化程度和优化效率各不相同。能完成大部分优化的编译器称为优化编译器。但优化过程会在一定程度上影响编译的速度,有时候简单的优化也可能让程序最后的效率大大提高,同时降低编译速度下降的幅度。

步骤六:代码生成

由代码生成器来生成目标机器的汇编程序,其中要完成数据分段、选定寄存器等工作,然后再生成机器可执行的代码。此过程中的一个关键问题是寄存器的分配。

1
2
3
4
5
6
//例:
MOV R2, id3 //将id3放入寄存器R2
MUL R2, #60.0 //将R2与60.0相乘,结果仍储存在R2。其中的#表示60.0作为立即数处理,无需将其定义命名
MOV R1, id2 //将id2放入寄存器R1
ADD R1, R2 //将R1与R2相加,并将结果储存于R1中
MOV id1, R1 //将R1中的值传递给id1
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计