i
i
icj
Search…
1.1 简述
我们平时所书写的源码,是无法被计算机直接执行的,因此需要一个过程,来将源码转化成机器可以执行的代码,这个转化的过程,就是编译。
综合现在所有的编程语言实现来看,并不是只有编译为机器码的语言,比如 C语言,才能称为编译型的语言。这是因为原本看上去是解释执行的语言,在其内部也大都引入的编译的环节,比如 PHP 和 Lua,它们都会将源程序编译为中间代码,称之为 Opcode,然后交由引擎或者虚拟机来执行 Opcode。因此,编译主要是强调的源码转化的过程,笼统地将语言一分为二为编译型和解释型、在当下显得有些不严谨了。
编译的步骤可以被大致简单地划分为:
  1. 1.
    词法分析
  2. 2.
    语法分析
  3. 3.
    语义分析
  4. 4.
    生成中间代码
  5. 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 的动态性,无法在编译环节发现这个错误。
我们在接下来的章节中,都会尽量地将一些特定中文词汇所对应的英文列出来,方便大家使用搜索引擎来进一步深入了解它们。
Copy link