菜单

解析器和 AST

相关源文件

本文档涵盖了 Bun 的 JavaScript 和 TypeScript 解析器及抽象语法树 (AST) 实现。解析器负责将 JavaScript/TypeScript 源代码转换为内部 AST 表示形式,该形式可供转译器管道的其他部分进行分析、转换和输出。

有关使用此解析器的转译器和打包器的信息,请参阅转译器和打包器。有关执行已解析代码的 JavaScript 运行时详细信息,请参阅核心 JavaScript 运行时

架构概述

解析器系统由三个主要组件协同工作:词法分析器、解析器和 AST。词法分析器将源代码分词,解析器从这些词元构建 AST,而 AST 则为 Bun 的整个工具链提供结构化表示。

解析器管道流程

来源:src/js_lexer.zig1-5000 src/js_parser.zig1-100 src/js_ast.zig1-100 src/js_printer.zig1-100

核心解析器组件

来源:src/js_lexer.zig76-191 src/js_parser.zig167-180 src/js_ast.zig193-230 src/js_printer.zig1-100

词法分析器实现

词法分析器将原始源代码转换为一系列词元。它使用一个通用的NewLexer 函数实现,该函数支持包括 JSON 和 JavaScript 在内的多种解析模式,并带有不同的功能标志。

词法分析器结构

主要的词法分析器结构包含

  • 源中的currentstartend 位置
  • token - 来自T 命名空间中的当前词元类型
  • code_point - 当前正在处理的 Unicode 码点
  • identifier - 标识符词元的文本
  • 用于错误报告的源位置跟踪
  • 注释保留和 pragma 检测

标记类型

js_lexer_tables.zigT 命名空间定义了所有词元类型

  • 字面量:t_string_literalt_numeric_literalt_big_integer_literal
  • 关键字:t_functiont_classt_ift_for 等。
  • 运算符:t_plust_minust_equals_equals 等。
  • 标点符号:t_open_parent_close_parent_semicolon 等。
  • 特殊:t_end_of_filet_identifier

来源:src/js_lexer.zig76-190 src/js_lexer_tables.zig

解析器实现

解析器实现为递归下降解析器,它在解析时构建 AST。它支持 JavaScript 和 TypeScript 语法、JSX 以及各种 ES6+ 特性。

主解析器结构

解析器维护几个关键状态

  • lexer - 提供输入词元的词法分析器
  • log - 错误和警告收集
  • allocator - 内存管理
  • scope - 当前词法作用域跟踪
  • fn_or_arrow_data_parse - 函数解析上下文
  • 用于解析模式和功能的各种标志

核心解析方法

解析器提供用于解析不同语言结构的方法

TypeScript 支持

解析器通过专用解析逻辑提供全面的 TypeScript 支持

  • 类型注解和断言
  • 接口和类型别名
  • 泛型和类型参数
  • 装饰器和元数据
  • 命名空间声明

JSX 支持

JSX 解析已集成到表达式解析器中

  • JSX 元素和片段
  • JSX 属性和展开属性
  • JSX 子项和文本节点
  • 与 React transform 选项集成

来源:src/js_parser.zig167-485 src/js_parser.zig528-587

AST 结构

AST 使用三种主要节点类型构建:表达式(E)、语句(S)和绑定(B)。每种类型包含所有可能的节点变体的区分联合。

表达式节点 (E 命名空间)

表达式表示值和计算

语句节点 (S 命名空间)

语句表示程序流程和声明

绑定节点 (B 命名空间)

绑定表示变量声明模式

  • b_identifier - 简单变量绑定
  • b_array - 数组解构模式
  • b_object - 对象解构模式
  • b_missing - 数组模式中的空位

内存管理

AST 通过NewStore 函数使用自定义内存分配策略。这会创建一个专门的区域分配器,将分配分组到块中,从而实现快速分配和批量取消分配。

来源:src/js_ast.zig41-191 src/js_ast.zig306-456 src/js_ast.zig475-545

代码生成和打印

js_printer.zig 文件负责将 AST 转换回 JavaScript 源代码。这用于

  • 转译器输出生成
  • 代码格式化和最小化
  • 源代码映射生成。
  • 打包创建

打印机架构

关键打印功能

打印机支持

  • 最小化(空格、标识符和语法)
  • 具有准确映射的源地图生成
  • 具有可配置缩进的代码格式化
  • 字符串转义和 Unicode 处理
  • JSX 输出转换
  • CommonJS/ESM 模块格式转换

来源:src/js_printer.zig427-497 src/js_printer.zig531-586

与打包器的集成

解析器通过几个关键接口与 Bun 的打包器集成

解析任务

打包器创建ParseTask 对象,这些对象封装了

  • 源文件信息
  • 解析选项和加载器类型
  • 依赖跟踪
  • 错误收集
  • AST 输出

工作池集成

依赖项解析

解析器识别导入/导出语句,并创建ImportRecord 对象,打包器使用这些对象进行

  • 模块解析
  • 依赖图构建
  • 代码拆分决策
  • 外部模块处理

来源:src/bundler/bundle_v2.zig274-394 src/bundler/bundle_v2.zig216-273