diff --git a/include/sem/SymbolTable.h b/include/sem/SymbolTable.h index 2dfbc89..bf757bf 100644 --- a/include/sem/SymbolTable.h +++ b/include/sem/SymbolTable.h @@ -90,9 +90,17 @@ class SymbolTable { float float_val; }; }; - void flattenInit(SysYParser::ConstInitValContext* ctx, - std::vector& out, - std::shared_ptr base_type) const; + void fillArray( + std::vector& values, + size_t& index, + SysYParser::ConstInitValContext* ctx, + const std::vector& dims, + size_t dim_idx, + std::shared_ptr base_type) const; + void fillZero(std::vector& values, size_t& index, + const std::vector& dims, size_t dim_idx, + 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 2de9fa4..079722d 100644 --- a/src/sem/SymbolTable.cpp +++ b/src/sem/SymbolTable.cpp @@ -383,7 +383,10 @@ SymbolTable::ConstValue SymbolTable::EvaluatePrimaryExp(SysYParser::PrimaryExpCo auto lval = ctx->lVal(); if (!lval->Ident()) throw std::runtime_error("常量表达式求值:无效左值"); std::string name = lval->Ident()->getText(); + DEBUG_MSG(" 左值标识符: " << name); const Symbol* sym = lookup(name); + DEBUG_MSG(" 找到符号: kind=" << (int)sym->kind << ", value=" + << (sym->is_int_const ? std::to_string(sym->const_value.i32) : std::to_string(sym->const_value.f32))); if (!sym) throw std::runtime_error("常量表达式求值:未定义的标识符 " + name); if (sym->kind != SymbolKind::Constant) throw std::runtime_error("常量表达式求值:标识符 " + name + " 不是常量"); @@ -405,6 +408,7 @@ SymbolTable::ConstValue SymbolTable::EvaluatePrimaryExp(SysYParser::PrimaryExpCo ConstValue val; val.kind = ConstValue::FLOAT; val.float_val = ParseFloatLiteral(text); + DEBUG_MSG(" 浮点字面量: " << text << " -> " << val.float_val); return val; } else if (ctx->HEX_INT() || ctx->OCTAL_INT() || ctx->DECIMAL_INT() || ctx->ZERO()) { @@ -416,6 +420,7 @@ SymbolTable::ConstValue SymbolTable::EvaluatePrimaryExp(SysYParser::PrimaryExpCo ConstValue val; val.kind = ConstValue::INT; val.int_val = static_cast(ParseIntegerLiteral(text)); + DEBUG_MSG(" 整数字面量: " << text << " -> " << val.int_val); return val; } else if (ctx->exp()) { @@ -435,6 +440,8 @@ SymbolTable::ConstValue SymbolTable::EvaluateUnaryExp(SysYParser::UnaryExpContex else if (ctx->unaryOp()) { ConstValue operand = EvaluateUnaryExp(ctx->unaryExp()); std::string op = ctx->unaryOp()->getText(); + DEBUG_MSG("EvaluateUnaryExp: 操作符=" << op); + DEBUG_MSG(" 操作数=" << (operand.kind==ConstValue::INT ? std::to_string(operand.int_val) : std::to_string(operand.float_val))); if (op == "+") { return operand; @@ -470,10 +477,15 @@ SymbolTable::ConstValue SymbolTable::EvaluateMulExp(SysYParser::MulExpContext* c if (!ctx) throw std::runtime_error("常量表达式求值:无效 MulExp"); if (ctx->mulExp()) { + DEBUG_MSG("EvaluateMulExp: 左子表达式"); ConstValue left = EvaluateMulExp(ctx->mulExp()); + DEBUG_MSG(" 左值=" << (left.kind==ConstValue::INT ? std::to_string(left.int_val) : std::to_string(left.float_val))); ConstValue right = EvaluateUnaryExp(ctx->unaryExp()); + std::string op; + DEBUG_MSG(" 运算符=" << op); + DEBUG_MSG(" 右值=" << (right.kind==ConstValue::INT ? std::to_string(right.int_val) : std::to_string(right.float_val))); if (ctx->MulOp()) op = "*"; else if (ctx->DivOp()) op = "/"; else if (ctx->QuoOp()) op = "%"; @@ -550,7 +562,9 @@ SymbolTable::ConstValue SymbolTable::EvaluateAddExp(SysYParser::AddExpContext* c int SymbolTable::EvaluateConstExp(SysYParser::ConstExpContext* ctx) const { if (!ctx || !ctx->addExp()) throw std::runtime_error("常量表达式求值:无效 ConstExp"); + DEBUG_MSG("EvaluateConstExp: 表达式文本=" << ctx->getText()); ConstValue val = EvaluateAddExp(ctx->addExp()); + DEBUG_MSG(" 求值结果: " << (val.kind==ConstValue::INT ? std::to_string(val.int_val) : std::to_string(val.float_val))); if (val.kind == ConstValue::INT) { return val.int_val; } else { @@ -566,7 +580,9 @@ int SymbolTable::EvaluateConstExp(SysYParser::ConstExpContext* ctx) const { float SymbolTable::EvaluateConstExpFloat(SysYParser::ConstExpContext* ctx) const { if (!ctx || !ctx->addExp()) throw std::runtime_error("常量表达式求值:无效 ConstExp"); + DEBUG_MSG("EvaluateConstExpFloat: 表达式文本=" << ctx->getText()); ConstValue val = EvaluateAddExp(ctx->addExp()); + DEBUG_MSG(" 求值结果: " << (val.kind==ConstValue::INT ? std::to_string(val.int_val) : std::to_string(val.float_val))); if (val.kind == ConstValue::INT) { return static_cast(val.int_val); } else { @@ -574,47 +590,97 @@ float SymbolTable::EvaluateConstExpFloat(SysYParser::ConstExpContext* ctx) const } } -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) { - DEBUG_MSG("错误:整型数组遇到浮点常量,值=" << val.float_val); - throw std::runtime_error("常量初始化:整型数组不能使用浮点常量"); +// 递归填充函数,按维度填充值 +void SymbolTable::fillArray( + std::vector& values, // 存储最终所有元素(行优先) + size_t& index, // 当前填充到的位置 + SysYParser::ConstInitValContext* ctx, // 当前初始化列表节点 + const std::vector& dims, // 剩余维度 + size_t dim_idx, // 当前维度索引 + std::shared_ptr base_type) const // 元素基本类型 +{ + DEBUG_MSG("fillArray: 进入,dim_idx=" << dim_idx + << ", 剩余维度=" << (dims.size() - dim_idx) + << ", 当前index=" << index); + + // 如果已经是最内层(单个元素) + if (dim_idx == dims.size()) { + // 必须是单个表达式 + if (!ctx || !ctx->constExp()) { + 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); + ConstValue val = EvaluateAddExp(ctx->constExp()->addExp()); + // 类型检查和转换... + DEBUG_MSG(" 填充标量值: index=" << index + << ", 值=" << (val.kind == ConstValue::INT ? std::to_string(val.int_val) : std::to_string(val.float_val))); + values[index++] = val; + return; + } + + // 当前维度的元素个数 + size_t cur_dim_size = dims[dim_idx]; + DEBUG_MSG(" 当前维度大小=" << cur_dim_size << ", 是否是花括号列表=" << (ctx && !ctx->constExp())); + + // 如果是花括号列表,则按子项填充 + if (ctx && !ctx->constExp()) { // 花括号 + auto sub_vals = ctx->constInitVal(); + DEBUG_MSG(" 花括号列表,子项数量=" << sub_vals.size()); + // 对于每个子项,填充一个子数组 + for (size_t i = 0; i < cur_dim_size; ++i) { + DEBUG_MSG(" 处理子项 " << i << " / " << cur_dim_size); + if (i < sub_vals.size()) { + fillArray(values, index, sub_vals[i], dims, dim_idx + 1, base_type); + } else { + // 子项不足,填充零 + DEBUG_MSG(" 子项不足,填充零"); + fillZero(values, index, dims, dim_idx + 1, base_type); + } } - out.push_back(val); } else { - DEBUG_MSG("进入花括号初始化列表: " << ctxText); - // 花括号初始化列表:递归展开所有子项 - for (auto* sub : ctx->constInitVal()) { - flattenInit(sub, out, base_type); + // 不是花括号,即单个值,应视为对当前维度第一个元素的初始化,其余补零 + // 第一个子数组 + DEBUG_MSG(" 单个值(非花括号),将填充第一个子数组,其余补零"); + if (ctx && ctx->constExp()) { + fillArray(values, index, ctx, dims, dim_idx + 1, base_type); + } else { + DEBUG_MSG(" 无初始化值,第一个子数组也补零"); + fillZero(values, index, dims, dim_idx + 1, base_type); + } + // 剩余子数组补零 + for (size_t i = 1; i < cur_dim_size; ++i) { + DEBUG_MSG(" 填充第" << i << "个子数组为零"); + fillZero(values, index, dims, dim_idx + 1, base_type); + } + } + DEBUG_MSG("fillArray: 退出,index=" << index); +} + +// 填充指定数量的零 +void SymbolTable::fillZero(std::vector& values, size_t& index, + const std::vector& dims, size_t dim_idx, + std::shared_ptr base_type) const +{ + DEBUG_MSG("fillZero: 进入,dim_idx=" << dim_idx << ", 当前index=" << index); + if (dim_idx == dims.size()) { + ConstValue zero; + if (base_type->IsInt32()) { + zero.kind = ConstValue::INT; + zero.int_val = 0; + } else { + zero.kind = ConstValue::FLOAT; + zero.float_val = 0.0f; } - DEBUG_MSG("退出花括号初始化列表"); + DEBUG_MSG(" 填充零值: index=" << index); + values[index++] = zero; + return; + } + size_t cur_dim_size = dims[dim_idx]; + DEBUG_MSG(" fillZero 当前维度大小=" << cur_dim_size); + for (size_t i = 0; i < cur_dim_size; ++i) { + DEBUG_MSG(" fillZero 子项 " << i); + fillZero(values, index, dims, dim_idx + 1, base_type); } + DEBUG_MSG("fillZero: 退出"); } std::vector SymbolTable::EvaluateConstInitVal( @@ -624,6 +690,7 @@ std::vector SymbolTable::EvaluateConstInitVal( // ========== 1. 标量常量(dims 为空)========== if (dims.empty()) { + DEBUG_MSG(" 标量常量初始化,表达式=" << ctx->getText()); if (!ctx || !ctx->constExp()) { throw std::runtime_error("标量常量初始化必须使用单个表达式"); } @@ -649,32 +716,22 @@ std::vector SymbolTable::EvaluateConstInitVal( // ========== 2. 数组常量(dims 非空)========== // 计算数组总元素个数 + DEBUG_MSG("EvaluateConstInitVal: 开始,维度=" << dims.size()); size_t total = 1; for (int d : dims) total *= d; + DEBUG_MSG(" 数组常量初始化,总元素数=" << total); + + std::vector values(total); + size_t index = 0; + fillArray(values, index, ctx, dims, 0, base_type); - // 展平初始化列表(递归处理花括号) - 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); + DEBUG_MSG("EvaluateConstInitVal: 填充完成,最终index=" << index); + // 可选:打印所有填充的值 + for (size_t i = 0; i < values.size(); ++i) { + DEBUG_MSG(" values[" << i << "] = " << (values[i].kind == ConstValue::INT ? std::to_string(values[i].int_val) : std::to_string(values[i].float_val))); } - - return flat; + + return values; } int SymbolTable::EvaluateConstExpression(SysYParser::ExpContext* ctx) const {