|
|
// 命令行参数解析:
|
|
|
// - 解析输入/输出路径
|
|
|
// - 解析输出类型(IR/MIR/ASM)与优化级别等选项
|
|
|
// - 将参数传递给 main.cpp 的编译流水线驱动
|
|
|
|
|
|
#include "utils/CLI.h"
|
|
|
|
|
|
#include <stdexcept>
|
|
|
#include <string>
|
|
|
#include <cstring>
|
|
|
|
|
|
CLIOptions ParseCLI(int argc, char** argv) {
|
|
|
CLIOptions opt;
|
|
|
bool explicit_emit = false;
|
|
|
|
|
|
if (argc <= 1) {
|
|
|
throw std::runtime_error(
|
|
|
"用法: compiler [--help] [--emit-ast] [--emit-ir] [--emit-asm] [--ast-dot <file.dot>] <input.sy>");
|
|
|
}
|
|
|
|
|
|
for (int i = 1; i < argc; ++i) {
|
|
|
const char* arg = argv[i];
|
|
|
if (std::strcmp(arg, "-h") == 0 || std::strcmp(arg, "--help") == 0) {
|
|
|
opt.show_help = true;
|
|
|
return opt;
|
|
|
}
|
|
|
|
|
|
if (std::strcmp(arg, "--ast-dot") == 0) {
|
|
|
if (i + 1 >= argc) {
|
|
|
throw std::runtime_error("参数错误: --ast-dot 需要一个输出路径");
|
|
|
}
|
|
|
opt.ast_dot_output = argv[++i];
|
|
|
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;
|
|
|
opt.emit_asm = false;
|
|
|
explicit_emit = true;
|
|
|
}
|
|
|
opt.emit_ir = true;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (std::strcmp(arg, "--emit-asm") == 0) {
|
|
|
if (!explicit_emit) {
|
|
|
opt.emit_ast = false;
|
|
|
opt.emit_ir = false;
|
|
|
opt.emit_asm = false;
|
|
|
explicit_emit = true;
|
|
|
}
|
|
|
opt.emit_asm = true;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (arg[0] == '-') {
|
|
|
throw std::runtime_error(std::string("未知参数: ") + arg +
|
|
|
"(使用 --help 查看用法)");
|
|
|
}
|
|
|
|
|
|
if (!opt.input.empty()) {
|
|
|
throw std::runtime_error(
|
|
|
"参数过多:当前只支持 1 个输入文件(使用 --help 查看用法)");
|
|
|
}
|
|
|
opt.input = arg;
|
|
|
}
|
|
|
|
|
|
if (opt.input.empty() && !opt.show_help) {
|
|
|
throw std::runtime_error("缺少输入文件:请提供 <input.sy>(使用 --help 查看用法)");
|
|
|
}
|
|
|
if (!opt.emit_ast && !opt.emit_ir && !opt.emit_asm &&
|
|
|
opt.ast_dot_output.empty()) {
|
|
|
throw std::runtime_error(
|
|
|
"未选择任何输出:请使用 --emit-ast / --emit-ir / --emit-asm(或使用 --ast-dot 导出图)");
|
|
|
}
|
|
|
return opt;
|
|
|
}
|