知识准备

学习:
https://github.com/starkwang/the-super-tiny-compiler-cn/blob/master/super-tiny-compiler-chinese.js

三个阶段:

  1. 解析 parse:输入转为 AST(抽象语法树,Abstract Syntax Tree)
  2. 转换 transform:承上启下。把1的东西给到下一步。
  3. 代码生成 code gen:生成新的代码

解析

第一步,词法分析:

输入,分割成一些被称为 Token 的东西,这个过程是在词法分析器(Tokenizer或者Lexer)中完成的

比如 输入 (add 2 (subtract 4 2))

它产生的 Token 看起来或许是这样的:

1
2
3
4
5
6
7
8
9
10
11
[
{ type: 'paren', value: '(' },
{ type: 'name', value: 'add' },
{ type: 'number', value: '2' },
{ type: 'paren', value: '(' },
{ type: 'name', value: 'subtract' },
{ type: 'number', value: '4' },
{ type: 'number', value: '2' },
{ type: 'paren', value: ')' },
{ type: 'paren', value: ')' }
]

语法分析:Token转AST。

完事AST是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
type: 'Program',
body: [{
type: 'CallExpression',
name: 'add',
params: [{
type: 'NumberLiteral',
value: '2'
}, {
type: 'CallExpression',
name: 'subtract',
params: [{
type: 'NumberLiteral',
value: '4'
}, {
type: 'NumberLiteral',
value: '2'
}]
}]
}]
}

转换

对上面的 AST 我们要转换啥呢。这要看你第三步想要啥。可以把上一步 AST 的一个节点转换成A 语言用的节点,也可以转成 B 语言。

  • 使用 DFS 进行遍历
  • 可以写一些方法 funcs,针对不同的节点进行转换
  • 把父节点作为参数一起传入上面的func,可能会用的到

生成代码

根据上一步的 AST,生成代码