|
|
|
|
@ -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<int>(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<float>(val.int_val);
|
|
|
|
|
} else {
|
|
|
|
|
@ -574,47 +590,97 @@ float SymbolTable::EvaluateConstExpFloat(SysYParser::ConstExpContext* ctx) const
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SymbolTable::flattenInit(SysYParser::ConstInitValContext* ctx,
|
|
|
|
|
std::vector<ConstValue>& out,
|
|
|
|
|
std::shared_ptr<ir::Type> 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<ConstValue>& values, // 存储最终所有元素(行优先)
|
|
|
|
|
size_t& index, // 当前填充到的位置
|
|
|
|
|
SysYParser::ConstInitValContext* ctx, // 当前初始化列表节点
|
|
|
|
|
const std::vector<int>& dims, // 剩余维度
|
|
|
|
|
size_t dim_idx, // 当前维度索引
|
|
|
|
|
std::shared_ptr<ir::Type> 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<float>(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<ConstValue>& values, size_t& index,
|
|
|
|
|
const std::vector<int>& dims, size_t dim_idx,
|
|
|
|
|
std::shared_ptr<ir::Type> 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::ConstValue> SymbolTable::EvaluateConstInitVal(
|
|
|
|
|
@ -624,6 +690,7 @@ std::vector<SymbolTable::ConstValue> 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::ConstValue> SymbolTable::EvaluateConstInitVal(
|
|
|
|
|
|
|
|
|
|
// ========== 2. 数组常量(dims 非空)==========
|
|
|
|
|
// 计算数组总元素个数
|
|
|
|
|
DEBUG_MSG("EvaluateConstInitVal: 开始,维度=" << dims.size());
|
|
|
|
|
size_t total = 1;
|
|
|
|
|
for (int d : dims) total *= d;
|
|
|
|
|
DEBUG_MSG(" 数组常量初始化,总元素数=" << total);
|
|
|
|
|
|
|
|
|
|
std::vector<ConstValue> values(total);
|
|
|
|
|
size_t index = 0;
|
|
|
|
|
fillArray(values, index, ctx, dims, 0, base_type);
|
|
|
|
|
|
|
|
|
|
// 展平初始化列表(递归处理花括号)
|
|
|
|
|
std::vector<ConstValue> 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 {
|
|
|
|
|
|