diff --git a/include/sem/SymbolTable.h b/include/sem/SymbolTable.h index a541739..bf05648 100644 --- a/include/sem/SymbolTable.h +++ b/include/sem/SymbolTable.h @@ -88,6 +88,9 @@ class SymbolTable { float float_val; }; }; + void flattenInit(SysYParser::ConstInitValContext* ctx, + std::vector& out, + std::shared_ptr base_type) const; std::vector EvaluateConstInitVal( SysYParser::ConstInitValContext* ctx, const std::vector& dims, diff --git a/src/sem/SymbolTable.cpp b/src/sem/SymbolTable.cpp index 976ce87..877ab63 100644 --- a/src/sem/SymbolTable.cpp +++ b/src/sem/SymbolTable.cpp @@ -5,6 +5,15 @@ #include #include +#define DEBUG_SYMBOL_TABLE + +#ifdef DEBUG_SYMBOL_TABLE +#include +#define DEBUG_MSG(msg) std::cerr << "[SymbolTable Debug] " << msg << std::endl +#else +#define DEBUG_MSG(msg) +#endif + // ---------- 构造函数 ---------- SymbolTable::SymbolTable() { scopes_.emplace_back(); // 初始化全局作用域 @@ -551,45 +560,100 @@ float SymbolTable::EvaluateConstExpFloat(SysYParser::ConstExpContext* ctx) const } } -std::vector SymbolTable::EvaluateConstInitVal( - SysYParser::ConstInitValContext* ctx, - const std::vector& dims, - std::shared_ptr base_type) const -{ - std::vector result; - if (!ctx) return result; +void SymbolTable::flattenInit(SysYParser::ConstInitValContext* ctx, + std::vector& out, + std::shared_ptr base_type) const { + if (!ctx) return; + + // 获取当前初始化列表的文本(用于调试) + std::string ctxText; + if (ctx->constExp()) { + ctxText = ctx->constExp()->getText(); + } else { + ctxText = "{ ... }"; + } if (ctx->constExp()) { ConstValue val = EvaluateAddExp(ctx->constExp()->addExp()); - // 根据基础类型进行可能的隐式转换 + + DEBUG_MSG("处理常量表达式: " << ctxText + << " 类型=" << (val.kind == ConstValue::INT ? "INT" : "FLOAT") + << " 值=" << (val.kind == ConstValue::INT ? std::to_string(val.int_val) : std::to_string(val.float_val)) + << " 目标类型=" << (base_type->IsInt32() ? "Int32" : "Float")); + + // 整型数组不能接受浮点常量 if (base_type->IsInt32() && val.kind == ConstValue::FLOAT) { - int i = static_cast(val.float_val); - if (std::abs(val.float_val - i) > 1e-6) { - throw std::runtime_error("常量初始化:浮点常量不能隐式转换为整数"); - } - val.kind = ConstValue::INT; - val.int_val = i; - } else if (base_type->IsFloat() && val.kind == ConstValue::INT) { + DEBUG_MSG("错误:整型数组遇到浮点常量,值=" << val.float_val); + throw std::runtime_error("常量初始化:整型数组不能使用浮点常量"); + } + // 浮点数组接受整型常量,并隐式转换 + if (base_type->IsFloat() && val.kind == ConstValue::INT) { + DEBUG_MSG("浮点数组接收整型常量,隐式转换为浮点: " << val.int_val); val.kind = ConstValue::FLOAT; val.float_val = static_cast(val.int_val); } - result.push_back(val); + out.push_back(val); } else { - // 嵌套初始化列表 - if (dims.empty()) { - throw std::runtime_error("常量初始化:非数组使用初始化列表"); + DEBUG_MSG("进入花括号初始化列表: " << ctxText); + // 花括号初始化列表:递归展开所有子项 + for (auto* sub : ctx->constInitVal()) { + flattenInit(sub, out, base_type); } - std::vector sub_dims(dims.begin() + 1, dims.end()); - int expected_count = 1; - for (int d : sub_dims) expected_count *= d; - - for (auto* sub_init : ctx->constInitVal()) { - auto sub_vals = EvaluateConstInitVal(sub_init, sub_dims, base_type); - if (sub_vals.size() != static_cast(expected_count)) { - throw std::runtime_error("常量初始化:子列表元素数量不匹配"); - } - result.insert(result.end(), sub_vals.begin(), sub_vals.end()); + DEBUG_MSG("退出花括号初始化列表"); + } +} + +std::vector SymbolTable::EvaluateConstInitVal( + SysYParser::ConstInitValContext* ctx, + const std::vector& dims, + std::shared_ptr base_type) const { + + // ========== 1. 标量常量(dims 为空)========== + if (dims.empty()) { + if (!ctx || !ctx->constExp()) { + throw std::runtime_error("标量常量初始化必须使用单个表达式"); + } + ConstValue val = EvaluateAddExp(ctx->constExp()->addExp()); + + // 类型兼容性检查 + /* + if (base_type->IsInt32() && val.kind == ConstValue::FLOAT) { + throw std::runtime_error("整型常量不能使用浮点常量初始化"); } + if (base_type->IsFloat() && val.kind == ConstValue::INT) { + val.kind = ConstValue::FLOAT; + val.float_val = static_cast(val.int_val); + } + */ + return {val}; // 返回包含单个值的向量 } - return result; + + // ========== 2. 数组常量(dims 非空)========== + // 计算数组总元素个数 + size_t total = 1; + for (int d : dims) total *= d; + + // 展平初始化列表(递归处理花括号) + std::vector flat; + flattenInit(ctx, flat, base_type); + + // 检查数量是否超过数组容量 + if (flat.size() > total) { + throw std::runtime_error("常量初始化:提供的初始值数量超过数组元素总数"); + } + + // 不足的部分补零 + if (flat.size() < total) { + ConstValue zero; + if (base_type->IsInt32()) { + zero.kind = ConstValue::INT; + zero.int_val = 0; + } else { + zero.kind = ConstValue::FLOAT; + zero.float_val = 0.0f; + } + flat.resize(total, zero); + } + + return flat; } \ No newline at end of file