原文发表在我的博客 编译原理(一) | 以太空间
一、什么是编译器
编译器是一类把源代码翻译成目标代码(一般是机器指令)的程序,当然,源代码和目标代码要具有相同的语义(等效的),而且在翻译过程中只能进行静态计算(静态计算的意思是不会去执行代码)
二、编译器与解释器
解释器也是一类处理源代码的程序,与编译器不同的是,解释器在处理源代码的过程中是解释执行的,通俗的来讲,就是解释器读取一句就执行一句,而不是像编译器那样直接将源代码翻译为目标代码。 根据编译器和解释器的划分,可以将编程语言分为编译型语言和解释型号语言,以下是常见编程语言的分类:
编译型语言:C、C++、Java、Go 解释型语言:JavaScript、Python、PHP
有一小部分关于Java的争议,因为Java语言是先由编译器翻译为字节码,然后由虚拟机(JVM)解释执行字节码,一般将Java归为编译型语言
三、编译器的工作过程
编译器将源代码翻译为目标代码的过程不是一蹴而就的,这个过程分为很多小过程,看下面这张图
其中左半部分负责将源代码翻译为中间代码(形式化描述语义的代码),称为前端;右半部分负责将中间代码翻译为机器代码,称为为后端;前端表示更接近于源代码,后端表示更接近于机器,可不是Web中的前端和后端哦~
实际的编译器可谓是相当复杂,除了上面图中展示的以外,还有相当多的优化环节和错误处理环节,但是,再复杂的编译器的架构都是源自于世界上第一个编译器Fortran编译器,不可或缺得要有以下六大主要模块:
- 词法分析
- 语法分析
- 语义分析
- 中间代码生成
- 代码优化
- 目标代码生成
还有一个贯穿全局的符号表和错误处理。
1. 词法分析
这个阶段编译器的主要工作是识别源程序中的记号,生成记号流。 常见的记号有以下几类:
- 关键词
- 标识符(变量名、过程名、类型名等)
- 字面量(常量)
- 特殊符号(运算符、分隔符)
2. 语法分析
识别记号流中的结构,构造语法数,一般是二叉树。
3. 语义分析
对语法书进行静态语义检查,保证语义合法。
4. 中间代码生成
生成与机器无关的中间代码,最常见的是三地址吗。
5. 代码优化
优化代码,是一个等价变换的过程。
6. 目标代码生成
根据实际的机器,生成机器代码。