Skip to content
On this page

编译是将高级语言程序转化为机器语言程序的过程,主要包括以下几个步骤:

  1. 词法分析(Lexical Analysis):将源代码按照定义好的规则分解成一个一个的单词(Token),并且对每个单词进行分类,如标识符、关键字、操作符、常量等。
md
在这过程主要用到,有限状态机(FSM)和正则表达式(Regex),都是用于描述字符串的语言工具,它们在匹配和处理字符串方面有一些不同之处。

1.匹配范围
正则表达式通常对整体字符串进行匹配,而有限状态机可以匹配任何前缀或子字符串。例如,给定一个模式P和一个字符串S,可以使用FSM来找出S中所有包含P的子字符串,但是正则表达式只会返回与整个S匹配的结果。

2. 完备性
正则表达式是一种完备的语言,可以匹配所有可计算的字符串,而有限状态机只能够匹配一些特定的语言。尽管FSM可以识别某些复杂的语言,但是对于某些类型的语言,如无法无限达到的语言,FSM可能是不适用的。

3. 处理效率
有限状态机在处理相对较小的字符串时速度很快,但随着输入字符串的长度增加,其效率也会下降。相反,如果需要处理大量数据并且要匹配多个规则,使用正则表达式可能更为有效。

4. 编码难度
虽然正则表达式的高级功能使得编写复杂的规则变得相对简单,但是当你需要匹配复杂的结构或特定的条件时,你可能会遇到困难。使用有限状态机,规则的编写和修改可以变得更加直观和可控。

总的来说,正则表达式更适合匹配简单的模式,应用范围相对广泛,而有限状态机更适合处理复杂规则、结构化数据等需要进行精细控制的场景。在实际应用时,可以根据具体需求选择使用哪种方式。
  1. 语法分析(Syntax Analysis):将词法分析产生的令牌进行组合,并且根据语言的语法规则判断是否有语法错误。生成抽象语法树(Abstract Syntax Tree, AST)。
将原始代码表示为类似二叉树的AST节点声明。显然,树形节点的结构表现了语法分析器通过识别代码中的模式以及模式之间的关系来分离并解释 JavaScript 代码文件得到的一些概念。叶节点通常代表数字、变量名等,而非终止符号类型的节点则通常表示代码块和其他可能包含其他节点的结构体。根据上下文和语言规范,编译器利用这些节点组成最终的语法抽象树。任何代码的AST都需要遵循JavaScript的规范要求,比如应用优先级和结合律等。
  1. 语义分析(Semantic Analysis):在抽象语法树基础上,检查源代码中不符合语言语义的部分,并进行修正或给出错误提示。
md
1. 符号表构建
该阶段的第一步是符号表的构建。符号表是一种数据结构,用于存储程序中使用的所有变量、函数和类的名称,同时也记录这些元素的类型、作用域等信息。当编译器遍历 AST 时,它会检查每个变量、函数和类,在全局范围内添加相应的条目到符号表中。

符号表通常由程序的编译器自动生成,并且与编译程序的具体实现有关。

2. 类型检查
类型检查是语义分析的另一个重要方面。其目的是确保变量的值与其类型相匹配,同时也会检查函数调用的参数是否正确。类型检查可以帮助检测程序中潜在的运行时错误,因为类型不正确可能导致错误的计算结果或者是逻辑错误。

例如,如果尝试将字符串与数字相乘,那么就要对此进行类型检查。如果 JavaScript 引擎在解释代码时遇到“3 * ‘hello’”这样的表达式,它就会在编译时报错。

3. 作用域检查
作用域检查是指编译器在检查变量的引用之前先找到该变量所在的作用域。JavaScript 具有动态作用域和静态作用域两种策略。而常用的 JavaScript 是静态作用域(词法作用域),在编译阶段就确定了每个变量的作用域。因此,在语义分析阶段,编译器将会检查函数和变量的作用域,并确保没有重复定义或者未定义的标识符出现。

4. 歧义消除
同样,在遍历 AST 时,编译器还必须进行歧义消除。例如,在函数调用时可能存在二义性,导致编译器无法确定使用哪个函数。这时编译器将依照一定的规则进行错误提示,帮助程序员修复代码中的问题。

5. 报错处理
最后,在执行所有上述操作后,编译器会尝试在代码中找到错误,如果发现任何错误,它将停止解析并返回错误信息。由于不同的编译器实现方法不同,因此可以生成不同级别的错误。比如语法错误、类型错误等。
  1. 中间代码生成(Intermediate Code Generation):将高级语言的抽象句法树翻译成目标代码和中间代码表示,一般以三地址码的形式表达,这种形式易于优化。

  2. 代码优化(Code Optimization):在不改变程序功能的前提下,对目标代码进行优化,使得程序效率更高或者占用更少的存储空间。

  3. 目标代码生成(Target Code Generation):将中间代码转换为目标代码,即计算机能够直接执行的机器指令。

  4. 符号表处理(Symbol Table Handling):管理指令中使用的变量和函数以及它们的属性。

  5. 错误处理(Error Handling):在编译过程中,如果发现语法错误、符号表不存在变量或函数等异常情况,则需要记录并提示用户。

总之,编译器是将高级语言程序转化为机器语言程序的重要工具,其内部实现涉及到多个步骤和环节,需要依次完成一系列任务以生成最终可执行文件。

From ChatGPT