Mini Bash AST¶
从 2679 行的
src/utils/bash/ast.ts提炼到 ~200 行的 Visitor + Query 模式。 9 种 AST 节点 + 3 类查询(kind 枚举 / 谓词 / visitor 模式)。
文件¶
mini-bash-ast/
├── src/
│ ├── ast.ts AST 节点类型 + 构造器(~70 行)
│ ├── visitor.ts walk / children / findAll / query / toTree(~110 行)
│ └── cli.ts 6 个查询 demo(~90 行)
└── README.md
跑¶
输出 6 个 query:
1. findAll(sample, 'Command') —— 找所有命令
2. rm 调用安全检查
3. for 循环枚举(谓词)
4. pipeline 模式(a | b)
5. 危险模式 visitor 收集(rm / chmod / curl|sh)
6. 函数定义列表
真实代码对照¶
| Demo | 真实文件 | 简化 |
|---|---|---|
ast.ts |
bash/ast.ts:100 TsNode (~400 行) |
9 种节点 vs 真实 50+;无 span / metadata |
visitor.ts:walk |
bash/ast.ts:200 visitNode (~800 行) |
无 visitEnter/visitExit;不维护 scope |
findAll |
walkNode 变体 |
简化 collect 逻辑 |
query |
bash/ast.ts:1200 findByPredicate (~300 行) |
不支持 path 过滤 / parent ref |
核心 4 件套¶
1️⃣ 类型驱动 dispatch¶
Node = discriminated union(kind 字段),每个 kind 对应一个 visitor handler。新增节点时 TS 强制提示补 handler。
2️⃣ walk = visit + recurse¶
export function walk(node, visitor) {
const handler = visitor[node.kind];
if (handler) handler(node); // 先访问自己
for (const child of children(node)) // 再递归子节点
walk(child, visitor);
}
visitEnter / visitExit 两次回调支持 post-order。
3️⃣ children() = type-narrowing switch¶
返回 Node[],每个 case 走对应类型,TS 自动收窄(node.body 在 Program case 里是 Node[])。
4️⃣ Query = visitor 模式实例化¶
findAll(node, "Command")—— 注册一个 kind 收集器query(node, pred)—— 注册一个谓词收集器- 自定义 visitor —— 自由组合(安全检查 + AST 转换 + 计数等)
6 个 Query 演示¶
| Query | 用途 | 用到的 API |
|---|---|---|
| 1. 所有命令 | 静态分析入口 | findAll(node, "Command") |
| 2. rm 安全 | 危险命令检测 | findAll + .filter() |
| 3. for 循环 | 重构分析 | query(node, n => n.kind === "For") |
| 4. pipeline | 数据流追踪 | query(node, n => n.kind === "Pipe") |
| 5. 危险模式 | 安全审计 | walk(node, customVisitor) |
| 6. 函数列表 | 文档生成 | findAll(node, "FunctionDef") |
进阶练习¶
- 加 visitEnter/visitExit —— 父节点可访问子节点的修改
- 加 parent ref —— 节点带
parent: Node | null,便于反向查询 - 加 path filter ——
findAllByPath(node, ["If", "Program", "Command"])限定路径 - 加 AST 转换 ——
transform(node, visitor)返回新 AST(不可变) - 加 scope 分析 —— 跟踪变量定义/使用
- 结合 mini-bash-parser —— 真实解析 bash 脚本,再 query
相关阅读¶
- topics/deep-dive-bash-ast.md —— 2679 行完整分析
- topics/deep-dive-bash-parser.md —— 解析器
- mini-bash-parser/ —— 上游 parser demo