From 97c01debbdcd8f0e97284c20a4f9231a774db883 Mon Sep 17 00:00:00 2001 From: potapo <2720187907@qq.com> Date: Thu, 26 Mar 2026 21:38:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E6=B5=8B=E8=AF=95=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E4=BD=86=E6=9C=89=E5=87=BD=E6=95=B0=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/irgen/IRGenExp.cpp | 220 +++++++++++++++++++++++++++++------------ 1 file changed, 158 insertions(+), 62 deletions(-) diff --git a/src/irgen/IRGenExp.cpp b/src/irgen/IRGenExp.cpp index 9a72deb..2ff3bd7 100644 --- a/src/irgen/IRGenExp.cpp +++ b/src/irgen/IRGenExp.cpp @@ -22,9 +22,38 @@ // - ... ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) { - return std::any_cast(expr.accept(this)); + try { + auto result_any = expr.accept(this); + + if (!result_any.has_value()) { + std::cerr << "[ERROR] EvalExpr: result_any has no value" << std::endl; + throw std::runtime_error("表达式求值结果为空"); + } + + try { + ir::Value* result = std::any_cast(result_any); + std::cerr << "[DEBUG] EvalExpr: success, result = " << (void*)result << std::endl; + return result; + } catch (const std::bad_any_cast& e) { + std::cerr << "[ERROR] EvalExpr: bad any_cast - " << e.what() << std::endl; + std::cerr << " Type info: " << result_any.type().name() << std::endl; + + // 尝试其他可能的类型 + try { + // 检查是否是无值的any(可能来自visit函数返回{}) + std::cerr << "[DEBUG] EvalExpr: Trying to handle empty any" << std::endl; + return nullptr; + } catch (...) { + throw std::runtime_error(FormatError("irgen", "表达式求值返回了错误的类型")); + } + } + } catch (const std::exception& e) { + std::cerr << "[ERROR] Exception in EvalExpr: " << e.what() << std::endl; + throw; + } } + ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) { return std::any_cast(cond.accept(this)); } @@ -35,62 +64,70 @@ std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) { throw std::runtime_error(FormatError("irgen", "缺少基本表达式")); } + std::cerr << "[DEBUG] visitPrimaryExp" << std::endl; + // 处理数字字面量 if (ctx->DECIMAL_INT()) { int value = std::stoi(ctx->DECIMAL_INT()->getText()); - return static_cast(builder_.CreateConstInt(value)); + ir::Value* const_int = builder_.CreateConstInt(value); + std::cerr << "[DEBUG] visitPrimaryExp: constant int " << value + << " created as " << (void*)const_int << std::endl; + return static_cast(const_int); } if (ctx->HEX_INT()) { std::string hex = ctx->HEX_INT()->getText(); int value = std::stoi(hex, nullptr, 16); - return static_cast(builder_.CreateConstInt(value)); + ir::Value* const_int = builder_.CreateConstInt(value); + return static_cast(const_int); } if (ctx->OCTAL_INT()) { std::string oct = ctx->OCTAL_INT()->getText(); int value = std::stoi(oct, nullptr, 8); - return static_cast(builder_.CreateConstInt(value)); + ir::Value* const_int = builder_.CreateConstInt(value); + return static_cast(const_int); } if (ctx->ZERO()) { - return static_cast(builder_.CreateConstInt(0)); + ir::Value* const_int = builder_.CreateConstInt(0); + return static_cast(const_int); } // 处理变量 if (ctx->lVal()) { + std::cerr << "[DEBUG] visitPrimaryExp: visiting lVal" << std::endl; return ctx->lVal()->accept(this); } // 处理括号表达式 if (ctx->L_PAREN() && ctx->exp()) { + std::cerr << "[DEBUG] visitPrimaryExp: visiting parenthesized expression" << std::endl; return EvalExpr(*ctx->exp()); } + std::cerr << "[ERROR] visitPrimaryExp: unsupported primary expression type" << std::endl; throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型")); } -// 左值(变量)处理 -// 1. 先通过语义分析结果把变量使用绑定回声明; -// 2. 再通过 storage_map_ 找到该声明对应的栈槽位; -// 3. 最后生成 load,把内存中的值读出来。 +// visitLVal std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) { if (!ctx || !ctx->Ident()) { throw std::runtime_error(FormatError("irgen", "非法左值")); } std::string varName = ctx->Ident()->getText(); + std::cerr << "[DEBUG] visitLVal: " << varName << std::endl; // 从语义分析获取变量定义 auto* decl = sema_.ResolveVarUse(ctx); if (!decl) { - auto* const_def = sema_.ResolveConstUse(ctx); - if (!const_def) { + throw std::runtime_error( FormatError("irgen", - "使用缺少语义绑定: " + varName); - } + "变量使用缺少语义绑定: " + varName)); } + // 使用 storage_map_ 而不是 varNameToSlot_ auto it = storage_map_.find(decl); if (it == storage_map_.end()) { throw std::runtime_error( @@ -98,26 +135,49 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) { "变量声明缺少存储槽位: " + varName)); } - return static_cast( - builder_.CreateLoad(it->second, module_.GetContext().NextTemp())); + ir::Value* load_result = builder_.CreateLoad(it->second, module_.GetContext().NextTemp()); + std::cerr << "[DEBUG] visitLVal: created load, result = " << (void*)load_result << std::endl; + + return static_cast(load_result); } // 加法表达式 std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) { - if (!ctx) throw std::runtime_error(FormatError("irgen", "非法加法表达式")); - + if (!ctx) { + throw std::runtime_error(FormatError("irgen", "非法加法表达式")); + } + + // 如果没有 addExp(),说明是单个 mulExp() if (!ctx->addExp()) { return ctx->mulExp()->accept(this); } - ir::Value* left = std::any_cast(ctx->addExp()->accept(this)); - ir::Value* right = std::any_cast(ctx->mulExp()->accept(this)); + // 正确提取左操作数 + auto left_any = ctx->addExp()->accept(this); + if (!left_any.has_value()) { + throw std::runtime_error(FormatError("irgen", "左操作数求值失败")); + } + ir::Value* left = std::any_cast(left_any); + + // 正确提取右操作数 + auto right_any = ctx->mulExp()->accept(this); + if (!right_any.has_value()) { + throw std::runtime_error(FormatError("irgen", "右操作数求值失败")); + } + ir::Value* right = std::any_cast(right_any); + + std::cerr << "[DEBUG] visitAddExp: left=" << (void*)left << ", right=" << (void*)right << std::endl; + + // 根据操作符生成相应的指令 if (ctx->AddOp()) { - return builder_.CreateAdd(left, right, module_.GetContext().NextTemp()); + return static_cast( + builder_.CreateAdd(left, right, module_.GetContext().NextTemp())); } else if (ctx->SubOp()) { - return builder_.CreateSub(left, right, module_.GetContext().NextTemp()); + return static_cast( + builder_.CreateSub(left, right, module_.GetContext().NextTemp())); } + throw std::runtime_error(FormatError("irgen", "未知的加法操作符")); } @@ -125,53 +185,42 @@ std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) { // visitMulExp std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) { - if (!ctx) throw std::runtime_error(FormatError("irgen", "非法乘法表达式")); - + if (!ctx) { + throw std::runtime_error(FormatError("irgen", "非法乘法表达式")); + } + // 如果是基本形式 UnaryExp if (!ctx->mulExp()) { return ctx->unaryExp()->accept(this); } - - // 否则有左子节点和操作符 - ir::Value* left = std::any_cast(ctx->mulExp()->accept(this)); - ir::Value* right = std::any_cast(ctx->unaryExp()->accept(this)); - std::string op; - if (ctx->MulOp()) op = "*"; - else if (ctx->DivOp()) op = "/"; - else if (ctx->QuoOp()) op = "%"; - else throw std::runtime_error(FormatError("irgen", "缺少乘法类操作符")); - - if (op == "*") { - return builder_.CreateMul(left, right, module_.GetContext().NextTemp()); - } else if (op == "/") { - return builder_.CreateDiv(left, right, module_.GetContext().NextTemp()); - } else if (op == "%") { - return builder_.CreateMod(left, right, module_.GetContext().NextTemp()); + + // 提取左操作数 + auto left_any = ctx->mulExp()->accept(this); + if (!left_any.has_value()) { + throw std::runtime_error(FormatError("irgen", "左操作数求值失败")); } - throw std::runtime_error(FormatError("irgen", "未知的乘法操作符")); -} - -// 关系表达式 -std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) { - if (!ctx) throw std::runtime_error(FormatError("irgen", "非法关系表达式")); - - if (!ctx->relExp()) { - return ctx->addExp()->accept(this); + ir::Value* left = std::any_cast(left_any); + + // 提取右操作数 + auto right_any = ctx->unaryExp()->accept(this); + if (!right_any.has_value()) { + throw std::runtime_error(FormatError("irgen", "右操作数求值失败")); } - - ir::Value* left = std::any_cast(ctx->relExp()->accept(this)); - ir::Value* right = std::any_cast(ctx->addExp()->accept(this)); - - if (ctx->LOp()) { - return builder_.CreateICmpSLT(left, right, module_.GetContext().NextTemp()); - } else if (ctx->GOp()) { - return builder_.CreateICmpSGT(left, right, module_.GetContext().NextTemp()); - } else if (ctx->LeOp()) { - return builder_.CreateICmpSLE(left, right, module_.GetContext().NextTemp()); - } else if (ctx->GeOp()) { - return builder_.CreateICmpSGE(left, right, module_.GetContext().NextTemp()); + ir::Value* right = std::any_cast(right_any); + + // 根据操作符生成指令 + if (ctx->MulOp()) { + return static_cast( + builder_.CreateMul(left, right, module_.GetContext().NextTemp())); + } else if (ctx->DivOp()) { + return static_cast( + builder_.CreateDiv(left, right, module_.GetContext().NextTemp())); + } else if (ctx->QuoOp()) { + return static_cast( + builder_.CreateMod(left, right, module_.GetContext().NextTemp())); } - throw std::runtime_error(FormatError("irgen", "未知的关系操作符")); + + throw std::runtime_error(FormatError("irgen", "未知的乘法操作符")); } // 相等表达式 @@ -326,7 +375,7 @@ std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) { if (ctx->constExp()) { // 常量表达式求值:需要语义分析支持常量折叠,这里我们返回求值后的常量值。 // 假设 sema_ 有方法 EvaluateConstExp 返回 int。 - auto* constExp = ctx->constExp(); + // auto* constExp = ctx->constExp(); // 这行可以删除,因为不需要使用 // 通过语义分析求值(暂未实现,先抛异常) // int val = sema_.EvaluateConstExp(constExp); // return builder_.CreateConstInt(val); @@ -348,6 +397,9 @@ std::any IRGenImpl::visitInitVal(SysYParser::InitValContext* ctx) { } std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) { + // 消除未使用参数警告 + (void)ctx; // 明确表示参数未使用 + // 常量表达式由 AddExp 构成,我们直接复用表达式求值(但需要常量折叠)。 // 由于常量表达式在编译时求值,IR 生成阶段其实不需要计算值,语义分析会提供。 // 这里我们只用来获取 IR 值(例如数组大小),但数组大小需要在 IR 生成前就知道。 @@ -357,3 +409,47 @@ std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) { // 这里先抛异常,等待语义团队提供接口。 throw std::runtime_error(FormatError("irgen", "常量表达式求值暂未实现")); } + +std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) { + if (!ctx) { + throw std::runtime_error(FormatError("irgen", "非法关系表达式")); + } + + // 如果是基本形式 AddExp + if (!ctx->relExp()) { + return ctx->addExp()->accept(this); + } + + // 提取左操作数 + auto left_any = ctx->relExp()->accept(this); + if (!left_any.has_value()) { + throw std::runtime_error(FormatError("irgen", "左操作数求值失败")); + } + ir::Value* left = std::any_cast(left_any); + + // 提取右操作数 + auto right_any = ctx->addExp()->accept(this); + if (!right_any.has_value()) { + throw std::runtime_error(FormatError("irgen", "右操作数求值失败")); + } + ir::Value* right = std::any_cast(right_any); + + // 根据操作符生成相应的比较指令 + std::string op = ctx->relExp()->getText(); + + if (op == "<") { + return static_cast( + builder_.CreateICmpSLT(left, right, module_.GetContext().NextTemp())); + } else if (op == ">") { + return static_cast( + builder_.CreateICmpSGT(left, right, module_.GetContext().NextTemp())); + } else if (op == "<=") { + return static_cast( + builder_.CreateICmpSLE(left, right, module_.GetContext().NextTemp())); + } else if (op == ">=") { + return static_cast( + builder_.CreateICmpSGE(left, right, module_.GetContext().NextTemp())); + } + + throw std::runtime_error(FormatError("irgen", "未知的关系操作符: " + op)); +} \ No newline at end of file