☰
grepai调用图提取技术揭秘:tree-sitter AST与正则双模式解析10+种编程语言
2026/10/11 3:20:22 网站建设 项目流程

grepai调用图提取技术揭秘:tree-sitter AST与正则双模式解析10+种编程语言

【免费下载链接】grepaiSemantic Search & Call Graphs for AI Agents (100% Local)项目地址: https://gitcode.com/gh_mirrors/gr/grepai

grepai 是一款 100% 本地运行的 AI 时代代码搜索工具,其调用图提取(Call Graph)能力可回答"谁调用了这个函数?这个函数又依赖谁?"这类关键问题。本文揭秘其底层实现:通过tree-sitter AST 精确解析与正则快速解析双模式引擎,支持 Go、Python、JavaScript、TypeScript 等10+ 种编程语言的符号提取与调用链追踪,全程无需任何云端服务。

为什么 AI Agent 需要调用图?

想象一下:你要修改ProcessPayment函数,但不敢确定它影响范围。grepai 的trace命令可以瞬间给出答案:

  • callers(调用者):谁在调用它?
  • callees(被调用者):它依赖哪些函数?
  • graph(调用图):以指定深度展开完整调用链

这正是 grepai 面向 AI Agent 场景设计的核心能力之一——用结构化上下文替代原始搜索结果,大幅降低 token 消耗。

双模式架构:一个接口,两种引擎

整个提取系统围绕一个统一接口设计,定义在 trace/trace.go:

type SymbolExtractor interface { ExtractSymbols(...) // 提取符号定义(函数、方法、类…) ExtractReferences(...) // 提取引用(函数调用、属性读写…) Mode() string // 返回 "fast" 或 "precise" }
模式引擎特点适用场景
⚡fast(默认)正则模式零额外依赖、速度极快大型代码库、日常使用
🔍precisetree-sitter AST 模式精确解析、可提取文档注释复杂代码、精度优先

一条命令即可切换:

grepai trace callers "Login" --mode fast grepai trace callers "Login" --mode precise

模式参数定义见 cli/trace.go,也可在.grepai/config.yaml中通过trace.mode固定配置。

正则模式:轻量而聪明的"快速通道"

每种语言一套模式表

正则模式的核心是一张语言模式注册表(trace/patterns.go),每种语言定义了五类定义模式(函数、方法、类、接口、类型)和两类调用模式(函数调用、方法调用)。以 Go 为例(trace/patterns.go):

// func FunctionName(params) Functions: regexp.MustCompile(`(?m)^func\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(`) // func (r *Receiver) MethodName(params) Methods: regexp.MustCompile(`(?m)^func\s+\(\w+\s+\*?([A-Za-z_][A-Za-z0-9_]*)\)\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(`)

提取器 trace/extractor.go 按扩展名匹配模式,从每个匹配中还原出符号名、行号、签名和是否导出等信息。

两个精巧的细节

  1. 注释与字符串屏蔽:正则匹配最怕"误伤"——注释里的foo()会被当成调用吗?不会。buildIgnoredMask(trace/extractor.go)先用一个状态机扫描全文,把行注释、块注释、字符串字面量全部标记为"忽略区",还专门处理了 F# 的(* *)嵌套块注释和 Lua 的--[[ ]]长字符串。

  2. 函数边界定位:调用图需要知道"这次调用发生在哪个函数体内"。边界检测按语言特性分三路走(trace/extractor.go):

    • 大括号语言(Go、JS、C、Rust…)→ 计数配对{},跳过字符串干扰
    • 缩进语言(Python、F#)→ 找到下一行缩进不深的语句
    • Lua → 追踪function到end的嵌套

连状态读写都能追踪

对 JavaScript/TypeScript,grepai 还额外提取属性读写引用:store.uid = ...算 write、this.count.value算 read,甚至识别 Vue/Pinia 的storeToRefs解构别名。这让前端状态流也能纳入分析——grepai refs readers "uid"就能找到所有读取该状态的位置。

tree-sitter 模式:AST 精确解析

precise 模式(trace/extractor_ts.go)为每种语言内置了 tree-sitter 语法解析器,直接遍历抽象语法树:

  • 按节点类型识别function_declaration、method_declaration等
  • 通过命名字段精准取符号名和接收者类型(Go 方法的 receiver)
  • 顺带提取docstring文档注释(trace/extractor_ts.go),为 AI 提供语义描述
  • 天然免疫正则的误报:注释、字符串里的"伪调用"在 AST 里根本不是调用节点

亮点:自研 F# 语法绑定

主流语言的解析器可直接引用现成库,但 F# 需要完整的语法文件。grepai 项目内直接维护了一份 F# tree-sitter 语法(fsharp/ 目录,其中parser.c是超过 80 万行的生成代码),通过 CGO 绑定接入(fsharp/binding.go)。这就是为什么精确模式能覆盖 C# 和 F# 这类少见的 .NET 语言。

💡 注意:precise 模式需要 CGO 依赖,须以treesitter构建标签编译;默认构建即为 fast 模式,开箱即用。

10+ 种语言支持一览

语言扩展名正则模式tree-sitter 模式
Go.go✅✅
TypeScript.ts.tsx✅✅
JavaScript.js.jsx✅✅
Python.py✅✅
PHP.php✅✅
C#.cs✅✅
F#.fs.fsx.fsi✅✅
C.c.h✅—
C++.cpp.hpp.cc.cxx✅—
Rust.rs✅—
Zig.zig✅—
Java.java✅—
Lua.lua✅—
Pascal/Delphi.pas.dpr✅—

完整列表参见官方文档 docs/src/content/docs/trace.md。

从符号到调用图:边是如何连起来的

数据流非常清晰:

  1. 符号索引:grepai watch启动守护进程,文件变更时自动增量提取
  2. 边构建:每条引用若能定位到所在函数(调用者),就生成一条CallEdge(调用者 → 被调用者,含文件与行号),逻辑见 trace/store.go
  3. 图查询:GetCallGraph从根符号出发按 BFS 逐层展开,--depth N控制深度
  4. 持久化:索引保存在项目本地的.grepai/symbols.gob,代码永远不出本机
grepai watch # 后台索引,自动保鲜 grepai trace callers "ValidateToken" # 谁调用了它? grepai trace graph "AuthMiddleware" --depth 2 --json # 结构化输出,喂给 AI

工作区模式下,--workspace还能跨项目聚合调用图——前端调后端 API 的完整链路一目了然。

总结

grepai 调用图提取的设计哲学可以概括为一句话:接口统一、双轨并行、本地闭环。

  • 🎯 正则模式负责"广"——14 种语言开箱即用,无依赖、速度快
  • 🧬 tree-sitter 模式负责"准"——AST 级别解析 + docstring,啃下复杂代码
  • 📊 所有结果落到.grepai/symbols.gob本地文件,AI Agent 通过--json即取即用

无论你是想评估一次重构的影响面,还是给 AI 喂上精准的调用上下文,这套双模式解析引擎都是背后可靠的支撑。

更多使用细节,可查看官方文档 docs/src/content/docs/trace.md 与快速上手指南 docs/src/content/docs/quickstart.md。

【免费下载链接】grepaiSemantic Search & Call Graphs for AI Agents (100% Local)项目地址: https://gitcode.com/gh_mirrors/gr/grepai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询