diff --git a/include/sem/SymbolTable.h b/include/sem/SymbolTable.h index bf05648..7b08f82 100644 --- a/include/sem/SymbolTable.h +++ b/include/sem/SymbolTable.h @@ -95,6 +95,8 @@ class SymbolTable { SysYParser::ConstInitValContext* ctx, const std::vector& dims, std::shared_ptr base_type) const; + + int EvaluateConstExpression(SysYParser::ExpContext* ctx) const; private: // 作用域栈:每个元素是一个从名字到符号的映射 diff --git a/src/sem/Sema.cpp b/src/sem/Sema.cpp index c03d2bb..a92a1db 100644 --- a/src/sem/Sema.cpp +++ b/src/sem/Sema.cpp @@ -1348,20 +1348,6 @@ private: table_.addSymbol(sym); } - - // 在 SemaVisitor 类中添加 - int EvaluateConstantAddExp(SysYParser::AddExpContext* ctx) { - if (!ctx) return 0; - // 使用常量求值器 - // 这里需要访问 ConstEvaluator,但 SemaVisitor 可能没有直接访问 - // 我们可以直接使用 CheckAddExp 并检查常量 - ExprInfo info = CheckAddExp(ctx); - if (info.is_const && info.is_const_int) { - return info.const_int_value; - } - throw std::runtime_error(FormatError("sema", "常量表达式求值失败")); - return 0; - } void CollectFunctionParams(SysYParser::FuncFParamsContext* ctx) { if (!ctx) return; @@ -1400,8 +1386,7 @@ private: } // 求值常量表达式 - // 我们需要一个函数来求值常量表达式 - int dim = EvaluateConstantAddExp(addExp); + int dim = table_.EvaluateConstExpression(exp_ctx); if (dim <= 0) { throw std::runtime_error(FormatError("sema", "数组维度必须为正整数")); } @@ -1448,59 +1433,6 @@ private: } } - int EvaluateConstExp(SysYParser::ConstExpContext* ctx) { - if (!ctx || !ctx->addExp()) return 0; - ExprInfo info = CheckAddExp(ctx->addExp()); - if (info.is_const && info.is_const_int) { - return info.const_int_value; - } - throw std::runtime_error(FormatError("sema", "常量表达式求值失败")); - return 0; - } - - struct ConstValue { - bool is_int; - int int_val; - float float_val; - }; - - std::vector EvaluateConstInitVal(SysYParser::ConstInitValContext* ctx, - const std::vector& dims, - std::shared_ptr base_type) { - std::vector result; - if (!ctx) return result; - if (ctx->constExp()) { - ExprInfo info = CheckAddExp(ctx->constExp()->addExp()); - ConstValue val; - if (info.type->IsInt32() && info.is_const_int) { - val.is_int = true; - val.int_val = info.const_int_value; - if (base_type->IsFloat()) { - val.is_int = false; - val.float_val = (float)info.const_int_value; - } - } else if (info.type->IsFloat() && info.is_const) { - val.is_int = false; - val.float_val = info.const_float_value; - if (base_type->IsInt32()) { - val.is_int = true; - val.int_val = (int)info.const_float_value; - } - } else { - val.is_int = base_type->IsInt32(); - val.int_val = 0; - val.float_val = 0.0f; - } - result.push_back(val); - } else { - for (auto* init : ctx->constInitVal()) { - std::vector sub_vals = EvaluateConstInitVal(init, dims, base_type); - result.insert(result.end(), sub_vals.begin(), sub_vals.end()); - } - } - return result; - } - void CheckMainFunction() { auto* main_sym = table_.lookup("main"); if (!main_sym || main_sym->kind != SymbolKind::Function) { diff --git a/src/sem/SymbolTable.cpp b/src/sem/SymbolTable.cpp index 877ab63..f1a6a87 100644 --- a/src/sem/SymbolTable.cpp +++ b/src/sem/SymbolTable.cpp @@ -656,4 +656,21 @@ std::vector SymbolTable::EvaluateConstInitVal( } return flat; +} + +int SymbolTable::EvaluateConstExpression(SysYParser::ExpContext* ctx) const { + if (!ctx || !ctx->addExp()) { + throw std::runtime_error("常量表达式求值:无效 ExpContext"); + } + ConstValue val = EvaluateAddExp(ctx->addExp()); + if (val.kind == ConstValue::INT) { + return val.int_val; + } else { + float f = val.float_val; + int i = static_cast(f); + if (std::abs(f - i) > 1e-6) { + throw std::runtime_error("常量表达式求值:浮点常量不能隐式转换为整数"); + } + return i; + } } \ No newline at end of file