概念
编译 就是把高级语言逻辑 转换为 低级语言指令
那么问题来了:低级语言和高级语言是啥?
低级语言:是涉及到寄存器,cpu指令等,与机器有关,描述在机器上具体执行过程的语言。
计算机硬件只能识别“断开”(0)和“闭合”(1)两种物理状态,低级语言符合机器的思考方式。
如字节码、机器语言、汇编语言
高级语言:是用来表达逻辑,提供各种逻辑组织方式(if else等)的语言。
高级语符合人的思考方式,编写和阅读都相对容易。
如Javascript、C、C++、Java、Python
低级语言执行效率高,高级语言开发效率高
解析(parser)
词法解析:按照状态机进行分词,把字符串拆分到最小颗粒的单词;
语法解析:单词之间的组合方式
LL parsing:从左到右,尝试构建最左边的推导
LR parsing:从左到右,尝试构建最右边的推导
AST处理
AST:Abtract Syntaxt Tree 抽象语法树
编译器(Compiler)处理
按照语法结构递归AST 进行每个节点的翻译,用线性IR的指令来翻译AST节点的属性
语义分析:检查语义错误,主要有 作用域分析 引用消解 类型推倒和检查 正确性检查
程序分析(静态分析):线性IR的分析,建立控制流(if /while /函数调用)图,可以用于编译优化
优化后的线性IR可以生成汇编代码,通过汇编器转成机器码
转译器(Transpiler)处理
转译器的目标代码也是嵌套结构的高级语言,所以转译是从树形结构到树形结构,不需要翻译成线性IR
babel tyoescript eslint postcss prettier 等都是转译器,
babel是把高版本es代码转成低版本 ,并注入polyfill。
Taro也是基于babel封装的小程序转译器
解释器(Interpreter)处理
解释器/直译器:用一门高级语言来解释另一门高级语言(一般都用c++写)
像v8、spidermonkey等都是用c++来写的js解释器。
tree walker解释器:直接解释执行ast
虚拟机:解释线性代码的,比如汇编代码,字节码等这种的程序,因为机器代码就是线性的
Ignation解释器:把解析出的 AST 转成字节码,然后解释执行字节码,热度到达阈值之后会交给 turbofan 编译为汇编代码之后生成机器代码,来加速。gc 是独立的做内存管理的
前端编译相关
工程化相关的转译器: babel、typescript、eslint、terser、prettier、postcss、posthtml、taro、vue template compiler等
js引擎: v8、javascriptcore、quickjs等
wasm(WebAssembly): LLVM(编译框架) 可以生成wasm字节码,所以c++、rust等可以转为LLVM IR(Intermediate Representation,中间表示) 的语言都可以做 wasm 开发
注:通常情况下,一门编程语言只需要完成能够生成LLVM IR的编译器前端即可,然后就可以轻松使用LLVM的各种编译优化、JIT支持、目标代码生成等功能