抽象语法书学习笔记

抽象语法树(AST)

核心提示:抽象语法树是编程语言中一个极其重要的概念,弄清楚它有助于后续深入理解编译原理、代码转译、babel 等技术。


一、概念拆解

当我们遇到一个难以理解的专业术语时,最简单的方式就是拆词。针对"抽象语法树",我们可以拆解为三个部分:

  1. 抽象
  2. 语法

接下来我们要做的就是针对这三个词逐一击破,只要把这三个词搞懂了,那么抽象语法树整体的概念也就能够理解了。


二、树(Tree)

2.1 什么是树

实际上是一种数据结构。

我们都知道计算机是用来处理数据的,处理数据的第一步就是先要将数据存储进去。那么存储数据的方式就有多种多样。

现实生活中的例子:比如我们有一个书柜(计算机)放 10 本书(数据),那么我放置这 10 本书的方式是多种多样的,我可以横着放、竖着放、斜着放。

所谓数据结构,实际上就是数据(书)在计算机(书柜)中组织和管理的一种方式。根据不同的场景,使用合适的数据结构能够帮助我们高效地对数据进行访问和操作。

2.2 数据结构的分类

数据结构从大类上分类,可以分为两大类:

1. 线性数据结构

数据以线性的方式来进行存储,这种结构又被称之为序列,每个数据在序列中最多只有一个前驱和后驱数据。

常见的线性数据结构:

类型 特点 典型应用
数组 连续存储空间中的固定大小集合,允许通过索引快速访问元素 需要频繁查找的场景
链表 由节点组成的线性集合,每个节点包含数据和指向下一个节点的指针 需要频繁插入删除的场景
遵循**后进先出(LIFO)**原则,操作都在栈顶进行 函数调用、撤销操作
队列 遵循**先进先出(FIFO)**原则,一端添加、另一端移除 任务队列、消息队列
2. 非线性数据结构

数据之间的存储和关系不是线性的。

常见的非线性数据结构:

类型 特点 典型应用
分层结构,有根节点,其余节点按层级组织,每个节点可有多个子节点 DOM树、文件系统
由顶点(节点)和边组成,边连接顶点,可有向或无向 社交网络、地图导航

2.3 没有完美的数据结构

核心原则:没有一种数据结构是完美的。假设有那么一种完美的数据结构,那么其他数据结构就没有存在的意义了。

数组 vs 链表的对比

  • 数组:在内存中是一段连续的地址

    • ✅ 查找效率高:通过下标可直接定位
    • ❌ 插入/删除效率低:需要移动后续元素
  • 链表:在内存中不连续存储,通过 next 字段指向下一个节点

    • ✅ 插入/删除效率高:只需修改指针
    • ❌ 查找效率低:需要遍历

2.4 树结构的优势

树这种非线性的数据结构在解决某些问题的时候,具有以下优点:

  1. 层次关系:自然表示数据之间的层次关系,如文件系统目录结构、组织结构、语法分析树等。
  2. 搜索效率 :对于二叉搜索树、AVL树、红黑树等,搜索、插入和删除操作的时间复杂度通常为 O(log n),比线性数据结构高得多。
  3. 动态数据集合:可以方便地添加、删除和重新组织节点,适合动态变化的数据集合。
  4. 有序存储:在有序树结构中,数据按一定顺序组织,可在 O(log n) 时间内完成查找最大值、最小值等操作。
  5. 空间优化:例如字典树(Trie)可存储大量字符串,公共前缀只存储一次,有效节省空间。
  6. 分治策略:树结构天然适应分治策略,可将复杂问题分解为较小的子问题并递归求解。

2.5 树的应用

正因为"树"这种数据结构有上述优点,所以你在很多地方都能看到它的身影:

  • DOM 树
  • CSSOM 树
  • Vue 模板树
  • 语法树(我们重点讨论的内容)

三、语法树

3.1 什么是语法树

语法树:简单来讲,就是将我们所写的代码转为树的结构。

3.2 从代码到 Token

假设有如下代码:

javascript 复制代码
var a = 42;
var b = 5;
function addA(d) {
  return a + d;
}
var c = addA(2) + b;

对于编译器或解释器来说,它们看不懂这些代码,这就是一段连续的字符串:

javascript 复制代码
'var a = 42;var b = 5;function addA(d) {return a + d;}var c = addA(2) + b;'

编译器或解释器会对代码进行整体扫描分析,分析出来:

  • 哪些是关键字(Keyword)
  • 哪些是标识符(Identifier)
  • 哪些是运算符(Punctuator)

形成一个一个的 token(最小的不可再拆分的单位)。

上面代码分析出的 token 序列:

复制代码
Keyword(var) Identifier(a) Punctuator(=) Numeric(42) Punctuator(;)
Keyword(var) Identifier(b) Punctuator(=) Numeric(5) Punctuator(;)
Keyword(function) Identifier(addA) Punctuator(() Identifier(d) Punctuator())
Punctuator({) Keyword(return) Identifier(a) Punctuator(+) Identifier(d)
Punctuator(;) Punctuator(}) Keyword(var) Identifier(c) Punctuator(=)
Identifier(addA) Punctuator(() Numeric(2) Punctuator()) Punctuator(+)
Identifier(b) Punctuator(;)

3.3 从 Token 到语法树

最终,会采用"树"这种数据结构来存储上面的 token 数据,形成一颗语法树

在线可视化工具https://www.jointjs.com/demos/abstract-syntax-tree

你可以将自己的源码放上去,看到对应源码所生成的语法树。


四、抽象

4.1 计算机科学中的"抽象"

重要区分:在计算机科学里面的"抽象"这个词和现实生活中"抽象"这个词的含义是不太相同的。

  • 现实生活中:"抽象"往往指"很模糊"的意思。
  • 计算机科学中 :抽象是一种思维方式,具体指的是从一个具体事物中提取出本质特征、概念和规律,忽略不相关的细节

这实际上是一种非常重要的方式,通过这种方式,我们可以将某个复杂的问题分解成更简单的、更纯粹的小问题,从而帮助我们更容易地解决复杂问题。

4.2 抽象在语法树中的体现

明白了抽象的概念之后,我们再来看抽象语法树。

在将源代码转换为树结构的时候,只会关注代码的结构和语法,会忽略具体的字符、空格、换行这些表达细节。像这些不重要的表达细节,在形成树结构的时候通通会被丢弃掉。


五、抽象语法树(AST)

5.1 定义

抽象语法树,是编程语言中一种树形的数据结构,用于表示源代码的语法结构。

5.2 核心特征

在 AST 中:

  • 每个节点代表源代码中的一个语法元素(如变量、表达式、语句等)
  • 描述了这些元素之间的层次关系
  • 采用抽象思想:只关注代码的结构和语法,忽略具体的字符、空格、换行等表达细节

5.3 价值与意义

通过这种抽象表示,我们可以:

  • ✅ 更方便地理解、分析和操作源代码
  • ✅ 无需直接处理文本格式的代码
  • ✅ 简化代码处理过程
  • ✅ 提高代码操作的精确性和可扩展性
  • ✅ 实现高效的代码优化和转换算法

5.4 应用领域

抽象语法树在以下领域具有广泛的应用:

  • 编译器和解释器设计
  • 代码分析(静态代码检查、代码审计)
  • 代码转换(Babel、TypeScript 编译)
  • 代码优化
  • 代码生成

六、总结

概念 核心含义
一种分层、非线性的数据结构,擅长表示层次关系
语法树 将代码转为树形结构的表示
抽象 忽略无关细节,只保留本质特征
AST 结合了树的结构、语法的表达、抽象的思想,是代码的结构化表示

一句话概括:抽象语法树就是忽略代码中的无关细节(空格、换行等),只保留代码的结构和语法信息,用树形数据结构来表示源代码。


相关推荐
墨黎芜7 小时前
ArcGIS从入门到精通——地图符号、注记的初步使用
学习·arcgis·信息可视化
小李云雾7 小时前
FastAPI重要知识点---中间件(Middleware)
学习·程序人生·中间件·fastapi·middleware
.Cnn7 小时前
JavaScript 前端基础笔记(网页交互核心)
前端·javascript·笔记·交互
小夏子_riotous7 小时前
Docker学习路径——3、常用命令
linux·运维·服务器·学习·docker·容器·centos
STLearner8 小时前
WSDM 2026 | 时间序列(Time Series)论文总结【预测,表示学习,因果】
大数据·论文阅读·人工智能·深度学习·学习·机器学习·数据挖掘
redaijufeng8 小时前
网络爬虫学习:应用selenium获取Edge浏览器版本号,自动下载对应版本msedgedriver,确保Edge浏览器顺利打开。
爬虫·学习·selenium
九成宫8 小时前
IT项目管理期末复习——Chapter 10 项目沟通管理
笔记·项目管理·软件工程
腾科IT教育8 小时前
零基础快速上岸HCIP,高效学习思路分享
学习·华为认证·hcip·hcip考试·hcip认证
23471021278 小时前
4.14 学习笔记
笔记·python·学习
醇氧8 小时前
【学习】软件过程模型全解析:从瀑布到敏捷的演进之路
学习·log4j