You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

70 lines
2.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// 极简符号表:记录局部变量定义点。
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
#include <memory>
#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; // 指向 Type 对象的智能指针
int scope_level = 0; // 定义时的作用域深度
int stack_offset = -1; // 局部变量/参数栈偏移(全局变量为 -1
bool is_initialized = false; // 是否已初始化
// 对于函数,额外存储参数列表(类型已包含在函数类型中,这里仅用于快速访问)
std::vector<std::shared_ptr<Type>> param_types;
// 对于常量,存储常量值(此处仅支持 int32
int const_value = 0;
// 关联的语法树节点(用于报错位置或进一步分析)
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<int>(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<Type> getTypeFromVarDef(SysYParser::VarDefContext* ctx);
static std::shared_ptr<Type> getTypeFromFuncDef(SysYParser::FuncDefContext* ctx);
private:
// 作用域栈:每个元素是一个从名字到符号的映射
std::vector<std::unordered_map<std::string, Symbol>> scopes_;
static constexpr int GLOBAL_SCOPE = 0; // 全局作用域索引
};