AST
抽象语法树是什么?
抽象语法树(Abstract Syntax Tree,AST)是源代码语法结构的一种抽象表示
它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构
每个包含type属性的数据结构,都是一个AST节点;
以下是普通函数function ast(){},转换为ast后的格式:
抽象语法树用途有哪些?
代码语法的检查、代码风格的检查、代码的格式化、代码的高亮、代码错误提示、代码自动补全、实现一套代码适配多端运行等等
优化变更代码,改变代码结构使达到想要的结构
webpack、Lint等这些工具的原理都是通过 JavaScript Parser 把源代码转化为一颗抽象语法树(AST),通过操纵这颗树,我们可以精准的定位到声明语句、赋值语句、运算语句等等,实现对代码的分析、优化、变更等操作。
JavaScript解析器
那什么是JavaScript解析器呢?
JavaScript解析器的作用,把JavaScript源码转化为抽象语法树。
浏览器会把js源码通过解析器转换为ast,再进一步转换为字节码或者直接生成机器码,进行渲染和执行。
一般来说,每个js引擎都有自己的抽象语法树格式,Chrome的v8引擎, firfox的Spider Monkey引擎等。
JavaScript解析器通常可以包含四个组成部分。
词法分析器(Lexical Analyser)
语法解析器(Syntax Parser)
字节码生成器(Bytecode generator)
字节码解释器(Bytecode interpreter)
词法分析器(Lexical Analyser)
首先词法分析器会扫描(scanning)代码,将一行行源代码,通过switch case 把源码?“/为一个个小单元,jS代码有哪些语法单元呢?大致有以下这些:
空白:JS中连续的空格、换行、缩进等这些如果不在字符串里,就没有任何实际逻辑意义,所以把连续的空白符直接组合在一起作为一个语法单元。
注释:行注释或块注释,虽然对于人类来说有意义,但是对于计算机来说知道这是个“注释”就行了,并不关心内容,所以直接作为一个不可再拆的语法单元
字符串:对于机器而言,字符串的内容只是会参与计算或展示,里面再细分的内容也是没必要分析的
数字:JS语言里就有16、10、8进制以及科学表达法等数字表达语法,数字也是个具备含义的最小单元
标识符:没有被引号扩起来的连续字符,可包含字母、_、$、及数字(数字不能作为开头)。标识符可能代表一个变量,或者true、false这种内置常量、也可能是if、return、function这种关键字,是哪种语义,分词阶段并不在乎,只要正确切分就好了。
运算符:+、-、*、/、>、<等等
括号:(...)可能表示运算优先级、也可能表示函数调用,分词阶段并不关注是哪种语义,只把“(”或“)”当做一种基本语法单元
就是一个字符一个字符地遍历,然后通过switch case分情况讨论,整个实现方法就是顺序遍历和大量的条件判断。以@babel/parser源码为例:
getTokenFromCode(code) {
switch (code) {
case 46: