fix(sem)修正常量表达式求值问题

feature/sem
mxr 2 weeks ago
parent 8e42c77caf
commit 8477ab4aca

@ -95,6 +95,8 @@ class SymbolTable {
SysYParser::ConstInitValContext* ctx,
const std::vector<int>& dims,
std::shared_ptr<ir::Type> base_type) const;
int EvaluateConstExpression(SysYParser::ExpContext* ctx) const;
private:
// 作用域栈:每个元素是一个从名字到符号的映射

@ -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<ConstValue> EvaluateConstInitVal(SysYParser::ConstInitValContext* ctx,
const std::vector<int>& dims,
std::shared_ptr<ir::Type> base_type) {
std::vector<ConstValue> 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<ConstValue> 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) {

@ -656,4 +656,21 @@ std::vector<SymbolTable::ConstValue> 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<int>(f);
if (std::abs(f - i) > 1e-6) {
throw std::runtime_error("常量表达式求值:浮点常量不能隐式转换为整数");
}
return i;
}
}
Loading…
Cancel
Save