🌳 什么是 AST?
抽象语法树(AST)是源代码的结构化表示,它只保留代码的语法核心信息,忽略语法糖(如括号、换行等)或不影响语义的细节。
它是一棵树结构,每个节点代表代码中的一个结构单位:运算符、变量、函数、语句块等。
示例
1 | 2 + 3 * (4 - 1); |
对应的 AST(简化表示):
1 | + |
每个内部节点表示一个操作符,叶子节点是字面量(如数字)。
🧩 AST 的典型用途
- 语法分析:将源代码转换成 AST
- 语义分析:检查类型或作用域错误
- 代码生成:把 AST 转换为机器码或字节码
JS 片段转 AST
执行顺序
- 读取 js 文件中的字符流
- 通过词法分析生成 token
- 通过语法分析( Parser )生成 AST
- 生成机器码执行
整个解析过程主要分为以下两个步骤:
- 分词:将整个代码字符串分割成最小语法单元数组
- 语法分析:在分词基础上建立分析语法单元之间的关系
JS Parser 是 js 语法解析器,它可以将 js 源码转成 AST,常见的 Parser 有 esprima、traceur、acorn、shift 等。
词法分析
- 词法分析,也称之为扫描(scanner),简单来说就是调用 next() 方法,一个一个字母的来读取字符,然后与定义好的 JavaScript 关键字符做比较,生成对应的 Token
1 | 例如 var 这三个字符,它只能作为一个整体,语义上不能再被分解,因此它是一个 Token。 |
- 词法分析器里,Token 包括 关键字 标识符 操作符 标点符 等
- 会过滤掉源程序中的注释和空白字符、换行符、空格、制表符等
- 最终,整个代码将被分割进一个 tokens 列表(或者说一维数组)。
语法分析
语法分析会将词法分析出来的 Token 转化成有语法含义的抽象语法树结构
示例 使用 babel/parser 转换代码
1 | import parser from "@babel/parser"; |
转换结果
1 | { |
实战 写一个 二则运算的 AST
- 完成一个最简易的 AST 函数
1 | const BinaryOp = { |
1 | const ast1 = new AstTree( |
输出
1 | { |
- 输出 HTML
1 | /** |
- 节点之间连线
1 | function drawLines(svg) { |
- 动态生成内容