|
|
|
|
@ -5,6 +5,15 @@
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
|
|
#define DEBUG_SYMBOL_TABLE
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_SYMBOL_TABLE
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#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::ConstValue> SymbolTable::EvaluateConstInitVal(
|
|
|
|
|
SysYParser::ConstInitValContext* ctx,
|
|
|
|
|
const std::vector<int>& dims,
|
|
|
|
|
std::shared_ptr<ir::Type> base_type) const
|
|
|
|
|
{
|
|
|
|
|
std::vector<ConstValue> result;
|
|
|
|
|
if (!ctx) return result;
|
|
|
|
|
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) {
|
|
|
|
|
int i = static_cast<int>(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<float>(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<int> 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<size_t>(expected_count)) {
|
|
|
|
|
throw std::runtime_error("常量初始化:子列表元素数量不匹配");
|
|
|
|
|
}
|
|
|
|
|
result.insert(result.end(), sub_vals.begin(), sub_vals.end());
|
|
|
|
|
DEBUG_MSG("退出花括号初始化列表");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<SymbolTable::ConstValue> SymbolTable::EvaluateConstInitVal(
|
|
|
|
|
SysYParser::ConstInitValContext* ctx,
|
|
|
|
|
const std::vector<int>& dims,
|
|
|
|
|
std::shared_ptr<ir::Type> 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<float>(val.int_val);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
return {val}; // 返回包含单个值的向量
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
// ========== 2. 数组常量(dims 非空)==========
|
|
|
|
|
// 计算数组总元素个数
|
|
|
|
|
size_t total = 1;
|
|
|
|
|
for (int d : dims) total *= d;
|
|
|
|
|
|
|
|
|
|
// 展平初始化列表(递归处理花括号)
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return flat;
|
|
|
|
|
}
|