跳转至

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

npm install && npm start

输出 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);
}
DFS pre-order(先父后子)。真实代码用 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")

进阶练习

  1. 加 visitEnter/visitExit —— 父节点可访问子节点的修改
  2. 加 parent ref —— 节点带 parent: Node | null,便于反向查询
  3. 加 path filter —— findAllByPath(node, ["If", "Program", "Command"]) 限定路径
  4. 加 AST 转换 —— transform(node, visitor) 返回新 AST(不可变)
  5. 加 scope 分析 —— 跟踪变量定义/使用
  6. 结合 mini-bash-parser —— 真实解析 bash 脚本,再 query

相关阅读