From 847dc7a5cf64ca44ff9b433bc6e9b1e0ee1db85d Mon Sep 17 00:00:00 2001 From: jing <3030349106@qq.com> Date: Sat, 7 Mar 2026 22:43:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(frontend):=20=E8=A1=A5=E5=85=85=E4=B8=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=AF=AD=E6=B3=95=E7=9A=84=E8=AD=A6=E5=91=8A?= =?UTF-8?q?=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/AntlrDriver.cpp | 40 ++++++++++++++++++++++++++++++++++-- src/irgen/IRGenDecl.cpp | 2 +- src/irgen/IRGenExp.cpp | 4 ++-- src/irgen/IRGenFunc.cpp | 2 +- src/irgen/IRGenStmt.cpp | 2 +- src/sem/Sema.cpp | 2 +- 6 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/frontend/AntlrDriver.cpp b/src/frontend/AntlrDriver.cpp index 29eb1c3..e1d05db 100644 --- a/src/frontend/AntlrDriver.cpp +++ b/src/frontend/AntlrDriver.cpp @@ -4,15 +4,30 @@ #include #include #include +#include #include "SysYLexer.h" #include "SysYParser.h" #include "antlr4-runtime.h" +namespace { + +class ParseErrorListener : public antlr4::BaseErrorListener { + public: + void syntaxError(antlr4::Recognizer* /*recognizer*/, antlr4::Token* /*offendingSymbol*/, + size_t line, size_t charPositionInLine, + const std::string& msg, std::exception_ptr /*e*/) override { + throw std::runtime_error("[parse] 暂不支持的语法/词法 @" + std::to_string(line) + ":" + + std::to_string(charPositionInLine) + " - " + msg); + } +}; + +} // namespace + AntlrResult ParseFileWithAntlr(const std::string& path) { std::ifstream fin(path); if (!fin.is_open()) { - throw std::runtime_error("无法打开输入文件: " + path); + throw std::runtime_error("[parse] 无法打开输入文件: " + path); } std::ostringstream ss; ss << fin.rdbuf(); @@ -21,8 +36,29 @@ AntlrResult ParseFileWithAntlr(const std::string& path) { auto lexer = std::make_unique(input.get()); auto tokens = std::make_unique(lexer.get()); auto parser = std::make_unique(tokens.get()); + + ParseErrorListener error_listener; + lexer->removeErrorListeners(); + lexer->addErrorListener(&error_listener); parser->removeErrorListeners(); - auto tree = parser->compUnit(); + parser->addErrorListener(&error_listener); + parser->setErrorHandler(std::make_shared()); + antlr4::tree::ParseTree* tree = nullptr; + try { + tree = parser->compUnit(); + } catch (const std::exception& ex) { + const std::string msg = ex.what(); + if (!msg.empty()) { + throw std::runtime_error("[parse] 暂不支持的语法/词法 - " + msg); + } + if (auto* tok = parser->getCurrentToken()) { + throw std::runtime_error("[parse] 暂不支持的语法/词法 @" + + std::to_string(tok->getLine()) + ":" + + std::to_string(tok->getCharPositionInLine()) + + " near token '" + tok->getText() + "'"); + } + throw std::runtime_error("[parse] 暂不支持的语法/词法"); + } AntlrResult result; result.input = std::move(input); diff --git a/src/irgen/IRGenDecl.cpp b/src/irgen/IRGenDecl.cpp index a676dfa..099ea0b 100644 --- a/src/irgen/IRGenDecl.cpp +++ b/src/irgen/IRGenDecl.cpp @@ -28,7 +28,7 @@ void IRGenImpl::GenBlock(const ast::Block& block) { void IRGenImpl::GenVarDecl(const ast::VarDecl& decl) { auto it = locals_.find(decl.name); if (it == locals_.end()) { - throw std::runtime_error("变量栈槽未创建: " + decl.name); + throw std::runtime_error("[irgen] 变量栈槽未创建: " + decl.name); } ir::Value* init = nullptr; diff --git a/src/irgen/IRGenExp.cpp b/src/irgen/IRGenExp.cpp index 29ba2f6..2dfc6aa 100644 --- a/src/irgen/IRGenExp.cpp +++ b/src/irgen/IRGenExp.cpp @@ -16,7 +16,7 @@ ir::Value* IRGenImpl::GenExpr(const ast::Expr& expr) { if (auto var = dynamic_cast(&expr)) { auto it = locals_.find(var->name); if (it == locals_.end()) { - throw std::runtime_error("变量未找到: " + var->name); + throw std::runtime_error("[irgen] 变量未找到: " + var->name); } std::string name = ir::DefaultContext().NextTemp(); return builder_.CreateLoad(it->second, name); @@ -33,5 +33,5 @@ ir::Value* IRGenImpl::GenExpr(const ast::Expr& expr) { return builder_.CreateBinary(ir::Opcode::Add, lhs, rhs, name); } } - throw std::runtime_error("不支持的表达式类型"); + throw std::runtime_error("[irgen] 暂不支持的表达式类型"); } diff --git a/src/irgen/IRGenFunc.cpp b/src/irgen/IRGenFunc.cpp index 6600a1a..e1b4a24 100644 --- a/src/irgen/IRGenFunc.cpp +++ b/src/irgen/IRGenFunc.cpp @@ -16,7 +16,7 @@ IRGenImpl::IRGenImpl(ir::Module& module) void IRGenImpl::Gen(const ast::CompUnit& ast) { if (!ast.func || !ast.func->body) { - throw std::runtime_error("AST 不完整:缺少 main 定义"); + throw std::runtime_error("[irgen] AST 不完整:缺少 main 定义"); } GenBlock(*ast.func->body); } diff --git a/src/irgen/IRGenStmt.cpp b/src/irgen/IRGenStmt.cpp index 6e9d189..9704f98 100644 --- a/src/irgen/IRGenStmt.cpp +++ b/src/irgen/IRGenStmt.cpp @@ -15,5 +15,5 @@ void IRGenImpl::GenStmt(const ast::Stmt& stmt) { builder_.CreateRet(v); return; } - throw std::runtime_error("不支持的语句类型"); + throw std::runtime_error("[irgen] 暂不支持的语句类型"); } diff --git a/src/sem/Sema.cpp b/src/sem/Sema.cpp index 9c9f305..68e9056 100644 --- a/src/sem/Sema.cpp +++ b/src/sem/Sema.cpp @@ -34,7 +34,7 @@ class SemaVisitor { void CheckExpr(const ast::Expr& expr) { if (auto var = dynamic_cast(&expr)) { if (!table_.Contains(var->name)) { - throw std::runtime_error("使用了未定义的变量: " + var->name); + throw std::runtime_error("[sema] 使用了未定义的变量: " + var->name); } } else if (auto bin = dynamic_cast(&expr)) { CheckExpr(*bin->lhs);