|
|
|
|
@ -1,17 +1,147 @@
|
|
|
|
|
// 维护局部变量声明的注册与查找。
|
|
|
|
|
|
|
|
|
|
#include "sem/SymbolTable.h"
|
|
|
|
|
|
|
|
|
|
void SymbolTable::Add(const std::string& name,
|
|
|
|
|
SysYParser::VarDefContext* decl) {
|
|
|
|
|
table_[name] = decl;
|
|
|
|
|
// ---------- 构造函数 ----------
|
|
|
|
|
SymbolTable::SymbolTable() {
|
|
|
|
|
// 初始化全局作用域
|
|
|
|
|
scopes_.emplace_back();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------- 作用域管理 ----------
|
|
|
|
|
void SymbolTable::enterScope() {
|
|
|
|
|
scopes_.emplace_back();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SymbolTable::exitScope() {
|
|
|
|
|
if (scopes_.size() > 1) {
|
|
|
|
|
scopes_.pop_back();
|
|
|
|
|
}
|
|
|
|
|
// 不能退出全局作用域
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------- 符号添加与查找 ----------
|
|
|
|
|
bool SymbolTable::addSymbol(const Symbol& sym) {
|
|
|
|
|
auto& current_scope = scopes_.back();
|
|
|
|
|
if (current_scope.find(sym.name) != current_scope.end()) {
|
|
|
|
|
return false; // 重复定义
|
|
|
|
|
}
|
|
|
|
|
current_scope[sym.name] = sym;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Symbol* SymbolTable::lookup(const std::string& name) {
|
|
|
|
|
// 从当前作用域向外层查找
|
|
|
|
|
for (auto it = scopes_.rbegin(); it != scopes_.rend(); ++it) {
|
|
|
|
|
auto& scope = *it;
|
|
|
|
|
auto found = scope.find(name);
|
|
|
|
|
if (found != scope.end()) {
|
|
|
|
|
return &found->second;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Symbol* SymbolTable::lookupCurrent(const std::string& name) {
|
|
|
|
|
auto& current_scope = scopes_.back();
|
|
|
|
|
auto it = current_scope.find(name);
|
|
|
|
|
if (it != current_scope.end()) {
|
|
|
|
|
return &it->second;
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------- 兼容原接口 ----------
|
|
|
|
|
void SymbolTable::Add(const std::string& name, SysYParser::VarDefContext* decl) {
|
|
|
|
|
Symbol sym;
|
|
|
|
|
sym.name = name;
|
|
|
|
|
sym.kind = SymbolKind::Variable;
|
|
|
|
|
sym.type = getTypeFromVarDef(decl);
|
|
|
|
|
sym.var_def_ctx = decl;
|
|
|
|
|
sym.scope_level = currentScopeLevel();
|
|
|
|
|
addSymbol(sym);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SymbolTable::Contains(const std::string& name) const {
|
|
|
|
|
return table_.find(name) != table_.end();
|
|
|
|
|
// const 方法不能修改 scopes_,我们模拟查找
|
|
|
|
|
for (auto it = scopes_.rbegin(); it != scopes_.rend(); ++it) {
|
|
|
|
|
if (it->find(name) != it->end()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SysYParser::VarDefContext* SymbolTable::Lookup(const std::string& name) const {
|
|
|
|
|
auto it = table_.find(name);
|
|
|
|
|
return it == table_.end() ? nullptr : it->second;
|
|
|
|
|
for (auto it = scopes_.rbegin(); it != scopes_.rend(); ++it) {
|
|
|
|
|
auto found = it->find(name);
|
|
|
|
|
if (found != it->end()) {
|
|
|
|
|
// 只返回变量定义的上下文(函数等其他符号返回 nullptr)
|
|
|
|
|
if (found->second.kind == SymbolKind::Variable) {
|
|
|
|
|
return found->second.var_def_ctx;
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------- 辅助函数:从语法树节点构造 Type ----------
|
|
|
|
|
std::shared_ptr<Type> SymbolTable::getTypeFromVarDef(SysYParser::VarDefContext* ctx) {
|
|
|
|
|
// 这里需要根据实际的语法树结构来提取类型。
|
|
|
|
|
// 假设 ctx 中包含类型节点和数组维度信息。
|
|
|
|
|
// 以下代码为示意,具体实现需根据你的 SysY 语法定义调整。
|
|
|
|
|
|
|
|
|
|
// 1. 判断基本类型(int / float / void 等)
|
|
|
|
|
std::shared_ptr<Type> base_type;
|
|
|
|
|
if (ctx->type() && ctx->type()->INT()) {
|
|
|
|
|
base_type = Type::GetInt32Type();
|
|
|
|
|
} else if (ctx->type() && ctx->type()->FLOAT()) {
|
|
|
|
|
// 若你扩展了 float 类型,可类似处理
|
|
|
|
|
// base_type = Type::GetFloatType();
|
|
|
|
|
} else {
|
|
|
|
|
// 默认为 int
|
|
|
|
|
base_type = Type::GetInt32Type();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 处理数组维度
|
|
|
|
|
// 假设 ctx 中有 arraySpecifier() 返回维度列表,每个维度是一个表达式节点
|
|
|
|
|
// 这里简单假设维度值在语法树中已经计算好,并存储在某个 vector 中
|
|
|
|
|
std::vector<int> dims;
|
|
|
|
|
// 示意:遍历数组维度节点,将常量值推入 dims
|
|
|
|
|
// for (auto dimNode : ctx->arraySpecifier()) {
|
|
|
|
|
// dims.push_back(parseConstExpr(dimNode));
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
if (dims.empty()) {
|
|
|
|
|
// 非数组,直接返回基本类型
|
|
|
|
|
return base_type;
|
|
|
|
|
} else {
|
|
|
|
|
// 数组类型:递归构建数组类型
|
|
|
|
|
// 注意:Type::GetArrayType 需要元素类型和维度列表
|
|
|
|
|
return Type::GetArrayType(base_type, dims);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<Type> SymbolTable::getTypeFromFuncDef(SysYParser::FuncDefContext* ctx) {
|
|
|
|
|
// 提取返回类型
|
|
|
|
|
std::shared_ptr<Type> ret_type;
|
|
|
|
|
if (ctx->type() && ctx->type()->VOID()) {
|
|
|
|
|
ret_type = Type::GetVoidType();
|
|
|
|
|
} else if (ctx->type() && ctx->type()->INT()) {
|
|
|
|
|
ret_type = Type::GetInt32Type();
|
|
|
|
|
} else {
|
|
|
|
|
ret_type = Type::GetInt32Type(); // 默认
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 提取参数类型列表
|
|
|
|
|
std::vector<std::shared_ptr<Type>> param_types;
|
|
|
|
|
if (ctx->paramList()) {
|
|
|
|
|
for (auto param : ctx->paramList()->param()) {
|
|
|
|
|
// 假设 param 包含类型信息
|
|
|
|
|
// 这里简单构建 int 类型,实际需根据参数声明解析
|
|
|
|
|
param_types.push_back(Type::GetInt32Type());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建函数类型
|
|
|
|
|
return Type::GetFunctionType(ret_type, param_types);
|
|
|
|
|
}
|
|
|
|
|
|