编译常识

名词介绍

  • 词法解析

    将一段文本,分成多个词

  • 语法解析

    将词法赋予跟高层意义比如, - 在数字前面可能是符号,也可能是减法标识,通过优先级赋予不同含义,语法在编程语言里面通常分为两种类型,一种是语句,一种是表达式

  • 语义分析

    判断当前语法是否符合上下文环境,比如使用了变量 a 那么需要确定是否声明过变量 a,在 js 中 eslint 就是的某些能力就是做了语义分析。

语法分析

一般语法分析都是上下文无关语法分析。

比如下面js 代码

console.log(hello)

在语法上是合理的,但是语义上因为上下文中没有hello这个变量的声明所以不合法的。

语法分析主要分为两种

LR 类型的语法分析 一种是 ycc 为首的自下而上的分析法,还比如 codemirror 的 Lezer。 特点是有代码生成环节,具体没实现过不多过多介绍。

LL 类型的语法分析 特点是现实简单,比如 babel,swc,esbuild 都是使用的这种类型的

我们这里也会使用 LL(K) 进行实现。

编译器的主要流程如下

input  -> lexer  ->   parse   --> stringify
string -> token  ->   ast-tree ->  string

从输入端的字符串开始解析词法,这是分析中的最小单位。

由多个或者单个词法组成具有含义的语法树节点。

由多个语法节点组合成语法树。

通过遍历语法树,转换生成对应的目标字符串。

以上就是编译器的全部流程,11/25 我完成了前三个代码实现,至于最后一个看下后面反响来做决定。

如果像对编译器推荐以下几本书

《自己动手实现Lua:虚拟机、编译器和标准库》 《编译原理(第2版)》