本文档涵盖了 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 在内的多种解析模式,并带有不同的功能标志。
主要的词法分析器结构包含
current、start、end 位置token - 来自T 命名空间中的当前词元类型code_point - 当前正在处理的 Unicode 码点identifier - 标识符词元的文本js_lexer_tables.zig 中T 命名空间定义了所有词元类型
t_string_literal、t_numeric_literal、t_big_integer_literalt_function、t_class、t_if、t_for 等。t_plus、t_minus、t_equals_equals 等。t_open_paren、t_close_paren、t_semicolon 等。t_end_of_file、t_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 支持
JSX 解析已集成到表达式解析器中
来源:src/js_parser.zig167-485 src/js_parser.zig528-587
AST 使用三种主要节点类型构建:表达式(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 源代码。这用于
打印机支持
来源:src/js_printer.zig427-497 src/js_printer.zig531-586
解析器通过几个关键接口与 Bun 的打包器集成
打包器创建ParseTask 对象,这些对象封装了
解析器识别导入/导出语句,并创建ImportRecord 对象,打包器使用这些对象进行
来源:src/bundler/bundle_v2.zig274-394 src/bundler/bundle_v2.zig216-273