【Go】Go学习笔记(一) GO的编译原理
编译器执行语法分析会输出一个抽象语法树(AST)。
抽象语法树辅助编译器进行语义分析。
- 知识点:词法分析、语法分析、语义分析
词法分析:编译过程的第一个阶段,一个字符一个字符的读入,根据构词规则识别单词。
语法分析:编译过程的一个逻辑阶段,在词法分析的基础上,将单词序列组合成各种语法短语(语法结构)。
语义分析:编译过程的一个逻辑阶段,对结构上正确的源程序进行上下文有关性质审查、类型审查1。
语义分析与上下文有关、语法分析与上下文无关。
静态单赋值(SSA)主要作用是对代码进行优化。
在编译成中间代码过程中,每个变量只会被赋值一次。
- 静态单赋值(SSA)
编译器的前后端。
前端分析词法、语法、语义生成中间代码。
后端完成对目标代码的生成和优化,将中间代码翻译成二进制机器码。
- 中间代码
中间语言(中间代码)是一种面向语法,易于翻译成目标程序的源程序的等效内部表示代码。
词法分析
为了能让计算机理解我们的源代码,第一件事情就是将字符串分组
词法分析就是将字符序列转换为标记(token)序列的过程。
通过使用lex生成词法分析器,lex生成的代码能够将一个文件中的字符分解成Token序列。
lex核心函数使用有限自动机(DFA)的程序结构来分析输入的字符流。
lex根据定义的规则生成的词法分析器lexer通过正则匹配的方式将机器原本很难理解的字符串进行分解成很多的Token。
-
有限自动机(DFA)
-
正则匹配
有限自动机是用来识别正规式的一个非常有用的工具,使用有限自动机来构造词法分析程序这也是一种比较好的途径。
语法分析
根据某种特定的形式文法对Token序列工程的输入文本进行分析并确定其语法结构的过程。词法分析的输出结果(Token序列)是语法分析的输入。
分析方法分为:自顶向下、自底向上
上下文无关文法 //对此,博主只做简单了解
类型检查
通过前两步的分析会得到抽象语法树,那之后就是类型检查。
通过类型检查检查语法错误、优化抽象语法树、去除冗余代码。
- 强弱类型
一般结论如下:
强类型的编程语言,在编译期间会有严格的类型限制,也就是编译器会在编译期间发现变量赋值、返回值和函数调用时的类型错误。
弱类型的编程语言在出现类型错误是可能会在运行时进行隐式的类型转换,在类型转换时可能会造成运行错误。
- 类型转换:强制类型转换、隐式类型转换。
隐式类型转换常表现为:在变量赋值时发生的类型转换、在变量运算时发生的类型转换。(这个概念来自于学习C++时)
但其实以上的强弱类型是人为定义的,概念的定义不严格。不必过分关注。
- 静态类型检查于动态类型检查(静态语言、动态语言)
静态类型检查对源代码进行分析,检查程序类型的安全。能让我们在编译期间就发现错误。静态类型为代码在编译期间提供了约束,编译器能够在编译期间约束变量的类型。
动态类型检查是在运行时确定程序类型安全的过程。灵活但容易出错。
二者可以同时使用。如:Java、Go。
完成了上面两大步:词法和语法分析、类型检查。此时的抽象语法树就不存在语法错误了。接下来将是编译器前端的最后工作。
中间代码生成。
在编译过程中,编译器会在将源代码转换到机器码的过程中,先把源代码转换成一种中间的表示形式。
生成的中间代码也需要多轮优化。
在这期间会对语法树中的关键字再进行改写,改写后的语法树会经过多轮处理转变成最后的 SSA 中间代码,相关代码中包括了大量 switch 语句、复杂的函数和调用栈,阅读和分析起来也非常困难。
机器码生成
- 指令集架构
他是计算机软件和硬件之间的接口和桥梁。如果一个编程语言想要在所有的机器上运行,那么他就需要具有将中间代码转换成使用不同指令集加购的机器码的能力。
机器码的生成主要分为两部分:
1.对静态单赋值(SSA)中的代码进行降级、执行框架特定的优化和重写并生成特定指令(生成中间代码)。
2.将特定指令(生成中间代码)转换成机器码。
引用转载(如有侵权请联系删除):
浙公网安备 33010602011771号