术语表与知识库
了解 AST(抽象语法树)的核心概念与术语,帮助你更好地理解代码结构与编译器原理。
抽象语法树(AST)
抽象语法树是源代码的树形结构表示。它将代码的语法结构抽象为节点和边的关系,去除了源码中的空格、注释、分号等不影响语义的细节。AST 是编译器、解释器、代码分析工具和代码转换工具的核心数据结构。JavaScript 引擎在执行代码前会先将其解析为 AST,然后再转换为字节码执行。
解析器(Parser)
解析器是将源代码文本转换为 AST 的工具。不同的解析器在性能、语法支持范围和 AST 输出格式上可能有所差异。JavaScript 领域主流的解析器包括 Acorn、Babel Parser、Esprima 等。解析器的工作分为词法分析(将文本分解为 Token 流)和语法分析(将 Token 流组合为 AST)两个阶段。
ESTree 规范
ESTree 是 JavaScript 社区制定的 AST 规范,定义了各种 AST 节点的类型和属性。大多数 JavaScript 解析器(如 Acorn、Esprima、Babel)都遵循或兼容 ESTree 规范。遵循统一规范使得不同的工具之间可以互操作,例如 ESLint 的规则可以使用任何兼容 ESTree 的解析器。
Program 节点
Program 是 AST 的根节点,代表整个源代码文件。它包含一个 body 数组,其中存放所有顶层语句和声明的节点。每个 JavaScript 文件的 AST 都以 Program 节点开始。
Expression 节点
Expression(表达式)节点代表会产生值的代码片段。常见的表达式节点包括:Identifier(标识符,如变量名)、Literal(字面量,如数字、字符串)、BinaryExpression(二元表达式,如 1 + 2)、CallExpression(函数调用,如 fn())、MemberExpression(成员访问,如 obj.prop)。
Statement 节点
Statement(语句)节点代表执行某个操作的代码片段。常见的语句节点包括:ExpressionStatement(表达式语句)、IfStatement(if 语句)、ForStatement(for 循环)、ReturnStatement(return 语句)、BlockStatement(代码块)。
Declaration 节点
Declaration(声明)节点代表创建新绑定的语句。常见的声明节点包括:VariableDeclaration(变量声明,var/let/const)、FunctionDeclaration(函数声明)、ClassDeclaration(类声明)。声明节点会创建新的标识符绑定,可以在后续代码中引用。
Babel
Babel 是一个 JavaScript 编译器,通过插件系统可以将新版 JavaScript 代码转换为兼容旧环境的代码。Babel 的核心工作流程就是解析代码为 AST,对 AST 进行各种转换操作,最后将转换后的 AST 生成新的代码。Babel 插件通过访问者模式(Visitor Pattern)遍历 AST 节点并进行修改。
ESLint
ESLint 通过解析代码为 AST 来检测代码中的问题。ESLint 规则本质上是对 AST 节点的检查函数,规则可以选择性地监听特定类型的节点,在节点被访问时执行检查逻辑。自定义 ESLint 规则需要理解目标代码结构对应的 AST 节点类型。
Prettier
Prettier 是一个代码格式化工具,它将代码解析为 AST,然后根据预设的格式化规则重新生成格式化后的代码。这种基于 AST 的格式化方式确保了输出代码的语法正确性,同时统一了代码风格。Prettier 不修改代码的语义,只调整格式。
Source Map
Source Map 是一种将压缩或转换后的代码映射回原始源码的技术。AST 节点中包含的 start/end 位置信息是 Source Map 生成的基础。通过 Source Map,浏览器开发者工具可以将压缩后的代码行号映射到原始源码,方便调试。Babel 和 TypeScript 在编译时都会生成 Source Map 文件。
节点位置信息
每个 AST 节点都包含源码位置信息:start(起始字符偏移量)、end(结束字符偏移量)、loc(包含 line 和 column 的位置对象)。这些位置信息对于错误报告、代码高亮、格式化和 Source Map 生成等功能至关重要。在本工具中,点击节点可以在详情面板中查看这些位置信息。
遍历与访问者模式
遍历 AST 是访问所有节点的过程。JavaScript 工具库通常使用访问者模式(Visitor Pattern)来遍历 AST,开发者可以注册对特定节点类型的处理函数。Babel 提供了 traverse 函数,Esprima 提供了 estraverse 模块,都遵循类似的访问者模式接口设计。
UD5工具箱