tsl-devkit/lsp-server/src/language
csh cee6e614bf ♻️ 重构符号表相关内容
🚀 优化`ast`相关代码
2025-11-16 21:20:47 +08:00
..
ast ♻️ 重构符号表相关内容 2025-11-16 21:20:47 +08:00
keyword 重构语法树/符号表 2025-10-15 20:31:00 +08:00
symbol ♻️ 重构符号表相关内容 2025-11-16 21:20:47 +08:00
README.md 重构语法树/符号表 2025-10-15 20:31:00 +08:00

README.md

从反序列化到符号表 - 设计架构

📐 系统架构总览

┌─────────────────────────────────────────────────────────────────┐
│                         Source Code                              │
│                      (tsl)                             │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│                    Tree-sitter Parser                            │
│                 (外部依赖,生成 TSTree)                          │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
                    ┌────────┐
                    │ TSTree │  Parse Tree (CST)
                    │ TSNode │
                    └────┬───┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│                  AST 反序列化层 (ast/)                           │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  deserializer.hpp/cpp                                    │   │
│  │  - ParseRoot()                                           │   │
│  │  - ParseNode()                                           │   │
│  │  - ParseVarDeclaration(), ParseFunctionDefinition()...  │   │
│  └─────────────────────────────────────────────────────────┘   │
│                         │                                        │
│                         ▼                                        │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  types.hpp                                               │   │
│  │  - ASTNode (variant)                                     │   │
│  │  - VarDeclaration, FunctionDefinition, ClassDefinition  │   │
│  │  - Expression, Block, Signature, Parameter...           │   │
│  └─────────────────────────────────────────────────────────┘   │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
              ┌────────────────────┐
              │ vector<ASTNode>    │  抽象语法树
              │ ParseResult        │
              └──────┬─────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────────┐
│                 符号表构建层 (symbol/)                           │
│                                                                  │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  Phase 1: Collection (builder/collector.hpp/cpp)         │  │
│  │  - 遍历 AST                                              │  │
│  │  - 创建符号 (Variable, Function, Class...)              │  │
│  │  - 插入符号表                                            │  │
│  │  - 建立作用域层次                                        │  │
│  └──────────────────────────────────────────────────────────┘  │
│                         │                                        │
│                         ▼                                        │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  Phase 2: Resolution (builder/resolver.hpp/cpp)          │  │
│  │  - 解析 Unit 依赖关系                                    │  │
│  │  - 解析类继承关系                                        │  │
│  │  - 检测循环依赖                                          │  │
│  └──────────────────────────────────────────────────────────┘  │
│                         │                                        │
│                         ▼                                        │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  Phase 3: Validation (builder/validator.hpp/cpp)         │  │
│  │  - 验证类型引用                                          │  │
│  │  - 验证方法覆盖                                          │  │
│  │  - 验证访问权限                                          │  │
│  │  - 验证虚方法                                            │  │
│  └──────────────────────────────────────────────────────────┘  │
│                         │                                        │
│                         ▼                                        │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  Coordinator (builder/builder.hpp/cpp)                   │  │
│  │  - 协调三阶段流程                                        │  │
│  │  - 错误收集和报告                                        │  │
│  └──────────────────────────────────────────────────────────┘  │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
              ┌────────────────────┐
              │ SymbolRegistry     │  完整的符号表
              │ - GlobalScope      │
              │ - Units            │
              └──────┬─────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────────┐
│                      应用层                                      │
│  - LSP 服务 (代码补全、跳转定义、查找引用...)                   │
│  - 语义分析                                                      │
│  - 代码生成                                                      │
└─────────────────────────────────────────────────────────────────┘

🔄 数据流详解

1. 解析阶段 (Tree-sitter → AST)

Source Code
    │
    ├─→ Tree-sitter Parser
    │       │
    │       └─→ TSTree (Concrete Syntax Tree)
    │               │
    │               └─→ TSNode (每个语法节点)
    │
    └─→ AST Deserializer
            │
            ├─→ ParseRoot(TSNode, source)
            │       │
            │       └─→ ParseNode() 递归解析
            │               │
            │               ├─→ ParseVarDeclaration()
            │               ├─→ ParseFunctionDefinition()
            │               ├─→ ParseClassDefinition()
            │               └─→ ...
            │
            └─→ vector<ASTNode>
                    │
                    └─→ AST (抽象语法树)

关键点

  • Tree-sitter 生成 CST具体语法树包含所有语法细节
  • Deserializer 将 CST 转换为 AST抽象语法树去除语法细节
  • AST 使用 std::variant<...> 表示不同类型的节点

2. 符号表构建阶段 (AST → Symbol Table)

vector<ASTNode>
    │
    ├─→ Phase 1: Collection
    │       │
    │       ├─→ 遍历每个 ASTNode
    │       │       │
    │       │       ├─→ Visit(UnitDefinition)
    │       │       │       └─→ CreateUnit → AddUnit
    │       │       │
    │       │       ├─→ Visit(ClassDefinition)
    │       │       │       └─→ CreateClass → Insert
    │       │       │               │
    │       │       │               └─→ Visit(ClassMembers)
    │       │       │
    │       │       ├─→ Visit(FunctionDefinition)
    │       │       │       └─→ CreateFunction → InsertFunction
    │       │       │               │
    │       │       │               └─→ CollectFunctionBody
    │       │       │
    │       │       └─→ Visit(VarDeclaration)
    │       │               └─→ CreateVariable → Insert
    │       │
    │       └─→ 结果:带有符号但引用未解析的符号表
    │
    ├─→ Phase 2: Resolution
    │       │
    │       ├─→ ResolveUnitDependencies()
    │       │       │
    │       │       └─→ 对每个 Unit.uses 查找目标 Unit
    │       │               └─→ 检测循环依赖
    │       │
    │       └─→ ResolveClassHierarchy()
    │               │
    │               └─→ 对每个 Class.parent_names 查找父类
    │                       └─→ 检测循环继承
    │
    └─→ Phase 3: Validation
            │
            ├─→ ValidateTypeReferences()
            │       └─→ 检查所有类型名是否存在
            │
            ├─→ ValidateMethodOverrides()
            │       └─→ 检查 override 是否合法
            │
            └─→ ValidateVirtualMethods()
                    └─→ 检查虚方法表一致性

🏗️ 模块职责划分

📦 AST 模块 (ast/)

组件 职责 输入 输出
deserializer 将 Tree-sitter 的 CST 转换为 AST TSNode, source code vector
types 定义 AST 节点类型 - 类型定义

设计原则

  • 无状态转换(纯函数)
  • 错误容忍(收集错误而非中断)
  • 完整信息保留(位置、类型、文本)

📦 符号表模块 (symbol/)

🔹 core/ - 核心类型

文件 职责 关键类型
error 定义错误类型 ErrorKind, Error
symbol 定义所有符号类型 Symbol, Variable, Function, Class...
table 管理作用域和符号 Table, LookupResult
registry 管理全局资源 SymbolRegistry

🔹 builder/ - 构建流程

文件 职责 主要方法
reporter 收集和报告错误 Report(), GetErrors()
collector 阶段1: 收集符号 Collect(), Visit()
resolver 阶段2: 解析引用 Resolve(), ResolveUnitDependencies()
validator 阶段3: 验证完整性 Validate(), ValidateTypeReferences()
builder 协调三阶段流程 Build()

🔹 factory/ - 工厂和管理

文件 职责 主要功能
factory 创建符号实例 CreateVariable(), CreateClass()...
scope_manager 管理当前作用域 EnterScope(), ScopeGuard (RAII)

🔹 utils/ - 工具类

文件 职责 主要功能
type 类型操作工具 TypeFactory, TypeQuery, TypeFormatter
signature 签名操作工具 SignatureComparator, SignatureFormatter
class_member 成员查找 FindMember(), GetAllMethods()
class_hierarchy 层次分析 BuildVTable(), ValidateHierarchy()

🔗 模块间依赖关系

┌─────────────────────────────────────────────────────────┐
│                       Application                        │
└──────────────────────┬──────────────────────────────────┘
                       │ uses
                       ▼
┌─────────────────────────────────────────────────────────┐
│              symbol/builder/builder                      │
│              (SymbolTableBuilder)                        │
└───────┬──────────────────────────────────┬──────────────┘
        │ uses                              │ uses
        ▼                                   ▼
┌──────────────────┐              ┌──────────────────┐
│  symbol/builder/ │              │  symbol/core/    │
│  - collector     │◄─────────────│  - registry      │
│  - resolver      │  uses         │  - table         │
│  - validator     │              │  - symbol        │
│  - reporter      │              │  - error         │
└────────┬─────────┘              └────────┬─────────┘
         │ uses                             │
         ▼                                  │
┌──────────────────┐                       │
│  symbol/factory/ │◄──────────────────────┘
│  - factory       │  uses
│  - scope_manager │
└────────┬─────────┘
         │ uses
         ▼
┌──────────────────┐
│  symbol/utils/   │
│  - type          │
│  - signature     │
│  - class_member  │
│  - class_hierarchy│
└──────────────────┘

依赖规则

  • 上层模块依赖下层模块
  • builder 依赖 core, factory, utils
  • factory 依赖 core, utils
  • utils 依赖 core
  • core 无外部依赖(除了 ast

🎯 关键设计模式

1. Visitor 模式 (AST 遍历)

// Collector 访问 AST
class Collector {
    bool Visit(const ast::ASTNode& node) {
        if (auto* unit = std::get_if<ast::UnitDefinition>(&node))
            return CollectUnit(*unit);
        if (auto* cls = std::get_if<ast::ClassDefinition>(&node))
            return CollectClass(*cls);
        // ...
    }
};

优点

  • 分离数据结构和操作
  • 易于添加新的访问操作
  • 类型安全(使用 variant

2. Factory 模式 (符号创建)

// 统一的符号创建入口
class Factory {
    static VariablePtr CreateVariable(...);
    static FunctionPtr CreateFunction(...);
    static ClassPtr CreateClass(...);
};

优点

  • 统一创建逻辑
  • 易于维护和扩展
  • 可以添加缓存、验证等逻辑

3. RAII 模式 (作用域管理)

// 自动管理作用域切换
class ScopeGuard {
    ~ScopeGuard() { /* 自动恢复 */ }
};

// 使用
auto guard = scope_manager.EnterScope(new_scope);
// 作用域内操作
// guard 析构时自动恢复

优点

  • 异常安全
  • 自动资源管理
  • 避免忘记恢复

4. Builder 模式 (符号表构建)

class SymbolTableBuilder {
    bool Build(nodes) {
        Collector collector(...);
        collector.Collect(nodes);
        
        ReferenceResolver resolver(...);
        resolver.Resolve();
        
        Validator validator(...);
        validator.Validate();
    }
};

优点

  • 分步构建复杂对象
  • 易于理解和维护
  • 可以中断和恢复

5. Strategy 模式 (错误报告)

class ErrorReporter {
    void Report(ErrorKind kind, ...);
};

// 不同组件使用同一报告器
Collector collector(registry, reporter);
Resolver resolver(registry, reporter);
Validator validator(registry, reporter);

优点

  • 统一错误处理
  • 易于替换报告策略
  • 集中管理错误

📊 性能考虑

1. 时间复杂度

阶段 复杂度 说明
解析 O(n) n = 源代码大小
收集 O(m) m = AST 节点数
解析引用 O(u + c) u = Unit数, c = Class数
验证 O(s) s = 符号总数

总体O(n + m + s) ≈ O(n),线性时间

2. 空间复杂度

数据结构 空间 优化
AST O(m) 构建符号表后可释放
符号表 O(s) 使用智能指针共享
作用域树 O(d) d = 作用域深度,通常很小

总体O(n),线性空间

3. 优化技术

  • 增量更新:只重新解析修改的文件
  • 缓存:缓存符号查找结果
  • 延迟加载:按需加载 Unit 内容
  • 并行处理:独立 Unit 可并行构建

🛡️ 错误处理策略

错误分类

错误类型 严重性 处理
语法错误 Fatal Tree-sitter 处理
结构错误 Error 收集但继续
类型错误 Error 收集但继续
警告 Warning 记录不中断

错误恢复

错误发生
    │
    ├─→ 记录错误信息(位置、消息)
    │
    ├─→ 尝试继续处理
    │   └─→ 跳过当前节点
    │       或使用默认值
    │
    └─→ 返回 false 或 Error
            │
            └─→ 上层决定是否继续

原则

  • 尽可能收集多个错误
  • 不因一个错误而停止整个过程
  • 提供详细的错误位置和上下文

🔍 使用示例

完整流程

#include "ast/deserializer.hpp"
#include "symbol/builder/builder.hpp"

int main() {
    // 1. 解析源代码
    std::string source = ReadFile("program.pas");
    TSTree* tree = ts_parser_parse_string(parser, nullptr, 
                                          source.c_str(), 
                                          source.length());
    TSNode root = ts_tree_root_node(tree);
    
    // 2. 反序列化为 AST
    auto parse_result = ast::deserializer::ParseRoot(root, source);
    
    if (parse_result.HasErrors()) {
        // 处理解析错误
        for (const auto& error : parse_result.errors) {
            std::cerr << error.message << std::endl;
        }
    }
    
    // 3. 构建符号表
    symbol::SymbolTableBuilder builder;
    bool success = builder.Build(parse_result.nodes);
    
    if (!success) {
        // 处理符号表错误
        for (const auto& error : builder.GetErrors()) {
            std::cerr << error.ToString() << std::endl;
        }
        return 1;
    }
    
    // 4. 使用符号表
    auto& registry = builder.GetRegistry();
    
    // 查找符号
    auto result = registry.GlobalScope()->Lookup("MyClass");
    if (result) {
        auto* cls = dynamic_cast<symbol::Class*>(result.symbol);
        // 使用类信息...
    }
    
    // 查找 Unit
    auto unit = registry.FindUnit("System");
    if (unit) {
        // 使用 Unit 信息...
    }
    
    return 0;
}

📝 总结

核心理念

  1. 分层清晰:解析 → AST → 符号表,每层职责明确
  2. 错误容忍:收集所有错误,不因一个错误而停止
  3. 三阶段构建:收集 → 解析 → 验证,逐步完善符号表
  4. 类型安全:使用 variant, dynamic_cast 等确保类型安全
  5. 资源管理:使用智能指针和 RAII 自动管理资源

扩展点

  • 新的 AST 节点:在 types.hpp 添加类型,在 deserializer 添加解析
  • 新的符号类型:在 symbol.hpp 添加类型,在 factory 添加创建方法
  • 新的验证规则:在 validator 添加验证方法
  • 新的工具函数:在 utils/ 添加工具类

最佳实践

  • 保持模块职责单一
  • 使用前向声明减少编译依赖
  • 在 .cpp 文件中包含完整定义
  • 使用 RAII 管理资源
  • 收集错误而非立即中断