Babel运行原理
前言
之前翻博客园的时候,看到有人朋友分享阿里巴巴的面试题,其中有一道题就是关于ES6转ES5
原理的,当时我看到感觉到自己离去阿里巴巴的路还很远啊,像我们大部分做开发的时候,都只知其然不知
其所以然,本着好学的态度我也去网上搜了下关于Babel es6转es5的原理,但是很多都是枯燥难懂,整理了一下午
把自己的收获和大家分享一下,有不对的地方请各位大神指正.
Babel运行原理
再说es6怎样转es5之前我们首先要来说一下Babel的运行原理,知道运行原理,我们也就不难理解
为什么Babel能这么强大.
Babel工作分为三个阶段:
1.解析:将代码字符串解析成抽象语法树
2.变换:将抽象语法树
3.根据变换后的抽象语法树再生成代码字符串
举个例子:
if(1>0){ alert('hi') }
用图像更简单地表达上面的结构:
第1步转换的过程中可以验证语法的正确性,同时由字符串变为对象结构后更有利于精准地分析以及进行代码结构调整。
第2步原理,就是遍历这个对象所描述的抽象语法树,遇到哪里需要做一下改变,就直接在对象上进行操作,比如我把IfStatement给改成WhileStatement就达到了把条件判断改成循环的效果。
第3步,递归遍历这颗语法树,然后生成相应的代码
第二步和第三步大家都很好理解,现在我来着重讲解第一步.
解析第一步分为两个步骤:
1.分词:将整个代码字符串分割成 语法单元 数组
2.语义分析:在分词结果的基础之上分析 语法单元之间的关系
分词的过过程从逻辑来讲并不难解释,但是这是个精细活,要考虑清楚所有的情况。还是以一个代码为例:
if (1 > 0) { alert("if \"1 > 0\""); }
我们希望得到的分词是:
'if' ' ' '(' '1' ' ' '>' ' ' ')' ' ' '{' '\n ' 'alert' '(' '"if \"1 > 0\""' ')' ';' '\n' '}'
这拆分过程其实没啥可取巧的,就是简单粗暴地一个字符一个字符地遍历,然后分情况讨论,整个实现方法就是顺序遍历和大量的条件判断.
语义分析就是把词汇进行立体的组合,确定有多重意义的词语最终是什么意思、多个词语之间有什么关系以及又应该再哪里断句等。
语义分析的过程又是个遍历语法单元的过程,不过相比较而言更复杂,因为分词过程中,每个语法单元都是独立平铺的,而语法分析中,语句和表达式会以树状的结构互相包含。针对这种情况我们 可以用栈,也可以用递归来实现。
结语
真正看下来,其实没有哪个地方的原理特别高深莫测,就是精细活,需要考虑到各种各样的情况。总之要做一个完整的语法解释器需要的是十分的细心与耐心。
本篇博客是根据 百度外卖前端 进行的总结原博客 https://zhuanlan.zhihu.com/p/27289600