From c945a61f90f5ebfffc3e5f9357162af96cd6a621 Mon Sep 17 00:00:00 2001 From: mxr <> Date: Sat, 28 Mar 2026 17:08:41 +0800 Subject: [PATCH] =?UTF-8?q?fix(sem)=E8=A7=A3=E5=86=B3=E6=95=B0=E7=BB=84?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E7=BB=91=E5=AE=9A=E7=BC=BA=E5=A4=B1=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/irgen/IRGenExp.cpp | 9 -------- src/sem/Sema.cpp | 46 +++++++++++++++++++++++++++++++++++++++++ src/sem/SymbolTable.cpp | 14 +++++++++++++ 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/irgen/IRGenExp.cpp b/src/irgen/IRGenExp.cpp index 5e86d9b..c3518b7 100644 --- a/src/irgen/IRGenExp.cpp +++ b/src/irgen/IRGenExp.cpp @@ -121,15 +121,6 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) { // 首先尝试从语义分析获取变量定义 auto* var_decl = sema_.ResolveVarUse(ctx); - // 从语义分析获取变量定义 - auto* decl = sema_.ResolveVarUse(ctx); - if (!decl) { - auto* const_def = sema_.ResolveConstUse(ctx); - if (!const_def) { - FormatError("irgen", - "使用缺少语义绑定: " + varName); - } - } if (var_decl) { // 找到变量定义 diff --git a/src/sem/Sema.cpp b/src/sem/Sema.cpp index 8e4fd0f..cb50416 100644 --- a/src/sem/Sema.cpp +++ b/src/sem/Sema.cpp @@ -180,6 +180,9 @@ public: if (is_array) { // 处理数组维度 for (auto* dim_exp : ctx->constExp()) { + // ========== 绑定维度表达式 ========== + dim_exp->addExp()->accept(this); // 触发常量绑定(如 N) + int dim = table_.EvaluateConstExp(dim_exp); if (dim <= 0) { throw std::runtime_error(FormatError("sema", "数组维度必须为正整数")); @@ -212,6 +215,10 @@ public: if (is_global && has_init) { CheckGlobalInitIsConst(ctx->initVal()); // 全局变量初始化必须是常量表达式 } + // ========== 绑定初始化表达式 ========== + if (ctx->initVal()) { + BindInitVal(ctx->initVal()); + } // 创建符号 Symbol sym; sym.name = name; @@ -275,9 +282,18 @@ public: type = ir::Type::GetArrayType(base_type, dims); std::cout << "[DEBUG] 创建数组类型完成,IsArray: " << type->IsArray() << std::endl; } + + // ========== 绑定维度表达式 ========== + for (auto* dim_exp : ctx->constExp()) { + dim_exp->addExp()->accept(this); + } + // 求值初始化器 std::vector init_values; if (ctx->constInitVal()) { + // ========== 绑定初始化表达式 ========== + BindConstInitVal(ctx->constInitVal()); + init_values = table_.EvaluateConstInitVal(ctx->constInitVal(), dims, base_type); std::cout << "[DEBUG] 初始化值数量: " << init_values.size() << std::endl; } @@ -294,6 +310,7 @@ public: Symbol sym; sym.name = name; sym.kind = SymbolKind::Constant; + std::cout << "CheckConstDef: before addSymbol, sym.kind = " << (int)sym.kind << std::endl; sym.type = type; sym.scope_level = table_.currentScopeLevel(); sym.is_initialized = true; @@ -314,6 +331,10 @@ public: std::cout << "[DEBUG] 数组常量,不存储单个常量值" << std::endl; } table_.addSymbol(sym); + std::cout << "CheckConstDef: after addSymbol, sym.kind = " << (int)sym.kind << std::endl; + auto* stored = table_.lookup(name); + std::cout << "CheckConstDef: after addSymbol, stored const_def_ctx = " << stored->const_def_ctx << std::endl; + std::cout << "[DEBUG] 常量符号添加完成" << std::endl; } @@ -1056,6 +1077,8 @@ private: if (!sym) { throw std::runtime_error(FormatError("sema", "未定义的变量: " + name)); } + std::cout << "CheckLValue: found sym->name = " << sym->name + << ", sym->kind = " << (int)sym->kind << std::endl; if (sym->kind == SymbolKind::Variable && sym->var_def_ctx) { sema_.BindVarUse(ctx, sym->var_def_ctx); @@ -1448,6 +1471,29 @@ private: throw std::runtime_error(FormatError("sema", "main 函数不能有参数")); } } + + void BindConstInitVal(SysYParser::ConstInitValContext* ctx) { + if (!ctx) return; + if (ctx->constExp()) { + // 遍历表达式树,触发 visitLVal 中的绑定 + ctx->constExp()->addExp()->accept(this); + } else { + for (auto* sub : ctx->constInitVal()) { + BindConstInitVal(sub); + } + } + } + + void BindInitVal(SysYParser::InitValContext* ctx) { + if (!ctx) return; + if (ctx->exp()) { + CheckExp(ctx->exp()); // 触发绑定 + } else { + for (auto* sub : ctx->initVal()) { + BindInitVal(sub); + } + } + } }; } // namespace diff --git a/src/sem/SymbolTable.cpp b/src/sem/SymbolTable.cpp index f9f421a..2de9fa4 100644 --- a/src/sem/SymbolTable.cpp +++ b/src/sem/SymbolTable.cpp @@ -39,6 +39,14 @@ bool SymbolTable::addSymbol(const Symbol& sym) { return false; // 重复定义 } current_scope[sym.name] = sym; + + // 立即验证存储的符号 + const auto& stored = current_scope[sym.name]; + std::cout << "SymbolTable::addSymbol: stored " << sym.name + << " with kind=" << (int)stored.kind + << ", const_def_ctx=" << stored.const_def_ctx + << std::endl; + return true; } @@ -55,6 +63,12 @@ const Symbol* SymbolTable::lookup(const std::string& name) const { const auto& scope = *it; auto found = scope.find(name); if (found != scope.end()) { + std::cout << "SymbolTable::lookup: found " << name + << " in scope level " << (scopes_.rend() - it - 1) + << ", kind=" << (int)found->second.kind + << ", const_def_ctx=" << found->second.const_def_ctx + << std::endl; + return &found->second; } }