程序为什么需要翻译

人编写的表达式、函数和变量,并不天然等同于处理器指令。编译器读取源程序,将其转换为另一种可供后续工具使用的表示。这个目标可能是汇编语言、虚拟机字节码,甚至另一种高级语言,因此“经过编译”不等于已经直接生成当前机器可执行的全部文件。

参考:[1] [2]

先建立程序结构

翻译通常需要先认出名字、数字和运算符,再根据语法把它们组织成结构。抽象语法树保留表达式之间的关系,例如乘法属于哪一次加法的输入,而不只是按字符顺序保存原文。LLVM教程用递归下降与运算符优先级分析构造这种树,后续阶段再从树生成代码。

参考:[2]

编译、汇编与连接

在GCC的常见使用流程里,预处理、编译、汇编和连接依次进行,但用户可以在中间停止。编译器可以先输出汇编,汇编器再形成目标文件;连接器把目标文件与所需库组合起来。缺少库符号的连接错误,与源程序语法错误发生在不同环节,不能一概视为同一种失败。

参考:[1]

中间形式让工具分工

把前端与后续表示分开,可以让不同语言复用部分处理工具,也让同一种语言面向不同目标。但优化仍须遵守语言规定的行为,不能只求指令更少而改变结果。编译器承担的是有约束的程序转换;运行时库、加载器和执行环境则继续完成它没有独自包办的工作。

参考:[1] [2]