|
|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
#include "sem/SymbolTable.h"
|
|
|
|
|
#include <antlr4-runtime.h> // 用于访问父节点
|
|
|
|
|
|
|
|
|
|
// ---------- 构造函数 ----------
|
|
|
|
|
SymbolTable::SymbolTable() {
|
|
|
|
|
@ -84,90 +85,118 @@ SysYParser::VarDefContext* SymbolTable::Lookup(const std::string& name) const {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------- 辅助函数:从语法树节点构造 Type ----------
|
|
|
|
|
// ---------- 辅助函数:从 VarDefContext 获取外层 VarDeclContext ----------
|
|
|
|
|
static SysYParser::VarDeclContext* getOuterVarDecl(SysYParser::VarDefContext* varDef) {
|
|
|
|
|
auto parent = varDef->parent;
|
|
|
|
|
while (parent) {
|
|
|
|
|
if (auto varDecl = dynamic_cast<SysYParser::VarDeclContext*>(parent)) {
|
|
|
|
|
return varDecl;
|
|
|
|
|
}
|
|
|
|
|
parent = parent->parent;
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------- 辅助函数:从 VarDefContext 获取外层 ConstDeclContext(常量定义)----------
|
|
|
|
|
static SysYParser::ConstDeclContext* getOuterConstDecl(SysYParser::VarDefContext* varDef) {
|
|
|
|
|
auto parent = varDef->parent;
|
|
|
|
|
while (parent) {
|
|
|
|
|
if (auto constDecl = dynamic_cast<SysYParser::ConstDeclContext*>(parent)) {
|
|
|
|
|
return constDecl;
|
|
|
|
|
}
|
|
|
|
|
parent = parent->parent;
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 常量表达式求值(占位,需实现真正的常量折叠)
|
|
|
|
|
static int evaluateConstExp(SysYParser::ConstExpContext* ctx) {
|
|
|
|
|
// TODO: 实现常量折叠,目前返回0
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从 VarDefContext 构造类型
|
|
|
|
|
std::shared_ptr<ir::Type> SymbolTable::getTypeFromVarDef(SysYParser::VarDefContext* ctx) {
|
|
|
|
|
// 这里需要根据实际的语法树结构来提取类型。
|
|
|
|
|
// 假设 ctx 中包含类型节点和数组维度信息。
|
|
|
|
|
// 以下代码为示意,具体实现需根据你的 SysY 语法定义调整。
|
|
|
|
|
|
|
|
|
|
// 1. 获取基本类型
|
|
|
|
|
std::shared_ptr<ir::Type> base_type;
|
|
|
|
|
// 假设 ctx 中有 type() 方法返回类型节点,且类型节点有 INT()、FLOAT() 等方法
|
|
|
|
|
if (ctx->type()) {
|
|
|
|
|
if (ctx->type()->INT()) {
|
|
|
|
|
// 1. 获取基本类型(int/float)
|
|
|
|
|
std::shared_ptr<ir::Type> base_type = nullptr;
|
|
|
|
|
auto varDecl = getOuterVarDecl(ctx);
|
|
|
|
|
if (varDecl) {
|
|
|
|
|
auto bType = varDecl->bType();
|
|
|
|
|
if (bType->Int()) {
|
|
|
|
|
base_type = ir::Type::GetInt32Type();
|
|
|
|
|
} else if (ctx->type()->FLOAT()) {
|
|
|
|
|
} else if (bType->Float()) {
|
|
|
|
|
base_type = ir::Type::GetFloatType();
|
|
|
|
|
} else {
|
|
|
|
|
// 默认为 int
|
|
|
|
|
base_type = ir::Type::GetInt32Type();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
base_type = ir::Type::GetInt32Type(); // 默认
|
|
|
|
|
auto constDecl = getOuterConstDecl(ctx);
|
|
|
|
|
if (constDecl) {
|
|
|
|
|
auto bType = constDecl->bType();
|
|
|
|
|
if (bType->Int()) {
|
|
|
|
|
base_type = ir::Type::GetInt32Type();
|
|
|
|
|
} else if (bType->Float()) {
|
|
|
|
|
base_type = ir::Type::GetFloatType();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!base_type) {
|
|
|
|
|
base_type = ir::Type::GetInt32Type(); // 默认 int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 处理数组维度
|
|
|
|
|
// 假设 ctx 中有 arraySpecifier() 返回维度列表,每个维度是一个表达式节点
|
|
|
|
|
// 这里简单假设维度值在语法树中已经计算好,并存储在某个 vector 中
|
|
|
|
|
// 2. 解析数组维度(从 varDef 的 constExp 列表获取)
|
|
|
|
|
std::vector<int> dims;
|
|
|
|
|
// 示意:遍历数组维度节点,将常量值推入 dims
|
|
|
|
|
// for (auto dimNode : ctx->arraySpecifier()) {
|
|
|
|
|
// dims.push_back(parseConstExpr(dimNode));
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
if (dims.empty()) {
|
|
|
|
|
// 非数组,直接返回基本类型
|
|
|
|
|
return base_type;
|
|
|
|
|
} else {
|
|
|
|
|
// 数组类型:递归构建数组类型
|
|
|
|
|
// 注意:Type::GetArrayType 需要元素类型和维度列表
|
|
|
|
|
for (auto constExp : ctx->constExp()) {
|
|
|
|
|
int dimVal = evaluateConstExp(constExp);
|
|
|
|
|
dims.push_back(dimVal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!dims.empty()) {
|
|
|
|
|
return ir::Type::GetArrayType(base_type, dims);
|
|
|
|
|
}
|
|
|
|
|
return base_type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从 FuncDefContext 构造函数类型
|
|
|
|
|
std::shared_ptr<ir::Type> SymbolTable::getTypeFromFuncDef(SysYParser::FuncDefContext* ctx) {
|
|
|
|
|
// 提取返回类型
|
|
|
|
|
// 1. 返回类型
|
|
|
|
|
std::shared_ptr<ir::Type> ret_type;
|
|
|
|
|
if (ctx->type()) {
|
|
|
|
|
if (ctx->type()->VOID()) {
|
|
|
|
|
ret_type = ir::Type::GetVoidType();
|
|
|
|
|
} else if (ctx->type()->INT()) {
|
|
|
|
|
ret_type = ir::Type::GetInt32Type();
|
|
|
|
|
} else if (ctx->type()->FLOAT()) {
|
|
|
|
|
ret_type = ir::Type::GetFloatType();
|
|
|
|
|
} else {
|
|
|
|
|
ret_type = ir::Type::GetInt32Type(); // 默认
|
|
|
|
|
}
|
|
|
|
|
auto funcType = ctx->funcType();
|
|
|
|
|
if (funcType->Void()) {
|
|
|
|
|
ret_type = ir::Type::GetVoidType();
|
|
|
|
|
} else if (funcType->Int()) {
|
|
|
|
|
ret_type = ir::Type::GetInt32Type();
|
|
|
|
|
} else if (funcType->Float()) {
|
|
|
|
|
ret_type = ir::Type::GetFloatType();
|
|
|
|
|
} else {
|
|
|
|
|
ret_type = ir::Type::GetInt32Type(); // 默认
|
|
|
|
|
ret_type = ir::Type::GetInt32Type(); // fallback
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 提取参数类型列表
|
|
|
|
|
// 2. 参数类型
|
|
|
|
|
std::vector<std::shared_ptr<ir::Type>> param_types;
|
|
|
|
|
if (ctx->paramList()) {
|
|
|
|
|
for (auto param : ctx->paramList()->param()) {
|
|
|
|
|
// 根据参数声明构建类型
|
|
|
|
|
// 这里假设每个参数有类型节点,并且可能包含数组维度
|
|
|
|
|
auto fParams = ctx->funcFParams();
|
|
|
|
|
if (fParams) {
|
|
|
|
|
for (auto param : fParams->funcFParam()) {
|
|
|
|
|
std::shared_ptr<ir::Type> param_type;
|
|
|
|
|
if (param->type()) {
|
|
|
|
|
if (param->type()->INT()) {
|
|
|
|
|
param_type = ir::Type::GetInt32Type();
|
|
|
|
|
} else if (param->type()->FLOAT()) {
|
|
|
|
|
param_type = ir::Type::GetFloatType();
|
|
|
|
|
} else {
|
|
|
|
|
param_type = ir::Type::GetInt32Type();
|
|
|
|
|
}
|
|
|
|
|
auto bType = param->bType();
|
|
|
|
|
if (bType->Int()) {
|
|
|
|
|
param_type = ir::Type::GetInt32Type();
|
|
|
|
|
} else if (bType->Float()) {
|
|
|
|
|
param_type = ir::Type::GetFloatType();
|
|
|
|
|
} else {
|
|
|
|
|
param_type = ir::Type::GetInt32Type();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理数组参数(如果存在维度)
|
|
|
|
|
// if (param->arraySpecifier()) { ... }
|
|
|
|
|
|
|
|
|
|
// 处理数组参数:如果存在 [ ] 或 [ exp ],退化为指针
|
|
|
|
|
if (param->L_BRACK().size() > 0) {
|
|
|
|
|
if (param_type->IsInt32()) {
|
|
|
|
|
param_type = ir::Type::GetPtrInt32Type();
|
|
|
|
|
} else if (param_type->IsFloat()) {
|
|
|
|
|
param_type = ir::Type::GetPtrFloatType();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
param_types.push_back(param_type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建函数类型
|
|
|
|
|
return ir::Type::GetFunctionType(ret_type, param_types);
|
|
|
|
|
}
|