> For the complete documentation index, see [llms.txt](https://hsiaosiyuan0.gitbook.io/icj/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hsiaosiyuan0.gitbook.io/icj/part1/1-1-intro.md).

# 1.1 简述

我们平时所书写的源码，是无法被计算机直接执行的，因此需要一个过程，来将源码转化成机器可以执行的代码，这个转化的过程，就是编译。

综合现在所有的编程语言实现来看，并不是只有编译为机器码的语言，比如 C语言，才能称为编译型的语言。这是因为原本看上去是解释执行的语言，在其内部也大都引入的编译的环节，比如 PHP 和 Lua，它们都会将源程序编译为中间代码，称之为 Opcode，然后交由引擎或者虚拟机来执行 Opcode。因此，编译主要是强调的源码转化的过程，笼统地将语言一分为二为编译型和解释型、在当下显得有些不严谨了。

编译的步骤可以被大致简单地划分为:

1. 词法分析&#x20;
2. 语法分析
3. 语义分析
4. 生成中间代码
5. 生成目标代码

词法分析「Lexical Analysis」通过词法分析器「Lexer」来完成。词法分析器的作用就是扫描字符串，并输出作为语法单元的词素「Token」，因此它也被称为扫描器「Scanner」。

语法分析「Syntax Analysis」通过语法分析器「Parser」来完成。语法分析器的作用就是根据给定的语法「Grammar」来对词素进行分析，生成抽象语法树「AST, Abstract Syntax Tree」，抽象语法树用来描述程序的结构。

语义分析「Semantic Analysis」用来保证代码中的语义规则的完整性。比如类型检查「Type Checking」。语义分析过程中还会生成符号表「Symbol Table」并生成中间代码「Intermediate Code」。中间代码的作用就是进一步将词法分析的结果进行完善，方便接下来在生成目标代码时的工作。

之所以将编译的步骤进行这样的划分，是希望简化编译器的结构，加快编译的过程。并不是对所有语言而且，上述的环节都是必须的，比如语义分析，可以移到程序运行期间来完成。在 JavaScript 中，当我们引用一个未定义的变量时，会在运行阶段进行报错「ReferenceError」，这也是由于 JavaScript 的动态性，无法在编译环节发现这个错误。

我们在接下来的章节中，都会尽量地将一些特定中文词汇所对应的英文列出来，方便大家使用搜索引擎来进一步深入了解它们。
