diff --git a/include/sem/Sema.h b/include/sem/Sema.h index c79c401..10e4d8e 100644 --- a/include/sem/Sema.h +++ b/include/sem/Sema.h @@ -34,6 +34,14 @@ public: return it == var_uses_.end() ? nullptr : it->second; } + void BindConstUse(SysYParser::LValContext* use, SysYParser::ConstDefContext* decl) { + const_uses_[use] = decl; + } + SysYParser::ConstDefContext* ResolveConstUse(const SysYParser::LValContext* use) const { + auto it = const_uses_.find(use); + return it == const_uses_.end() ? nullptr : it->second; + } + // ----- 表达式类型信息存储 ----- void SetExprType(antlr4::ParserRuleContext* node, const ExprInfo& info) { ExprInfo copy = info; @@ -76,6 +84,8 @@ private: // 隐式转换列表 std::vector conversions_; + + std::unordered_map const_uses_; }; // 目前仅检查: diff --git a/include/sem/SymbolTable.h b/include/sem/SymbolTable.h index 7b08f82..2dfbc89 100644 --- a/include/sem/SymbolTable.h +++ b/include/sem/SymbolTable.h @@ -43,6 +43,8 @@ struct Symbol { // 关联的语法树节点(用于报错位置或进一步分析) SysYParser::VarDefContext* var_def_ctx = nullptr; + SysYParser::ConstDefContext* const_def_ctx = nullptr; + SysYParser::FuncFParamContext* param_def_ctx = nullptr; SysYParser::FuncDefContext* func_def_ctx = nullptr; }; diff --git a/src/irgen/IRGenExp.cpp b/src/irgen/IRGenExp.cpp index 90d07b1..acf9d9c 100644 --- a/src/irgen/IRGenExp.cpp +++ b/src/irgen/IRGenExp.cpp @@ -84,9 +84,11 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) { // 从语义分析获取变量定义 auto* decl = sema_.ResolveVarUse(ctx); if (!decl) { - throw std::runtime_error( + auto* const_def = sema_.ResolveConstUse(ctx); + if (!const_def) { FormatError("irgen", - "变量使用缺少语义绑定: " + varName)); + "使用缺少语义绑定: " + varName); + } } auto it = storage_map_.find(decl); diff --git a/src/sem/Sema.cpp b/src/sem/Sema.cpp index 01bae52..8e4fd0f 100644 --- a/src/sem/Sema.cpp +++ b/src/sem/Sema.cpp @@ -298,6 +298,9 @@ public: sym.scope_level = table_.currentScopeLevel(); sym.is_initialized = true; sym.var_def_ctx = nullptr; + sym.const_def_ctx = ctx; + sym.const_def_ctx = ctx; + std::cout << "保存常量定义上下文: " << name << ", ctx: " << ctx << std::endl; // 存储常量值(仅对非数组有效) if (!is_array && !init_values.empty()) { if (base_type->IsInt32() && init_values[0].kind == SymbolTable::ConstValue::INT) { @@ -1056,9 +1059,17 @@ private: if (sym->kind == SymbolKind::Variable && sym->var_def_ctx) { sema_.BindVarUse(ctx, sym->var_def_ctx); + std::cout << "绑定变量: " << name << " -> VarDefContext" << std::endl; } - std::cout << "CheckLValue 绑定变量: " << name << std::endl; - + else if (sym->kind == SymbolKind::Constant && sym->const_def_ctx) { + sema_.BindConstUse(ctx, sym->const_def_ctx); + std::cout << "绑定常量: " << name << " -> ConstDefContext" << std::endl; + } + std::cout << "CheckLValue 绑定变量: " << name + << ", sym->kind: " << (int)sym->kind + << ", sym->var_def_ctx: " << sym->var_def_ctx + << ", sym->const_def_ctx: " << sym->const_def_ctx << std::endl; + bool is_array_access = !ctx->exp().empty(); bool is_const = (sym->kind == SymbolKind::Constant);