From a015a4bc306350fa88611ae4db53cb1b93b22dd8 Mon Sep 17 00:00:00 2001 From: mxr <> Date: Tue, 24 Mar 2026 16:30:39 +0800 Subject: [PATCH] =?UTF-8?q?fix(sem)=E4=BF=AE=E6=AD=A3=E7=AC=A6=E5=8F=B7?= =?UTF-8?q?=E8=A1=A8=E9=83=A8=E5=88=86=E7=9A=84=E7=BC=96=E8=AF=91=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/sem/SymbolTable.h | 2 +- src/sem/SymbolTable.cpp | 145 +++++++++++++++++++++++--------------- 2 files changed, 88 insertions(+), 59 deletions(-) diff --git a/include/sem/SymbolTable.h b/include/sem/SymbolTable.h index df5399b..360126d 100644 --- a/include/sem/SymbolTable.h +++ b/include/sem/SymbolTable.h @@ -7,7 +7,7 @@ #include #include "SysYParser.h" -#include "../ir/IR.h" +#include "ir/IR.h" // 符号种类 enum class SymbolKind { diff --git a/src/sem/SymbolTable.cpp b/src/sem/SymbolTable.cpp index e2b0da7..1b29f7f 100644 --- a/src/sem/SymbolTable.cpp +++ b/src/sem/SymbolTable.cpp @@ -1,4 +1,5 @@ #include "sem/SymbolTable.h" +#include // 用于访问父节点 // ---------- 构造函数 ---------- 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(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(parent)) { + return constDecl; + } + parent = parent->parent; + } + return nullptr; +} + +// 常量表达式求值(占位,需实现真正的常量折叠) +static int evaluateConstExp(SysYParser::ConstExpContext* ctx) { + // TODO: 实现常量折叠,目前返回0 + return 0; +} + +// 从 VarDefContext 构造类型 std::shared_ptr SymbolTable::getTypeFromVarDef(SysYParser::VarDefContext* ctx) { - // 这里需要根据实际的语法树结构来提取类型。 - // 假设 ctx 中包含类型节点和数组维度信息。 - // 以下代码为示意,具体实现需根据你的 SysY 语法定义调整。 - - // 1. 获取基本类型 - std::shared_ptr base_type; - // 假设 ctx 中有 type() 方法返回类型节点,且类型节点有 INT()、FLOAT() 等方法 - if (ctx->type()) { - if (ctx->type()->INT()) { + // 1. 获取基本类型(int/float) + std::shared_ptr 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 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 SymbolTable::getTypeFromFuncDef(SysYParser::FuncDefContext* ctx) { - // 提取返回类型 + // 1. 返回类型 std::shared_ptr 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> 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 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); } \ No newline at end of file