diff --git a/src/irgen/IRGenDecl.cpp b/src/irgen/IRGenDecl.cpp index 948c72f..931f023 100644 --- a/src/irgen/IRGenDecl.cpp +++ b/src/irgen/IRGenDecl.cpp @@ -4,6 +4,7 @@ #include "SysYParser.h" #include "ir/IR.h" +#include "utils/Log.h" void IRGenImpl::GenBlock(SysYParser::BlockContext& block) { for (auto* item : block.blockItem()) { @@ -24,7 +25,7 @@ bool IRGenImpl::GenBlockItem(SysYParser::BlockItemContext& item) { if (item.stmt()) { return GenStmt(*item.stmt()); } - throw std::runtime_error("[irgen] 暂不支持的 blockItem 类型"); + throw std::runtime_error(FormatError("irgen", "暂不支持的语句或声明")); } void IRGenImpl::GenDecl(SysYParser::DeclContext& decl) { @@ -32,13 +33,13 @@ void IRGenImpl::GenDecl(SysYParser::DeclContext& decl) { GenVarDecl(*decl.varDecl()); return; } - throw std::runtime_error("[irgen] 暂不支持的声明类型"); + throw std::runtime_error(FormatError("irgen", "暂不支持的声明类型")); } void IRGenImpl::GenVarDecl(SysYParser::VarDeclContext& decl) { const std::string name = decl.Ident()->getText(); if (locals_.find(name) != locals_.end()) { - throw std::runtime_error("[irgen] 重复定义变量: " + name); + throw std::runtime_error(FormatError("irgen", "重复定义变量: " + name)); } auto* slot = builder_.CreateAllocaI32(ir::DefaultContext().NextTemp()); locals_[name] = slot; diff --git a/src/irgen/IRGenDriver.cpp b/src/irgen/IRGenDriver.cpp index 014b60a..0db686b 100644 --- a/src/irgen/IRGenDriver.cpp +++ b/src/irgen/IRGenDriver.cpp @@ -6,15 +6,16 @@ #include "SysYParser.h" #include "antlr4-runtime.h" #include "ir/IR.h" +#include "utils/Log.h" std::unique_ptr GenerateIR(antlr4::tree::ParseTree* tree) { if (!tree) { - throw std::runtime_error("[irgen] 语法树为空"); + throw std::runtime_error(FormatError("irgen", "语法树为空")); } auto* cu = dynamic_cast(tree); if (!cu) { - throw std::runtime_error("[irgen] 语法树根节点不是 compUnit"); + throw std::runtime_error(FormatError("irgen", "语法树根节点不是 compUnit")); } auto module = std::make_unique(); diff --git a/src/irgen/IRGenExp.cpp b/src/irgen/IRGenExp.cpp index e62ca91..62e13a9 100644 --- a/src/irgen/IRGenExp.cpp +++ b/src/irgen/IRGenExp.cpp @@ -4,10 +4,11 @@ #include "SysYParser.h" #include "ir/IR.h" +#include "utils/Log.h" ir::Value* IRGenImpl::GenExpr(SysYParser::ExpContext& expr) { if (!expr.addExp()) { - throw std::runtime_error("[irgen] 非法表达式"); + throw std::runtime_error(FormatError("irgen", "非法表达式")); } return GenAddExpr(*expr.addExp()); } @@ -16,7 +17,7 @@ ir::Value* IRGenImpl::GenAddExpr(SysYParser::AddExpContext& add) { // 当前表达式层次仍是最小实现,直接贴合 addExp -> primary 的语法形状。 const auto& terms = add.primary(); if (terms.empty()) { - throw std::runtime_error("[irgen] 空加法表达式"); + throw std::runtime_error(FormatError("irgen", "空加法表达式")); } ir::Value* acc = GenPrimary(*terms[0]); @@ -36,12 +37,12 @@ ir::Value* IRGenImpl::GenPrimary(SysYParser::PrimaryContext& primary) { const std::string name = primary.Ident()->getText(); auto it = locals_.find(name); if (it == locals_.end()) { - throw std::runtime_error("[irgen] 变量未找到: " + name); + throw std::runtime_error(FormatError("irgen", "变量未找到: " + name)); } return builder_.CreateLoad(it->second, ir::DefaultContext().NextTemp()); } if (primary.exp()) { return GenExpr(*primary.exp()); } - throw std::runtime_error("[irgen] 暂不支持的 primary 形式"); + throw std::runtime_error(FormatError("irgen", "暂不支持的表达式形式")); } diff --git a/src/irgen/IRGenFunc.cpp b/src/irgen/IRGenFunc.cpp index 4c0500a..a58086b 100644 --- a/src/irgen/IRGenFunc.cpp +++ b/src/irgen/IRGenFunc.cpp @@ -4,6 +4,7 @@ #include "SysYParser.h" #include "ir/IR.h" +#include "utils/Log.h" namespace { @@ -11,8 +12,9 @@ void VerifyFunctionStructure(const ir::Function& func) { // 当前 IRGen 仍是单入口、顺序生成;这里在生成结束后补一层块终结校验。 for (const auto& bb : func.blocks()) { if (!bb || !bb->HasTerminator()) { - throw std::runtime_error("[irgen] 基本块未正确终结: " + - (bb ? bb->name() : std::string(""))); + throw std::runtime_error( + FormatError("irgen", "基本块未正确终结: " + + (bb ? bb->name() : std::string("")))); } } } @@ -24,17 +26,17 @@ IRGenImpl::IRGenImpl(ir::Module& module) void IRGenImpl::Gen(SysYParser::CompUnitContext& cu) { if (!cu.funcDef()) { - throw std::runtime_error("[irgen] 缺少 main 定义"); + throw std::runtime_error(FormatError("irgen", "缺少 main 定义")); } GenFuncDef(*cu.funcDef()); } void IRGenImpl::GenFuncDef(SysYParser::FuncDefContext& func) { if (!func.block()) { - throw std::runtime_error("[irgen] 函数体为空"); + throw std::runtime_error(FormatError("irgen", "函数体为空")); } if (!func.Ident()) { - throw std::runtime_error("[irgen] 缺少函数名"); + throw std::runtime_error(FormatError("irgen", "缺少函数名")); } func_ = module_.CreateFunction(func.Ident()->getText(), ir::Type::Int32()); diff --git a/src/irgen/IRGenStmt.cpp b/src/irgen/IRGenStmt.cpp index 9b63daa..67ce213 100644 --- a/src/irgen/IRGenStmt.cpp +++ b/src/irgen/IRGenStmt.cpp @@ -4,18 +4,19 @@ #include "SysYParser.h" #include "ir/IR.h" +#include "utils/Log.h" bool IRGenImpl::GenStmt(SysYParser::StmtContext& stmt) { if (stmt.returnStmt()) { GenReturnStmt(*stmt.returnStmt()); return true; } - throw std::runtime_error("[irgen] 暂不支持的语句类型"); + throw std::runtime_error(FormatError("irgen", "暂不支持的语句类型")); } void IRGenImpl::GenReturnStmt(SysYParser::ReturnStmtContext& ret) { if (!ret.exp()) { - throw std::runtime_error("[irgen] return 缺少表达式"); + throw std::runtime_error(FormatError("irgen", "return 缺少表达式")); } ir::Value* v = GenExpr(*ret.exp()); builder_.CreateRet(v); diff --git a/src/main.cpp b/src/main.cpp index fafc646..cbb4fc9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,7 +28,7 @@ int main(int argc, char** argv) { auto* comp_unit = dynamic_cast(antlr.tree); if (!comp_unit) { - throw std::runtime_error("[main] 语法树根节点不是 compUnit"); + throw std::runtime_error(FormatError("main", "语法树根节点不是 compUnit")); } RunSema(*comp_unit); diff --git a/src/mir/FrameLowering.cpp b/src/mir/FrameLowering.cpp index e6ad9c9..bdf05fc 100644 --- a/src/mir/FrameLowering.cpp +++ b/src/mir/FrameLowering.cpp @@ -3,6 +3,8 @@ #include #include +#include "utils/Log.h" + namespace mir { namespace { @@ -17,8 +19,7 @@ void RunFrameLowering(MachineFunction& function) { for (const auto& slot : function.frame_slots()) { cursor += slot.size; if (-cursor < -256) { - throw std::runtime_error( - "Lab3 MVP 后端暂不支持超过 64 个 i32 栈槽的函数"); + throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧")); } } diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index 8b99276..636e6ea 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -4,6 +4,7 @@ #include #include "ir/IR.h" +#include "utils/Log.h" namespace mir { namespace { @@ -20,8 +21,8 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, auto it = slots.find(value); if (it == slots.end()) { - throw std::runtime_error("Lab3 MVP 后端找不到值对应的栈槽: " + - value->name()); + throw std::runtime_error( + FormatError("mir", "找不到值对应的栈槽: " + value->name())); } block.Append(Opcode::LoadStack, @@ -41,7 +42,8 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, auto& store = static_cast(inst); auto dst = slots.find(store.ptr()); if (dst == slots.end()) { - throw std::runtime_error("Lab3 MVP 后端要求 store 目标必须来自 alloca"); + throw std::runtime_error( + FormatError("mir", "暂不支持对非栈变量地址进行写入")); } EmitValueToReg(store.value(), PhysReg::W8, slots, block); block.Append(Opcode::StoreStack, @@ -52,7 +54,8 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, auto& load = static_cast(inst); auto src = slots.find(load.ptr()); if (src == slots.end()) { - throw std::runtime_error("Lab3 MVP 后端要求 load 源必须来自 alloca"); + throw std::runtime_error( + FormatError("mir", "暂不支持对非栈变量地址进行读取")); } int dst_slot = function.CreateFrameIndex(); block.Append(Opcode::LoadStack, @@ -83,10 +86,10 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, } case ir::Opcode::Sub: case ir::Opcode::Mul: - throw std::runtime_error("Lab3 MVP 后端暂不支持 add 以外的二元运算"); + throw std::runtime_error(FormatError("mir", "暂不支持该二元运算")); } - throw std::runtime_error("Lab3 MVP 后端遇到未知 IR 指令"); + throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令")); } } // namespace @@ -95,19 +98,19 @@ std::unique_ptr LowerToMIR(const ir::Module& module) { DefaultContext(); if (module.functions().size() != 1) { - throw std::runtime_error("Lab3 MVP 后端只支持单函数 main"); + throw std::runtime_error(FormatError("mir", "暂不支持多个函数")); } const auto& func = *module.functions().front(); if (func.name() != "main") { - throw std::runtime_error("Lab3 MVP 后端只支持 main 函数"); + throw std::runtime_error(FormatError("mir", "暂不支持非 main 函数")); } auto machine_func = std::make_unique(func.name()); ValueSlotMap slots; const auto* entry = func.entry(); if (!entry) { - throw std::runtime_error("IR 函数缺少入口基本块"); + throw std::runtime_error(FormatError("mir", "IR 函数缺少入口基本块")); } for (const auto& inst : entry->instructions()) { diff --git a/src/mir/RegAlloc.cpp b/src/mir/RegAlloc.cpp index e9f083f..9262af1 100644 --- a/src/mir/RegAlloc.cpp +++ b/src/mir/RegAlloc.cpp @@ -2,6 +2,8 @@ #include +#include "utils/Log.h" + namespace mir { namespace { @@ -24,7 +26,7 @@ void RunRegAlloc(MachineFunction& function) { for (const auto& inst : function.entry().instructions()) { for (const auto& operand : inst.operands()) { if (operand.kind() == Operand::Kind::Reg && !IsAllowedReg(operand.reg())) { - throw std::runtime_error("Lab3 MVP 后端发现未预着色的寄存器"); + throw std::runtime_error(FormatError("mir", "寄存器分配失败")); } } } diff --git a/src/sem/Sema.cpp b/src/sem/Sema.cpp index d64d9f0..cdc797d 100644 --- a/src/sem/Sema.cpp +++ b/src/sem/Sema.cpp @@ -4,6 +4,7 @@ #include #include "sem/SymbolTable.h" +#include "utils/Log.h" namespace { @@ -18,7 +19,7 @@ void CheckPrimary(SysYParser::PrimaryContext& primary, if (primary.Ident()) { const std::string name = primary.Ident()->getText(); if (!table.Contains(name)) { - throw std::runtime_error("[sema] 使用了未定义的变量: " + name); + throw std::runtime_error(FormatError("sema", "使用了未定义的变量: " + name)); } return; } @@ -28,12 +29,12 @@ void CheckPrimary(SysYParser::PrimaryContext& primary, return; } - throw std::runtime_error("[sema] 暂不支持的 primary 形式"); + throw std::runtime_error(FormatError("sema", "暂不支持的表达式形式")); } void CheckExpr(SysYParser::ExpContext& exp, const SymbolTable& table) { if (!exp.addExp()) { - throw std::runtime_error("[sema] 非法表达式"); + throw std::runtime_error(FormatError("sema", "非法表达式")); } const auto& terms = exp.addExp()->primary(); for (auto* term : terms) { @@ -46,10 +47,10 @@ void CheckExpr(SysYParser::ExpContext& exp, const SymbolTable& table) { void RunSema(SysYParser::CompUnitContext& comp_unit) { auto* func = comp_unit.funcDef(); if (!func || !func->block()) { - throw std::runtime_error("[sema] 缺少 main 函数定义"); + throw std::runtime_error(FormatError("sema", "缺少 main 函数定义")); } if (!func->Ident() || func->Ident()->getText() != "main") { - throw std::runtime_error("[sema] 入口函数必须命名为 main"); + throw std::runtime_error(FormatError("sema", "入口函数必须命名为 main")); } SymbolTable table; @@ -57,7 +58,8 @@ void RunSema(SysYParser::CompUnitContext& comp_unit) { const auto& items = func->block()->blockItem(); if (items.empty()) { - throw std::runtime_error("[sema] main 函数不能为空,且必须以 return 结束"); + throw std::runtime_error( + FormatError("sema", "main 函数不能为空,且必须以 return 结束")); } for (size_t i = 0; i < items.size(); ++i) { @@ -66,12 +68,13 @@ void RunSema(SysYParser::CompUnitContext& comp_unit) { continue; } if (seen_return) { - throw std::runtime_error("[sema] return 必须是 main 函数中的最后一条语句"); + throw std::runtime_error( + FormatError("sema", "return 必须是 main 函数中的最后一条语句")); } if (auto* decl = item->decl() ? item->decl()->varDecl() : nullptr) { const std::string name = decl->Ident()->getText(); if (table.Contains(name)) { - throw std::runtime_error("[sema] 重复定义变量: " + name); + throw std::runtime_error(FormatError("sema", "重复定义变量: " + name)); } if (decl->exp()) { CheckExpr(*decl->exp(), table); @@ -84,14 +87,15 @@ void RunSema(SysYParser::CompUnitContext& comp_unit) { CheckExpr(*ret->exp(), table); seen_return = true; if (i + 1 != items.size()) { - throw std::runtime_error("[sema] return 必须是 main 函数中的最后一条语句"); + throw std::runtime_error( + FormatError("sema", "return 必须是 main 函数中的最后一条语句")); } continue; } - throw std::runtime_error("[sema] 暂不支持的 blockItem 类型"); + throw std::runtime_error(FormatError("sema", "暂不支持的语句或声明")); } if (!seen_return) { - throw std::runtime_error("[sema] main 函数必须包含 return 语句"); + throw std::runtime_error(FormatError("sema", "main 函数必须包含 return 语句")); } }