知识准备
学习:
https://github.com/starkwang/the-super-tiny-compiler-cn/blob/master/super-tiny-compiler-chinese.js
三个阶段:
- 解析 parse:输入转为 AST(抽象语法树,Abstract Syntax Tree)
- 转换 transform:承上启下。把1的东西给到下一步。
- 代码生成 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,生成代码