本文授权转载自原作者黄瑞敏, 未经许可请勿转载
编译,其实就是把源代码变成机器能理解的目标代码(如汇编语言)的过程。
编译的主要步骤主要如下:
- 词法分析:把输入的字符串流变成
token
。 - 语法分析:把
token
变成抽象语法树AST
。 - 语义分析:遍历
AST
树,根据已有的语义规则做语义理解和语义检查。 - 生成目标语言(如汇编语言)。
本篇文章分析以 javascript
为程序语言的基本编译过程及相关原理。
词法分析
简单理解,就是将程序(字符串形式)进行解析:
例如对于
10 + 2 * 30
我们已经定义好这些词法:
- TokenNumber: 1 2 3 4 5 6 7 8 9 0 的组合
- Operator: + 、-、 *、 / 之一
- Whitespace:
- LineTerminator:
空白和换行没有意义,因此不加入后续语义分析。
怎么将程序字符解析出我们需要的一个一个的 token
,有两种方法,一种是状态机,一种正则;
这里用状态机demo作为例子解析 10 + 2 * 30
:
let token = [];
let result = [];
const inSingleChar = char => { // 分析单个字符
if(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'].indexOf(char) > -1) {
token.push(char);
return inNumber;
}
if(['+', '-', '*', '/'].indexOf(char) > -1) {
emmitToken(char, char);
return inSingleChar
}
if(char === ' ') {
return inSingleChar;
}
if(char === '\r'
|| char =&#