// 极简符号表:记录局部变量定义点。 #pragma once #include #include #include #include #include "SysYParser.h" #include "ir/IR.h" // 符号种类 enum class SymbolKind { Variable, Function, Parameter, Constant }; // 符号条目 struct Symbol { std::string name; SymbolKind kind; std::shared_ptr type; // 指向 Type 对象的智能指针 int scope_level = 0; // 定义时的作用域深度 int stack_offset = -1; // 局部变量/参数栈偏移(全局变量为 -1) bool is_initialized = false; // 是否已初始化 bool is_builtin = false; // 是否为库函数 // 对于函数,额外存储参数列表(类型已包含在函数类型中,这里仅用于快速访问) std::vector> param_types; // 对于常量,存储常量值(这里支持 int32 和 float) union ConstantValue { int i32; float f32; } const_value; bool is_int_const = true; // 标记常量类型,用于区分 int 和 float // 关联的语法树节点(用于报错位置或进一步分析) SysYParser::VarDefContext* var_def_ctx = nullptr; SysYParser::FuncDefContext* func_def_ctx = nullptr; }; class SymbolTable { public: SymbolTable(); ~SymbolTable() = default; // ----- 作用域管理 ----- void enterScope(); // 进入新作用域 void exitScope(); // 退出当前作用域 int currentScopeLevel() const { return static_cast(scopes_.size()) - 1; } // ----- 符号操作(推荐使用)----- bool addSymbol(const Symbol& sym); // 添加符号到当前作用域 Symbol* lookup(const std::string& name); // 从当前作用域向外查找 Symbol* lookupCurrent(const std::string& name); // 仅在当前作用域查找 // ----- 与原接口兼容(保留原有功能)----- void Add(const std::string& name, SysYParser::VarDefContext* decl); bool Contains(const std::string& name) const; SysYParser::VarDefContext* Lookup(const std::string& name) const; // ----- 辅助函数:从语法树节点构造 Type ----- static std::shared_ptr getTypeFromVarDef(SysYParser::VarDefContext* ctx); static std::shared_ptr getTypeFromFuncDef(SysYParser::FuncDefContext* ctx); void registerBuiltinFunctions(); private: // 作用域栈:每个元素是一个从名字到符号的映射 std::vector> scopes_; static constexpr int GLOBAL_SCOPE = 0; // 全局作用域索引 };