Babel 是目前最常用的 JavaScript 编译器。能够编译JS代码,使得代码能够正常的在旧版本的浏览器上面运行;还能够转化 JSX 语法,使得 react写的代码能够正常运行。
eg把let a = 1;
转换成var a = 1;
编译原理
三个阶段:解析,转换和代码生成
解析(Parsing):将原始代码转换成AST抽象树
转换(Transformation):对AST抽象树进行处理,变化结构
代码生成(Code Generation):把处理后的AST抽象树转化成代码
解析
分为词义分析和语法分析:
1、词义分析:接收原始代码进行分词,最后生成token
eglet a = 1
词义分析结果为
[
{ "type": "Keyword", "value": "let" },
{ "type": "Identifier", "value": "a" },
{ "type": "Punctuator", "value": "=" },
{ "type": "Numeric", "value": "1" }
]
词义分析函数为
//解析代码,最后返回tokens
function tokenizer(input){
//记录当前解析到词的位置
var current = 0;
//tokens用来保存我们解析的token
var tokens = [];
//利用循环进行解析
while(current < input.length){
//提取出当前要解析的字符
var char = input[current];
//处理符号,检查是否是符号
var PUNCTUATOR = /[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/im;
if(PUNCTUATOR.test(char)){
//创建变量用于保存匹配的符号
var punctuators = char;
//判断是否是箭头函数的符号
if(char === '=' && input[current+1] === '>'){
punctuators += input[++current];
}
current++;
//最后把数据更新到tokens中
tokens.push({
type: 'Punctuator',
value: punctuators
});
//进入下次循环
continue;
}
var WHITESPACE = /\s/;
if(WHITESPACE.test(char)){
current++;
continue;
}
//处理数字,检查是否为数字
var NUMBERS = /[0-9]/;
if(NUMBERS.test(char)){
//创建变量用于保存匹配的数字
var number = '';
//循环遍历接下来的字符,直到下一个字符不是数字为止
while(NUMBERS.test(char)){
number += char;
char = input[++current];
}
//最后把数据更新到tokens中
tokens.push({
type: 'Numeric',
value: number
});
continue;
}
//处理字符,检查是否为字符
var LETTERS = /[a-z]/i;
if(LETTERS.test(char)){
var value = '';
//用一个循环遍历所有的字母,把它们放入token中
while(LETTERS.test(char)){
value += char;
char = input[++current];
}
//判断当前字符串是否为关键字
var KEYWORD = /function|var|return|let|const|if|for/;
if(KEYWORD.test(value)){
tokens.push({
type: 'Keyword',
value: value
});
}else{
tokens.push({
type: 'Identifier',
value: value
});
}
continue;
}
// 最后如果我们没有匹配上任何类型的 token,那么我们抛出一个错误。
throw new TypeError('I dont know what this character is: ' + char);
}
//返回tokens数组
return tokens;
}
语法分析:接收词义分析的tokens,然后分析内部之间内部关系,最终生成抽象语法树(AST)
eg
[ { "type": "Keyword", "value": "let" },
{ "type": "Identifier", "value": "a" },
{ "type": "Punctuator", "value": "=" },
{ "type": "Numeric", "value": "1" } ]
的语法分析结果为
{
"type": "Program",
"body": [
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "a"
},
"init": {
"type": "Literal",
"value": 1,
"raw": "1"
}
}
],
"kind": "let"
}
],
"sourceType": "script"
}