编译器的工作原理

编译器的工作原理

编译器 (Compiler) 是一种将由一种语言编写的程序转换为另一种编程语言的可执行程序. 现代软件对于编译器的需求远甚从前, 究其原因很简单: 作为中间层, 编译器是构建更高层抽象的基础设施. 编译器意欲将人类可阅读的高阶代码, 翻译为机器能运行的低阶代码.

编译器五花八门, 例如:

  • gcc, llvm 将 c, c++, go, obj-c 之类的语言编译为汇编代码;
  • less 编译器可将 less 代码编译为 css 代码;
  • clojure 编译器可将 clojure 代码编译为 JVM 汇编码, clojurescript 代码编译为 javascript 代码;

现代编译器的主要工作流程为: 源代码(source code)→ 预处理器(preprocessor)→ 编译器(compiler)→ 汇编程序(assembler)→ 目标代码(object code)→ 链接器(Linker)→ 可执行文件(executables)[1].

其中, 编译器位于一个最重要的位置: 将源码转为汇编(上文提到的css, js也可认为是一种汇编). 传统编译器的工作原理大致可以分为 3 个步骤:

  • 前端: 解析代码, 检查语法, 切分token, 建立抽象语法树(abstract syntax tree).
  • 优化器: 对前端生成的中间文件进行优化
  • 后端: 将优化器优化后的代码转换为汇编代码.

SimpleCompiler

前端的多态实现, 使编译器得以编译各种代码; 后端的多态实现, 使编译器得以生成不同的汇编码进而运行在不同的宿主上. 如果在一种平台上用编译器编译到另一个平台上, 那么这便是交叉编译了.

RetargetableCompiler

JIT(Just-in-time compilation) 是近年来比较热门的一种编译技术. 我们知道, 一般我们用编译过的程序是表示程序执行前就已经全部被转为机器码, 而解释则是运行时一句一句边翻译边运行. JIT 混合了两者的优点, 一句一句编译源码, 又会缓存编译结果.

refer: http://www.aosabook.org/en/llvm.html [1]: http://zh.wikipedia.org/wiki/%E7%B7%A8%E8%AD%AF%E5%99%A8