From 66659524c816e379055f1729cad58f0f27042861 Mon Sep 17 00:00:00 2001 From: jing <3030349106@qq.com> Date: Sat, 28 Feb 2026 23:40:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20=E5=91=BD=E4=BB=A4=E8=A1=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0IR=E5=92=8CAST=E9=80=89=E6=8B=A9=E8=BE=93?= =?UTF-8?q?=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ast/AstNodes.cpp | 24 ++++++++++++++++++++++++ src/ast/AstNodes.h | 17 +++++++---------- src/ast/AstPrinter.cpp | 2 ++ src/main.cpp | 10 +++++++--- src/utils/CLI.cpp | 28 +++++++++++++++++++++++++++- src/utils/CLI.h | 2 ++ src/utils/Log.cpp | 8 ++++++-- 7 files changed, 75 insertions(+), 16 deletions(-) diff --git a/src/ast/AstNodes.cpp b/src/ast/AstNodes.cpp index 5493907..380e36e 100644 --- a/src/ast/AstNodes.cpp +++ b/src/ast/AstNodes.cpp @@ -3,3 +3,27 @@ // - 表达式、语句、声明、函数、类型等节点 // - 支持后续阶段在节点上附加信息(类型、符号绑定、常量值等) #include "ast/AstNodes.h" + +#include + +namespace ast { + +NumberExpr::NumberExpr(int v) : value(v) {} + +VarExpr::VarExpr(std::string n) : name(std::move(n)) {} + +BinaryExpr::BinaryExpr(BinaryOp op, std::shared_ptr lhs, + std::shared_ptr rhs) + : op(op), lhs(std::move(lhs)), rhs(std::move(rhs)) {} + +ReturnStmt::ReturnStmt(std::shared_ptr v) : value(std::move(v)) {} + +VarDecl::VarDecl(std::string n, std::shared_ptr i) + : name(std::move(n)), init(std::move(i)) {} + +FuncDef::FuncDef(std::string n, std::shared_ptr b) + : name(std::move(n)), body(std::move(b)) {} + +CompUnit::CompUnit(std::shared_ptr f) : func(std::move(f)) {} + +} // namespace ast diff --git a/src/ast/AstNodes.h b/src/ast/AstNodes.h index 55efccc..cfe5908 100644 --- a/src/ast/AstNodes.h +++ b/src/ast/AstNodes.h @@ -16,20 +16,19 @@ struct Expr { struct NumberExpr : Expr { int value{}; - explicit NumberExpr(int v) : value(v) {} + explicit NumberExpr(int v); }; struct VarExpr : Expr { std::string name; - explicit VarExpr(std::string n) : name(std::move(n)) {} + explicit VarExpr(std::string n); }; struct BinaryExpr : Expr { BinaryOp op; std::shared_ptr lhs; std::shared_ptr rhs; - BinaryExpr(BinaryOp op, std::shared_ptr lhs, std::shared_ptr rhs) - : op(op), lhs(std::move(lhs)), rhs(std::move(rhs)) {} + BinaryExpr(BinaryOp op, std::shared_ptr lhs, std::shared_ptr rhs); }; struct Stmt { @@ -38,14 +37,13 @@ struct Stmt { struct ReturnStmt : Stmt { std::shared_ptr value; - explicit ReturnStmt(std::shared_ptr v) : value(std::move(v)) {} + explicit ReturnStmt(std::shared_ptr v); }; struct VarDecl { std::string name; std::shared_ptr init; // nullptr if no initializer - VarDecl(std::string n, std::shared_ptr i) - : name(std::move(n)), init(std::move(i)) {} + VarDecl(std::string n, std::shared_ptr i); }; struct Block { @@ -56,13 +54,12 @@ struct Block { struct FuncDef { std::string name; std::shared_ptr body; - FuncDef(std::string n, std::shared_ptr b) - : name(std::move(n)), body(std::move(b)) {} + FuncDef(std::string n, std::shared_ptr b); }; struct CompUnit { std::shared_ptr func; - explicit CompUnit(std::shared_ptr f) : func(std::move(f)) {} + explicit CompUnit(std::shared_ptr f); }; // 调试打印 diff --git a/src/ast/AstPrinter.cpp b/src/ast/AstPrinter.cpp index 5aec665..89510ba 100644 --- a/src/ast/AstPrinter.cpp +++ b/src/ast/AstPrinter.cpp @@ -60,6 +60,7 @@ void PrintAST(const CompUnit& cu) { PrintLine(0, "CompUnit"); if (!cu.func) { PrintLine(1, ""); + std::cout << "\n"; return; } @@ -86,6 +87,7 @@ void PrintAST(const CompUnit& cu) { PrintLine(3, "UnknownStmt"); } } + std::cout << "\n"; } namespace { diff --git a/src/main.cpp b/src/main.cpp index 816409d..b296dc8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,9 @@ int main(int argc, char** argv) { } auto antlr = ParseFileWithAntlr(opts.input); auto ast = BuildAst(antlr.tree); - ast::PrintAST(*ast); // 调试 AST + if (opts.emit_ast) { + ast::PrintAST(*ast); // 调试 AST + } if (!opts.ast_dot_output.empty()) { std::ofstream dot_out(opts.ast_dot_output); if (!dot_out) { @@ -34,8 +36,10 @@ int main(int argc, char** argv) { // 同学们可以在 irgen/ 目录下按提示自行完善或替换实现。 auto module = GenerateIR(*ast); - ir::IRPrinter printer; - printer.Print(*module); + if (opts.emit_ir) { + ir::IRPrinter printer; + printer.Print(*module); + } } catch (const std::exception& ex) { std::cerr << "error: " << ex.what() << "\n"; return 1; diff --git a/src/utils/CLI.cpp b/src/utils/CLI.cpp index ef8f325..8409ac5 100644 --- a/src/utils/CLI.cpp +++ b/src/utils/CLI.cpp @@ -11,9 +11,11 @@ CLIOptions ParseCLI(int argc, char** argv) { CLIOptions opt; + bool explicit_emit = false; if (argc <= 1) { - throw std::runtime_error("用法: compiler [--help] [--ast-dot ] "); + throw std::runtime_error( + "用法: compiler [--help] [--emit-ast] [--emit-ir] [--ast-dot ] "); } for (int i = 1; i < argc; ++i) { @@ -31,6 +33,26 @@ CLIOptions ParseCLI(int argc, char** argv) { continue; } + if (std::strcmp(arg, "--emit-ast") == 0) { + if (!explicit_emit) { + opt.emit_ast = false; + opt.emit_ir = false; + explicit_emit = true; + } + opt.emit_ast = true; + continue; + } + + if (std::strcmp(arg, "--emit-ir") == 0) { + if (!explicit_emit) { + opt.emit_ast = false; + opt.emit_ir = false; + explicit_emit = true; + } + opt.emit_ir = true; + continue; + } + if (arg[0] == '-') { throw std::runtime_error(std::string("未知参数: ") + arg + "(使用 --help 查看用法)"); @@ -46,5 +68,9 @@ CLIOptions ParseCLI(int argc, char** argv) { if (opt.input.empty() && !opt.show_help) { throw std::runtime_error("缺少输入文件:请提供 (使用 --help 查看用法)"); } + if (!opt.emit_ast && !opt.emit_ir && opt.ast_dot_output.empty()) { + throw std::runtime_error( + "未选择任何输出:请使用 --emit-ast 或 --emit-ir(或使用 --ast-dot 导出图)"); + } return opt; } diff --git a/src/utils/CLI.h b/src/utils/CLI.h index de5440c..9c42cff 100644 --- a/src/utils/CLI.h +++ b/src/utils/CLI.h @@ -6,6 +6,8 @@ struct CLIOptions { std::string input; std::string ast_dot_output; + bool emit_ast = true; + bool emit_ir = true; bool show_help = false; }; diff --git a/src/utils/Log.cpp b/src/utils/Log.cpp index 58a7c26..92b7a04 100644 --- a/src/utils/Log.cpp +++ b/src/utils/Log.cpp @@ -10,13 +10,17 @@ void PrintHelp(std::ostream& os) { os << "SysY Compiler (课程实验最小可运行示例)\n" << "\n" << "用法:\n" - << " compiler [--help] [--ast-dot ] \n" + << " compiler [--help] [--emit-ast] [--emit-ir] [--ast-dot ] \n" << "\n" << "选项:\n" << " -h, --help 打印帮助信息并退出\n" + << " --emit-ast 仅在显式模式下启用 AST 文本输出\n" + << " --emit-ir 仅在显式模式下启用 IR 输出\n" << " --ast-dot 导出 AST Graphviz DOT 到指定文件\n" << "\n" << "说明:\n" - << " - 当前默认将 IR 输出到标准输出,可使用重定向写入文件:\n" + << " - 默认同时输出 AST 与 IR\n" + << " - 若使用 --emit-ast/--emit-ir,则仅输出显式选择的阶段\n" + << " - 可使用重定向写入文件:\n" << " compiler test/test_case/simple_add.sy > out.ll\n"; }