# 1.1 编译器简介

CPU 是计算机执行指令的单元，每种架构的 CPU 都有自己的指令集，例如常见的 `x86` , `ARM` 等，由此构成的编程语言称为机器语言，由机器语言构成的程序是 CPU 唯一能够执行的程序，机器语言是面向机器的低级编程语言。

而在软件开发中，人的生产效率是第一需要考虑的因素，除此之外，我们还需要更多、更强的抽象能力与表达能力（例如并发、模块化、作用域等），来编写结构更加复杂的程序；像 `Java`, `Golang` 这类编程语言是面向人类的高级编程语言。

因此，从高级语言到机器语言的转换是执行任何程序的先行步骤，这个过程叫着编译，完成该过程的程序叫着编译器。编译是个复杂的过程，通常被划分为如下几个阶段：

词法分析 –> 语法分析 –> 语义分析 –> 中间代码生成 –> 机器无关代码优化 –> 目标代码生成 –> 目标代码优化

编译器是一个非常庞大复杂的系统，更准确地说，这其实是一个完整的领域。通常而言，程序语言设计者会采用已有的编译器工具链来构造不同的模块，例如使用 [Lex](https://en.wikipedia.org/wiki/Lex_\(software\)) 来构造词法分析器，使用 [Yacc](https://en.wikipedia.org/wiki/Yacc) 来构造语法分析器，然后配合自己实现的其他模块来组装成一个完整的编译器，这样的话技术栈将非常宽泛，深入学习该语言的编译过程就变成了一件非常困难的事情。通常情况下，编程语言的编译器都会使用另一种语言来实现，这对用户学习其编译过程也是极度不友好的。因此除非是编译器的实现者，对于大多数普通程序员而言，对编译器的知识通常只是停留在理论阶段，而无法与所使用的语言直接关联起来。对于自己所使用语言的编译过程知识的缺失，是造成无法深入了解、掌握甚至精通该语言的障碍之一。
