# SysY 编译器目录结构设计

## 1. 编译流程图

```text
[ 前端 Frontend ]
  C 源代码
    ↓
  Lexer / Parser（ANTLR）
    ↓
  语法树构建 + 语义分析（Sema）
    ↓
  语法树（附加语义信息）

[ 中端 Middle-end ]
  语法树
    ↓
  IR 构建（平台无关 IR，LLVM 风格）
    ↓
  IR 优化（ConstFold / DCE / mem2reg 等，可选）
    ↓
  优化后的 IR

[ 后端 Backend（ARMv8-A / AArch64）]
  IR
    ↓
  IR → MIR（AArch64 指令 + 虚拟寄存器）      ← 指令选择
    ↓
  MIR → MIR（AArch64 指令 + 物理寄存器）      ← 寄存器分配（含 spill/reload）
    ↓
  栈帧构建 / Prologue / Epilogue 插入         ← FrameLowering
    ↓
  MIR（最终机器指令）
    ↓
  汇编打印
    ↓
  ARMv8-A 汇编（.s）
```

## 2. 目录结构

```text
.
├── CMakeLists.txt
├── README.md
├── .gitignore
├── src/
│   ├── CMakeLists.txt
│   ├── main.cpp
│   ├── antlr4/
│   │   └── SysY.g4
│   ├── frontend/
│   │   ├── AntlrDriver.cpp
│   │   └── SyntaxTreePrinter.cpp
│   ├── sem/
│   │   ├── Sema.cpp
│   │   ├── SymbolTable.cpp
│   │   └── ConstEval.cpp
│   ├── irgen/
│   │   ├── CMakeLists.txt
│   │   ├── IRGenDriver.cpp
│   │   ├── IRGenFunc.cpp
│   │   ├── IRGenStmt.cpp
│   │   ├── IRGenExp.cpp
│   │   └── IRGenDecl.cpp
│   ├── ir/
│   │   ├── Context.cpp
│   │   ├── Module.cpp
│   │   ├── Function.cpp
│   │   ├── BasicBlock.cpp
│   │   ├── Type.cpp
│   │   ├── Value.cpp
│   │   ├── Instruction.cpp
│   │   ├── IRBuilder.cpp
│   │   ├── IRPrinter.cpp
│   │   ├── analysis/
│   │   │   ├── DominatorTree.cpp
│   │   │   └── LoopInfo.cpp
│   │   └── passes/
│   │       ├── PassManager.cpp
│   │       ├── Mem2Reg.cpp
│   │       ├── ConstFold.cpp
│   │       ├── DCE.cpp
│   │       └── CFGSimplify.cpp
│   ├── mir/
│   │   ├── MIRContext.cpp
│   │   ├── MIRFunction.cpp
│   │   ├── MIRBasicBlock.cpp
│   │   ├── MIRInstr.cpp
│   │   ├── Register.cpp
│   │   ├── Lowering.cpp
│   │   ├── RegAlloc.cpp
│   │   ├── FrameLowering.cpp
│   │   ├── AsmPrinter.cpp
│   │   └── passes/
│   │       ├── PassManager.cpp
│   │       └── Peephole.cpp
│   └── utils/
│       ├── Log.cpp
│       └── CLI.cpp
├── include/
│   ├── frontend/
│   ├── sem/
│   ├── irgen/
│   ├── ir/
│   ├── mir/
│   └── utils/
├── sylib/
│   ├── sylib.c
│   └── sylib.h
└── test/
    ├── test_case/
    ├── test_result/
    └── run_tests.sh
```

## 3. 文件功能说明

### 3.1 顶层文件

- `CMakeLists.txt`
  - 工程构建入口：配置编译器、添加子目录、链接生成最终可执行文件。
  - 负责集成 ANTLR runtime（通过系统依赖或第三方源码），并将“ANTLR 生成代码所在的构建目录”加入编译。
- `README.md`
  - 实验/工程说明：依赖环境、构建方式、测试脚本用法、ANTLR 生成命令（写在文档中，不提供脚本）。
- `.gitignore`
  - 忽略构建产物（如 `build/`）、ANTLR 自动生成文件、`test/test_result/` 等输出目录。

### 3.2 `src/`：实现代码

#### 3.2.1 入口与构建

- `src/CMakeLists.txt`
  - `src/` 子目录构建脚本：编译各子模块源文件，生成静态库/目标并链接到最终可执行文件。
- `src/main.cpp`
  - 编译器入口：解析命令行参数、驱动完整流水线（Frontend → Middle-end → Backend）。
  - 负责把不同阶段产物输出为文件（如输出 `.ll` / `.s` 的开关可在此集中实现）。

#### 3.2.2 `src/antlr4/`：SysY 文法（只提交 `.g4`）

- `src/antlr4/SysY.g4`
  - SysY 语法定义（lexer + parser rules），为 ANTLR 生成 C++ lexer/parser 提供输入。

- ANTLR 自动生成文件位置约定：该工程采用工程化方式：ANTLR 生成文件**不进入仓库**，统一放到构建目录，例如：
    - `build/generated/antlr4/`

- 典型生成物包括（随生成选项略有差异）：
    - `SysYLexer.cpp/.h`
    - `SysYParser.cpp/.h`
    - `SysYBaseVisitor.cpp/.h`、`SysYVisitor.cpp/.h`
    - `*.tokens`、`*.interp`

#### 3.2.3 `src/frontend/`：语法解析与语法树输出

- `src/frontend/AntlrDriver.cpp`
  - 读取源代码并调用解析流程，得到语法树。
  - 由于语法正确性由测试保证，该模块只需提供“可用的解析入口”，不需要实现复杂的语法错误报告体系。
- `src/frontend/SyntaxTreePrinter.cpp`
  - 语法树调试打印：用于验证语法规则与前端解析行为是否符合预期。

#### 3.2.4 `src/sem/`：语义分析（Sema）

- `src/sem/Sema.cpp`
  - 语义分析主流程：符号解析、类型检查、控制流规则检查、必要的隐式转换插入/记录等。
  - 在语法树基础上完成语义检查，并为后续 IR 生成提供约束。
- `src/sem/SymbolTable.cpp`
  - 符号表与作用域管理：支持嵌套作用域、变量/函数/参数/常量的注册与查找。
- `src/sem/ConstEval.cpp`
  - 常量求值：用于数组维度、全局初始化、`const` 表达式等需要编译期计算的场景。

#### 3.2.5 `src/irgen/`：语法树 → IR（平台无关，LLVM 风格）

- `src/irgen/IRGenDriver.cpp`
  - 驱动语法树遍历，调度各子模块完成翻译。
- `src/irgen/IRGenFunc.cpp`
  - 函数翻译：函数定义、参数列表与返回值翻译；创建对应 IR 函数对象。
- `src/irgen/IRGenStmt.cpp`
  - 语句翻译：if/while/return 等控制流构造，生成基本块与分支。
- `src/irgen/IRGenExp.cpp`
  - 表达式翻译：算术运算、比较、逻辑运算、函数调用等ir指令生成。
- `src/irgen/IRGenDecl.cpp`
  - 声明翻译：处理全局变量、局部变量、数组初始化与空间分配等。

#### 3.2.6 `src/ir/`：LLVM 风格 IR 核心

- `src/ir/Context.cpp`
  - IR 上下文：管理类型/常量创建与复用、字符串/符号等公共资源。
- `src/ir/Module.cpp`
  - Module 容器：保存全局变量、函数列表、目标信息（如需要）、符号表等。
- `src/ir/Function.cpp`
  - Function 容器：参数、基本块列表、属性/元信息等。
- `src/ir/BasicBlock.cpp`
  - 基本块表示：指令序列、前驱/后继关系（显式或可计算）。
- `src/ir/Type.cpp`
  - IR 类型系统：`i32/f32/void`、指针、数组、函数类型等（按 SysY 支持范围裁剪）。
- `src/ir/Value.cpp`
  - SSA 值体系：常量、参数、指令结果等统一抽象。
- `src/ir/Instruction.cpp`
  - 指令体系：二元运算、比较、load/store、call、br/condbr、ret、phi、alloca 等（按需求逐步补齐）。
- `src/ir/IRBuilder.cpp`
  - IR 构建工具：集中管理插入点与指令创建，降低 IRGen 复杂度。
- `src/ir/IRPrinter.cpp`
  - IR 文本输出：打印为 `.ll` 风格文本，支撑调试与测试对比。
- `src/ir/analysis/DominatorTree.cpp`
  - 支配树分析：为 `mem2reg`、部分 CFG 优化与循环分析提供基础能力。
- `src/ir/analysis/LoopInfo.cpp`
  - 循环分析：识别循环结构，为后续优化（可选）提供信息。
- `src/ir/passes/PassManager.cpp`
  - IR pass 管理：按优化级别组织 pipeline，并统一运行与统计。
- `src/ir/passes/Mem2Reg.cpp`
  - SSA 构造关键 pass：将局部变量的 `alloca/load/store` 提升为 SSA（插入 PHI）。
- `src/ir/passes/ConstFold.cpp`
  - IR 常量折叠：简化可判定的常量表达与常量控制流分支（按实现范围裁剪）。
- `src/ir/passes/DCE.cpp`
  - 死代码删除：删除无用指令与无用块（与 CFG 简化配合）。
- `src/ir/passes/CFGSimplify.cpp`
  - CFG 简化：删除不可达块、合并空块、简化分支等。

#### 3.2.7 `src/mir/`：Machine IR

- `src/mir/MIRContext.cpp`
  - MIR 上下文：保存目标约束、指令集信息等。
- `src/mir/MIRFunction.cpp`
  - 机器函数：包含机器基本块、栈帧信息、虚拟/物理寄存器管理等。
- `src/mir/MIRBasicBlock.cpp`
  - 机器基本块：机器指令列表与 CFG 信息。
- `src/mir/MIRInstr.cpp`
  - 机器指令：opcode + operands（寄存器/立即数/栈槽/符号/标签等）。
- `src/mir/Register.cpp`
  - 寄存器表示：区分虚拟寄存器与物理寄存器，提供编号/属性等。
  - 寄存器类（RegClass）：GPR/FPR 等分类与可分配集合描述（供 RA 使用）。
- `src/mir/Lowering.cpp`
  - IR → MIR：从平台无关 IR 生成 AArch64 指令的 MIR（在此完成指令选择），初始使用虚拟寄存器。
- `src/mir/RegAlloc.cpp`
  - 寄存器分配主入口：将虚拟寄存器分配到物理寄存器，并驱动 spill/reload 等后续处理。
- `src/mir/FrameLowering.cpp`
  - 栈帧布局与序言尾声：根据寄存器分配阶段记录的栈槽需求计算栈大小与对齐，插入 prologue/epilogue，保存/恢复 callee-saved 等。
- `src/mir/AsmPrinter.cpp`
  - 汇编打印：将最终机器指令 MIR 打印为 ARMv8-A 汇编 `.s`。
- `src/mir/passes/PassManager.cpp`
  - MIR pass 管理：组织后端 pass 的运行顺序（PreRA/PostRA/PEI 等阶段）。
- `src/mir/passes/Peephole.cpp`
  - 窥孔优化：删除冗余 move、合并常见指令模式，提升最终汇编质量。

#### 3.2.8 `src/utils/`：日志与命令行

- `src/utils/Log.cpp`
  - 日志输出：统一调试信息、阶段信息与错误信息输出。
- `src/utils/CLI.cpp`
  - 命令行参数解析：输入/输出路径、输出类型（IR/MIR/ASM）、优化级别等。

### 3.3 `include/`：头文件目录

`include/` 目录与 `src/` 分层保持一致，用于放置对外可复用的头文件（具体头文件列表按实现新增）。

### 3.4 `sylib/`：SysY 运行库

- `sylib/sylib.c`
  - SysY 运行库实现（按实验/评测规范提供 I/O 等函数）。
- `sylib/sylib.h`
  - 运行库头文件声明（供编译器生成 `call` 时引用，或用于链接阶段）。

### 3.5 `test/`：测试

- `test/test_case/`
  - 测试输入目录：存放 `*.sy` 测试用例（可选搭配 `*.in` 作为 stdin 输入）。
- `test/test_result/`
  - 测试输出目录：由测试脚本生成 `.ll/.s`、运行输出、diff 结果与日志等。
  - 建议通过 `.gitignore` 忽略，不纳入版本管理。
- `test/run_tests.sh`
  - Bash 测试脚本：批量编译 `test_case/`，将产物写入 `test_result/`，并汇总通过/失败信息。
