feat(frontend): 命令行添加IR和AST选择输出
This commit is contained in:
@@ -3,3 +3,27 @@
|
||||
// - 表达式、语句、声明、函数、类型等节点
|
||||
// - 支持后续阶段在节点上附加信息(类型、符号绑定、常量值等)
|
||||
#include "ast/AstNodes.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace ast {
|
||||
|
||||
NumberExpr::NumberExpr(int v) : value(v) {}
|
||||
|
||||
VarExpr::VarExpr(std::string n) : name(std::move(n)) {}
|
||||
|
||||
BinaryExpr::BinaryExpr(BinaryOp op, std::shared_ptr<Expr> lhs,
|
||||
std::shared_ptr<Expr> rhs)
|
||||
: op(op), lhs(std::move(lhs)), rhs(std::move(rhs)) {}
|
||||
|
||||
ReturnStmt::ReturnStmt(std::shared_ptr<Expr> v) : value(std::move(v)) {}
|
||||
|
||||
VarDecl::VarDecl(std::string n, std::shared_ptr<Expr> i)
|
||||
: name(std::move(n)), init(std::move(i)) {}
|
||||
|
||||
FuncDef::FuncDef(std::string n, std::shared_ptr<Block> b)
|
||||
: name(std::move(n)), body(std::move(b)) {}
|
||||
|
||||
CompUnit::CompUnit(std::shared_ptr<FuncDef> f) : func(std::move(f)) {}
|
||||
|
||||
} // namespace ast
|
||||
|
||||
@@ -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<Expr> lhs;
|
||||
std::shared_ptr<Expr> rhs;
|
||||
BinaryExpr(BinaryOp op, std::shared_ptr<Expr> lhs, std::shared_ptr<Expr> rhs)
|
||||
: op(op), lhs(std::move(lhs)), rhs(std::move(rhs)) {}
|
||||
BinaryExpr(BinaryOp op, std::shared_ptr<Expr> lhs, std::shared_ptr<Expr> rhs);
|
||||
};
|
||||
|
||||
struct Stmt {
|
||||
@@ -38,14 +37,13 @@ struct Stmt {
|
||||
|
||||
struct ReturnStmt : Stmt {
|
||||
std::shared_ptr<Expr> value;
|
||||
explicit ReturnStmt(std::shared_ptr<Expr> v) : value(std::move(v)) {}
|
||||
explicit ReturnStmt(std::shared_ptr<Expr> v);
|
||||
};
|
||||
|
||||
struct VarDecl {
|
||||
std::string name;
|
||||
std::shared_ptr<Expr> init; // nullptr if no initializer
|
||||
VarDecl(std::string n, std::shared_ptr<Expr> i)
|
||||
: name(std::move(n)), init(std::move(i)) {}
|
||||
VarDecl(std::string n, std::shared_ptr<Expr> i);
|
||||
};
|
||||
|
||||
struct Block {
|
||||
@@ -56,13 +54,12 @@ struct Block {
|
||||
struct FuncDef {
|
||||
std::string name;
|
||||
std::shared_ptr<Block> body;
|
||||
FuncDef(std::string n, std::shared_ptr<Block> b)
|
||||
: name(std::move(n)), body(std::move(b)) {}
|
||||
FuncDef(std::string n, std::shared_ptr<Block> b);
|
||||
};
|
||||
|
||||
struct CompUnit {
|
||||
std::shared_ptr<FuncDef> func;
|
||||
explicit CompUnit(std::shared_ptr<FuncDef> f) : func(std::move(f)) {}
|
||||
explicit CompUnit(std::shared_ptr<FuncDef> f);
|
||||
};
|
||||
|
||||
// 调试打印
|
||||
|
||||
@@ -60,6 +60,7 @@ void PrintAST(const CompUnit& cu) {
|
||||
PrintLine(0, "CompUnit");
|
||||
if (!cu.func) {
|
||||
PrintLine(1, "<empty>");
|
||||
std::cout << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -86,6 +87,7 @@ void PrintAST(const CompUnit& cu) {
|
||||
PrintLine(3, "UnknownStmt");
|
||||
}
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
10
src/main.cpp
10
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;
|
||||
|
||||
@@ -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 <file.dot>] <input.sy>");
|
||||
throw std::runtime_error(
|
||||
"用法: compiler [--help] [--emit-ast] [--emit-ir] [--ast-dot <file.dot>] <input.sy>");
|
||||
}
|
||||
|
||||
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("缺少输入文件:请提供 <input.sy>(使用 --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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,13 +10,17 @@ void PrintHelp(std::ostream& os) {
|
||||
os << "SysY Compiler (课程实验最小可运行示例)\n"
|
||||
<< "\n"
|
||||
<< "用法:\n"
|
||||
<< " compiler [--help] [--ast-dot <file.dot>] <input.sy>\n"
|
||||
<< " compiler [--help] [--emit-ast] [--emit-ir] [--ast-dot <file.dot>] <input.sy>\n"
|
||||
<< "\n"
|
||||
<< "选项:\n"
|
||||
<< " -h, --help 打印帮助信息并退出\n"
|
||||
<< " --emit-ast 仅在显式模式下启用 AST 文本输出\n"
|
||||
<< " --emit-ir 仅在显式模式下启用 IR 输出\n"
|
||||
<< " --ast-dot <path> 导出 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";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user