在日常开发中,我们写下的每一行代码最终都会被计算机执行。但计算机并不能直接"理解"人类书写的源代码——在这个转换过程中,有一个至关重要的中间角色:抽象语法树(Abstract Syntax Tree,简称 AST)


什么是抽象语法树?

抽象语法树是源代码的一种树状结构表示。它将代码中的每一个语法结构(如表达式、语句、函数声明等)抽象为树的节点,通过节点之间的父子关系来描述代码的层次结构。

"抽象"二字的含义在于:AST 并不需要保留源代码中所有的细节,例如括号、分号、空白符等对语义没有实质影响的内容都会被忽略,只保留代码的逻辑结构

举一个简单的例子,假设有如下表达式:

1 + 2 * 3

对应的 AST 结构大致如下:

    +
   / \
  1   *
     / \
    2   3

可以看到,乘法的优先级高于加法,这一规则在树的结构中得到了自然体现。


AST 是如何生成的?

AST 的生成通常分为两个阶段:

1. 词法分析(Lexical Analysis)

源代码首先会被"词法分析器"(Lexer)扫描,将字符流切分成一个个有意义的词法单元(Token),例如关键字、标识符、运算符、数字等。

2. 语法分析(Parsing)

词法单元随后被传入"语法分析器"(Parser),根据语言的语法规则,将 Token 序列组装成树状结构,最终生成 AST。


AST 有哪些实际应用?

AST 并不只是编译器内部的"黑盒",它在现代开发工具链中扮演着极为广泛的角色:

🔧 代码编译与转译

Babel 是前端开发中最典型的例子。它将现代 JavaScript(ES6+)代码解析为 AST,对节点进行转换,再重新生成兼容旧浏览器的代码。整个过程的核心就是对 AST 的操作。

✅ 代码静态分析与 Lint

ESLint、Pylint 等代码检查工具,通过遍历 AST 来检测潜在的错误、不符合规范的写法,而无需实际运行代码。

🎨 代码格式化

Prettier 等格式化工具将源代码解析为 AST 后,按照既定的风格规则重新"打印"出格式统一的代码。

💡 IDE 智能提示

代码编辑器的自动补全、跳转到定义、重构等功能,背后都依赖对 AST 的实时分析。

🔍 代码混淆与压缩

Terser、UglifyJS 等工具通过操作 AST 来删除无用代码、缩短变量名,从而压缩代码体积。


如何亲手探索 AST?

如果你想直观感受 AST 的结构,推荐使用在线工具 AST Explorer。只需在左侧输入任意代码,右侧就会实时展示对应的 AST 结构,支持多种语言和解析器。

对于想要在项目中使用 AST 的开发者,以下是一些常用库:

语言

常用解析库

JavaScript

@babel/parseracornespree

Python

内置 ast 模块

Java

JavaParser、Eclipse JDT

Go

go/ast 标准库


小结

抽象语法树是现代编程语言工具链的基石。理解 AST 的概念,不仅能帮助你更好地理解编译器、解释器的工作原理,还能让你在开发构建工具、代码分析工具时有更清晰的思路。

下次当你运行 babeleslint 时,不妨想一想——在这背后,正有一棵"抽象语法树"默默地完成着复杂的工作。