ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Esprima 语法树格式(AST)完全指南:ESTree 节点定义与位置信息

Esprima 语法树格式(AST)完全指南:ESTree 节点定义与位置信息 开发工具【免费下载链接】esprimaECMAScript parsing infrastructure for multipurpose analysis项目地址https://gitcode.com/gh_mirrors/es/esprima点击查看免费下载Esprima 是 ECMAScript 解析基础设施其输出的语法树Abstract Syntax Tree, AST格式继承自 Mozilla Parser API并经 ESTree 规范正式化与扩展。本文以 docs/syntax-tree-format.md 为骨架结合仓库src/nodes.ts、src/syntax.ts、src/parser.ts等源码实现系统梳理每一个 AST 节点的 TypeScript 接口定义、字段含义与真实输出形态帮助你在编写代码分析工具、转换器、linter 或自定义编译器时准确消费 Esprima 的解析结果。从 Mozilla Parser API 到 ESTree语法树的来源Esprima 的语法树格式并非凭空发明而是派生自 Mozilla Parser API 的原始版本随后被正式化并扩展为 ESTree 规范。因此任何基于 ESTree 的工具链如 Babel、ESLint 的解析器生态都能与 Esprima 的输出保持结构兼容。在后续小节中接口统一使用 TypeScript interface 语法描述。节点基座每个 AST 节点都是普通 JavaScript 对象Esprima 输出的 AST 中每个节点都是一个普通 JavaScript 对象实现如下基础接口interface Node { type: string; }type属性是包含节点变体类型名称的字符串例如Program、VariableDeclaration、CallExpression。类型名称常量集中定义在 src/syntax.ts 的Syntax对象中并在 src/nodes.ts 的各类构造函数中被引用如this.type Syntax.ArrayExpression保证type值在整个仓库中完全一致。当节点被标注位置信息见 syntactic-analysis.md 对应的loc/range选项时接口扩展为interface Node { type: string; range?: [number, number]; loc?: SourceLocation; }其中源位置定义如下interface Position { line: number; column: number; } interface SourceLocation { start: Position; end: Position; source?: string | null; }从实现上看src/parser.ts 中Parser构造函数会把options.range、options.loc、options.tokens、options.comment、options.tolerant等布尔选项读入config当config.loc为真且提供了options.source字符串时node.loc.source会携带该来源标识见 src/parser.ts 的finalize方法。range是[起始偏移, 结束偏移]的 UTF-16 码元索引对loc则记录行列号行从 1 计列从 0 计。测试夹具中的真实输出如 test/fixtures/JSX/simple-expression-container.tree.json展示了range与loc同时存在时的完整形态。Expressions and Patterns表达式与绑定模式绑定模式binding pattern用于解构语境只能是以下之一type BindingPattern ArrayPattern | ObjectPattern;表达式expression则可以是以下任意一种type Expression ThisExpression | Identifier | Literal | ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | ClassExpression | TaggedTemplateExpression | MemberExpression | Super | MetaProperty | NewExpression | CallExpression | UpdateExpression | AwaitExpression | UnaryExpression | BinaryExpression | LogicalExpression | ConditionalExpression | YieldExpression | AssignmentExpression | SequenceExpression;仓库中 src/nodes.ts 的类型联合union在此基础上还补充了ChainExpression、RegexLiteral、ComputedMemberExpression、StaticMemberExpression与异步函数变体说明 Esprima 对 ESTree 的实现在细节上略超前于本文档的基础集合。Array Pattern数组绑定模式interface ArrayPattern { type: ArrayPattern; elements: ArrayPatternElement[]; }其中type ArrayPatternElement AssignmentPattern | Identifier | BindingPattern | RestElement | null; interface RestElement { type: RestElement; argument: Identifier | BindingPattern; }null元素对应数组解构中的洞hole如const [, a] arr;中逗号间的空位RestElement对应...rest剩余元素src/nodes.ts。Assignment Pattern带默认值的绑定模式interface AssignmentPattern { type: AssignmentPattern; left: Identifier | BindingPattern; right: Expression; }用于function f(a 1)或解构默认值{a 1}。实现见 src/nodes.ts。Object Pattern对象绑定模式interface ObjectPattern { type: ObjectPattern; properties: Property[]; }仓库实现 src/nodes.ts 中properties实际为Property | RestElement即还支持{...rest}的对象剩余属性ES2018 rest-property见 test/fixtures/es2018/rest-property。This Expression、Identifier 与 Literalinterface ThisExpression { type: ThisExpression; } interface Identifier { type: Identifier; name: string; } interface Literal { type: Literal; value: boolean | number | string | RegExp | null; raw: string; regex?: { pattern: string, flags: string }; }要点Literal.value是运行时求值后的值如42、foo、null、trueraw保留源码中的原始文本如0xFF的 raw 为0xFFvalue 为255regex属性仅适用于正则表达式字面量携带pattern与flags。仓库中该场景由独立的 RegexLiteral 类生成其type仍为Literal。Array Expression 与 Object Expressioninterface ArrayExpression { type: ArrayExpression; elements: ArrayExpressionElement[]; }其中type ArrayExpressionElement Expression | SpreadElement;仓库中还允许null表示稀疏数组空洞见 src/nodes.ts。interface ObjectExpression { type: ObjectExpression; properties: Property[]; }其中Property定义如下interface Property { type: Property; key: Expression; computed: boolean; value: Expression | null; kind: get | set | init; method: false; shorthand: boolean; }字段语义computedtrue表示[key]计算属性kindget/set为访问器属性init为普通属性method文档中固定为false方法属性在 Esprima 中同样以PropertyFunctionExpression值表达仓库实现见 src/nodes.tsshorthandtrue表示{a}形式的简写属性ES6 object-literal-property-value-shorthand。Function Expression、Arrow Function Expression 与 Class Expressioninterface FunctionExpression { type: FunctionExpression; id: Identifier | null; params: FunctionParameter[]; body: BlockStatement; generator: boolean; async: boolean; expression: boolean; }FunctionParameter定义为AssignmentPattern | Identifier | BindingPattern。generator为true表示生成器函数表达式。expression恒为falseEsprima 用body字段区分函数体与表达式体箭头函数除外。interface ArrowFunctionExpression { type: ArrowFunctionExpression; id: Identifier | null; params: FunctionParameter[]; body: BlockStatement | Expression; generator: boolean; async: boolean; expression: false; }箭头函数的body可以是BlockStatement() {}或Expression() 1id恒为null。实现中expression布尔值由构造函数第三个参数传入src/nodes.tsasync恒为false异步箭头函数由AsyncArrowFunctionExpression生成但其type同样写为ArrowFunctionExpressionsrc/nodes.tsasync为true。interface ClassExpression { type: ClassExpression; id: Identifier | null; superClass: Identifier | null; body: ClassBody; }ClassBody与MethodDefinition如下interface ClassBody { type: ClassBody; body: MethodDefinition[]; } interface MethodDefinition { type: MethodDefinition; key: Expression | null; computed: boolean; value: FunctionExpression | null; kind: method | constructor; static: boolean; }注意ClassExpression.id、superClass在接口中标注为Identifier | null但 ES2015 的superClass实际可以是任意表达式class A extends mixin(B) {}仓库实现 src/nodes.ts 中其类型为Expression | null阅读输出时需兼容这一差异。Tagged Template Expressioninterface TaggedTemplateExpression { type: TaggedTemplateExpression; readonly tag: Expression; readonly quasi: TemplateLiteral; }模板相关节点interface TemplateElement { type: TemplateElement; value: { cooked: string; raw: string }; tail: boolean; } interface TemplateLiteral { type: TemplateLiteral; quasis: TemplateElement[]; expressions: Expression[]; }quasis为静态文本片段的TemplateElement数组expressions为插入表达式数组二者一一交错quasis 数量 expressions 数量 1。仓库中TemplateElement.value.cooked的类型为string | nullsrc/nodes.tstail标记是否为最后一个 quasi。Member Expression、Super 与 MetaPropertyinterface MemberExpression { type: MemberExpression; computed: boolean; object: Expression; property: Expression; } interface Super { type: Super; } interface MetaProperty { type: MetaProperty; meta: Identifier; property: Identifier; }MemberExpression.computeda.b为falsea[b]为true。实现中由StaticMemberExpressioncomputedfalse与ComputedMemberExpressioncomputedtrue两个类共同产出MemberExpressionsrc/nodes.ts、src/nodes.tsMetaProperty对应new.targetmeta为newproperty为targetfixture 见 test/fixtures/ES6/meta-property。Call / New Expressions、Import 与 SpreadElementinterface CallExpression { type: CallExpression; callee: Expression | Import; arguments: ArgumentListElement[]; } interface NewExpression { type: NewExpression; callee: Expression; arguments: ArgumentListElement[]; }辅助类型interface Import { type: Import; } type ArgumentListElement Expression | SpreadElement; interface SpreadElement { type: SpreadElement; argument: Expression; }Import节点对应动态import()ES2020 dynamic-importfixture 见 test/fixtures/es2018/dynamic-importSpreadElement对应展开参数f(...args)或数组展开[...a]。Update、Await、Unary、Binary、Logical、Conditional、Yield、Assignment、Sequence 表达式interface UpdateExpression { type: UpdateExpression; operator: | --; argument: Expression; prefix: boolean; } interface AwaitExpression { type: AwaitExpression; argument: Expression; } interface UnaryExpression { type: UnaryExpression; operator: | - | ~ | ! | delete | void | typeof; argument: Expression; prefix: true; } interface BinaryExpression { type: BinaryExpression; operator: instanceof | in | | - | * | / | % | ** | | | ^ | | | ! | | ! | | | | | | ; left: Expression; right: Expression; } interface LogicalExpression { type: LogicalExpression; operator: || | ; left: Expression; right: Expression; } interface ConditionalExpression { type: ConditionalExpression; test: Expression; consequent: Expression; alternate: Expression; } interface YieldExpression { type: YieldExpression; argument: Expression | null; delegate: boolean; } interface AssignmentExpression { type: AssignmentExpression; operator: | * | ** | / | % | | - | | | | | ^ | |; left: Expression; right: Expression; } interface SequenceExpression { type: SequenceExpression; expressions: Expression[]; }关键语义与实现要点UpdateExpression.prefix区分xtrue与xfalseUnaryExpression.prefix恒为true仓库对二元运算的归类值得注意BinaryExpression构造函数在运算符为||、以及??时会将type置为LogicalExpressionsrc/nodes.ts与文档中LogicalExpression单独成类的约定一致ES2020 空值合并??同样输出为LogicalExpressionYieldExpression.delegate为true表示yield*委托生成fixture 见 test/fixtures/ES6/yieldAwaitExpression与ForOfStatement.awaitfor await...of覆盖 ES2017 异步特性fixture 见 test/fixtures/es2017/async。Statements and Declarations语句与声明语句statement可以是以下任意一种type Statement BlockStatement | BreakStatement | ContinueStatement | DebuggerStatement | DoWhileStatement | EmptyStatement | ExpressionStatement | ForStatement | ForInStatement | ForOfStatement | FunctionDeclaration | IfStatement | LabeledStatement | ReturnStatement | SwitchStatement | ThrowStatement | TryStatement | VariableDeclaration | WhileStatement | WithStatement;声明declaration只能是type Declaration ClassDeclaration | FunctionDeclaration | VariableDeclaration;语句列表项statement list item则两者皆可type StatementListItem Declaration | Statement;仓库中 src/nodes.ts 将Declaration扩展为包含AsyncFunctionDeclaration、ExportDeclaration、ImportDeclarationStatement亦包含AsyncFunctionDeclaration与Directive子类型这是对模块语法的直接支撑。Block、Break、Continue、Debugger、Do-While、Empty 语句interface BlockStatement { type: BlockStatement; body: StatementListItem[]; } interface BreakStatement { type: BreakStatement; label: Identifier | null; } interface ContinueStatement { type: ContinueStatement; label: Identifier | null; } interface DebuggerStatement { type: DebuggerStatement; } interface DoWhileStatement { type: DoWhileStatement; body: Statement; test: Expression; } interface EmptyStatement { type: EmptyStatement; }BreakStatement/ContinueStatement的label在无标签跳转时为null。Class Declaration、Expression Statement 与指令序言interface ClassDeclaration { type: ClassDeclaration; id: Identifier | null; superClass: Identifier | null; body: ClassBody; } interface ExpressionStatement { type: ExpressionStatement; expression: Expression; directive?: string; }指令directive语义当表达式语句表示一条指令如use strict时directive属性会包含指令字符串。仓库中 Directive 类生成该节点type仍为ExpressionStatementparser 在parseDirective路径处理相关 fixture 见 test/fixtures/directive-prolog 与 ES2016 strict-directive。脚本开头的指令序列即“指令序言”directive prologue。For、For-In、For-Of 语句interface ForStatement { type: ForStatement; init: Expression | VariableDeclaration | null; test: Expression | null; update: Expression | null; body: Statement; } interface ForInStatement { type: ForInStatement; left: Expression | VariableDeclaration; right: Expression; body: Statement; each: false; } interface ForOfStatement { type: ForOfStatement; await: boolean; left: Expression | VariableDeclaration; right: Expression; body: Statement; }ForStatement.init/test/update在缺省时均为nullForInStatement.each恒为false历史遗留字段保留兼容ForOfStatement.await为true表示for await (x of y)ES2018fixture 见 test/fixtures/es2018/for-await-of。实现见 src/nodes.ts。Function Declaration、If、Labeled、Return、Switch 语句interface FunctionDeclaration { type: FunctionDeclaration; id: Identifier | null; params: FunctionParameter[]; body: BlockStatement; generator: boolean; async: boolean; expression: false; } interface IfStatement { type: IfStatement; test: Expression; consequent: Statement; alternate?: Statement; } interface LabeledStatement { type: LabeledStatement; label: Identifier; body: Statement; } interface ReturnStatement { type: ReturnStatement; argument: Expression | null; } interface SwitchStatement { type: SwitchStatement; discriminant: Expression; cases: SwitchCase[]; }SwitchCase辅助类型interface SwitchCase { type: SwitchCase; test: Expression | null; consequent: Statement[]; }注意IfStatement.alternate与SwitchCase.testdefault分支在缺省时为null或省略。Throw、Try 与 Catchinterface ThrowStatement { type: ThrowStatement; argument: Expression; } interface TryStatement { type: TryStatement; block: BlockStatement; handler: CatchClause | null; finalizer: BlockStatement | null; } interface CatchClause { type: CatchClause; param: Identifier | BindingPattern; body: BlockStatement; }ES2019 的可选 catch 绑定try {} catch {}对应handler.param为nullfixture 见 test/fixtures/es2019/optional-catch-binding仓库实现 src/nodes.ts 中param类型已允许null。Variable Declarationinterface VariableDeclaration { type: VariableDeclaration; declarations: VariableDeclarator[]; kind: var | const | let; } interface VariableDeclarator { type: VariableDeclarator; id: Identifier | BindingPattern; init: Expression | null; }kind只能是var/const/letVariableDeclarator.init在var a;这类无初始化器声明时为null。实现见 src/nodes.ts。While 与 With 语句interface WhileStatement { type: WhileStatement; test: Expression; body: Statement; } interface WithStatement { type: WithStatement; object: Expression; body: Statement; }Scripts and Modules脚本与模块程序Program要么是脚本要么是模块interface Program { type: Program; sourceType: script; body: StatementListItem[]; } interface Program { type: Program; sourceType: module; body: ModuleItem[]; }辅助类型type StatementListItem Declaration | Statement; type ModuleItem ImportDeclaration | ExportDeclaration | StatementListItem;仓库中 Script 与 Module 两个类分别产出sourceType为script/module的Program节点。入口 src/esprima.ts 通过options.sourceType决定调用parseModule()还是parseScript()并暴露了parseModule/parseScript便捷函数parse()在收集注释、token 或容错模式下还会向Program追加comments、tokens、errors数组src/esprima.ts。Import Declaration导入声明type ImportDeclaration { type: ImportDeclaration; specifiers: ImportSpecifier[]; source: Literal; }interface ImportSpecifier { type: ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier; local: Identifier; imported?: Identifier; }三种 specifier 形态ImportSpecifier具名导入import { a as b } from mlocal为本地名imported为源模块导出名ImportDefaultSpecifier默认导入import a from m仅含localImportNamespaceSpecifier命名空间导入import * as ns from m仅含local。实现分别见 src/nodes.tsfixture 见 test/fixtures/ES6/import-declaration。Export Declaration导出声明导出声明可以是批量batch、默认default或具名named三种形式type ExportDeclaration ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration;interface ExportAllDeclaration { type: ExportAllDeclaration; source: Literal; } interface ExportDefaultDeclaration { type: ExportDefaultDeclaration; declaration: Identifier | BindingPattern | ClassDeclaration | Expression | FunctionDeclaration; } interface ExportNamedDeclaration { type: ExportNamedDeclaration; declaration: ClassDeclaration | FunctionDeclaration | VariableDeclaration; specifiers: ExportSpecifier[]; source: Literal; }interface ExportSpecifier { type: ExportSpecifier; exported: Identifier; local: Identifier; };ExportAllDeclarationexport * from m仅含sourceExportDefaultDeclarationexport default ...declaration可以是表达式、标识符、类/函数声明或绑定模式ExportNamedDeclarationexport { a as b }含specifiers或export const x 1含declaration配合source即为export { a } from m的重导出。仓库实现 src/nodes.ts 中ExportNamedDeclaration.declaration与source的类型允许为null而ExportSpecifier.exported为导出名、local为本地名。对应测试覆盖见 test/fixtures/ES6/export-declaration。实战从源码验证语法树格式要在本地观察 Esprima 的输出可结合 getting-started.md 运行# 在仓库根目录执行输出带 range/loc 的完整 AST node -e const esprima require(./dist/esprima); const ast esprima.parseScript(const answer 42;, { range: true, loc: true }); console.log(JSON.stringify(ast, null, 2)); 输出顶层结构为ProgramsourceType为scriptbody中包含VariableDeclarationkind: const与VariableDeclarator其init为Literalvalue: 42与本文各节接口完全对应。需要定位的验证依据速查关注点仓库证据节点类型常量src/syntax.ts全部节点类实现src/nodes.ts位置信息range/loc注入src/parser.ts解析入口与选项处理src/esprima.ts真实 AST 输出样例test/fixtures/JSX/simple-expression-container.tree.json小结Esprima 的语法树格式以 ESTree 为规范骨架通过type字段区分节点变体以可选range/loc携带精确位置信息。本文完整梳理了表达式、语句/声明、脚本/模块三大类约 40 种节点接口掌握Literal的raw与value分离、Property.kind/computed/shorthand语义、Directive与ExpressionStatement的关系、Program.sourceType区分脚本与模块以及Import/Export系列声明结构即可从容解析 Esprima 的任意输出并在此基础上构建自己的静态分析、代码转换或格式化工具。赞分享开发工具【免费下载链接】esprimaECMAScript parsing infrastructure for multipurpose analysis项目地址https://gitcode.com/gh_mirrors/es/esprima点击查看免费下载相关推荐如何用Get Shit Done解决AI编程的上下文衰退难题架构深度解析与工程实践如何用Get Shit Done解决AI编程的上下文衰退难题架构深度解析与工程实践 在AI编程工具日益普及的今天开发者面临着一个普遍却致命的问题上下文衰退人工智能AI 应用提示工程开发工具工作流自动化AI AgentMaLiang API完全指南掌握iOS Metal绘图的核心类与最佳实践MaLiang API完全指南掌握iOS Metal绘图的核心类与最佳实践 MaLiang是一款基于Metal的iOS绘图库为开发者提供了高效、灵活的涂鸦和create-guten-block核心功能揭秘为什么它是WordPress开发者的必备工具create guten block核心功能揭秘为什么它是WordPress开发者的必备工具 在WordPress Gutenberg编辑器时代开发自定义区上一篇告别Python代码格式混乱VSCode与PyCharm集成YAPF的超实用方案下一篇Snap.svg SVG元素复制终极指南copy.js完整使用教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表