Files
nudt-compiler-cpp/doc/目录结构设计.md
2025-12-26 15:27:35 +08:00

284 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SysY 编译器目录结构设计
## 1. 编译流程图
```text
[ 前端 Frontend ]
C 源代码
Lexer / ParserANTLR
AST 构建 + 语义分析Sema
AST带类型 / 符号 / 常量)
[ 中端 Middle-end ]
AST
IR 构建(平台无关 IRLLVM 风格)
IR 优化ConstFold / DCE / mem2reg 等,可选)
优化后的 IR
[ 后端 BackendARMv8-A / AArch64]
IR
IR → MIRAArch64 指令 + 虚拟寄存器) ← 指令选择
MIR → MIRAArch64 指令 + 物理寄存器) ← 寄存器分配(含 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
│ │ └── AstBuilder.cpp
│ ├── ast/
│ │ ├── AstNodes.cpp
│ │ └── AstPrinter.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/
│ ├── ast/
│ ├── 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/`ANTLR 调用与 AST 构建
- `src/frontend/AntlrDriver.cpp`
- 读取源代码并调用 ANTLR 生成的 lexer/parser得到 parse tree。
- 由于语法正确性由测试保证,该模块只需提供“可用的解析入口”,不需要实现复杂的语法错误报告体系。
- `src/frontend/AstBuilder.cpp`
- 将 parse tree 转换为 AST`src/ast/*`),并在 AST 节点上保留必要的定位信息(可选,用于调试/日志)。
#### 3.2.4 `src/ast/`抽象语法树AST
- `src/ast/AstNodes.cpp`
- AST 节点定义与实现:表达式、语句、声明、函数、类型等。
- AST 节点应当能够承载后续阶段附加信息(类型、符号绑定、常量值等)。
- `src/ast/AstPrinter.cpp`
- AST 调试打印:用于验证 AST 构建是否符合预期,便于定位前端/语义阶段问题。
#### 3.2.5 `src/sem/`语义分析Sema
- `src/sem/Sema.cpp`
- 语义分析主流程:符号解析、类型检查、控制流规则检查、必要的隐式转换插入/记录等。
- 输出为“带类型 / 符号 / 常量信息”的 AST可通过在 AST 节点上附加属性实现)。
- `src/sem/SymbolTable.cpp`
- 符号表与作用域管理:支持嵌套作用域、变量/函数/参数/常量的注册与查找。
- `src/sem/ConstEval.cpp`
- 常量求值:用于数组维度、全局初始化、`const` 表达式等需要编译期计算的场景。
#### 3.2.6 `src/irgen/`AST → IR平台无关LLVM 风格)
- `src/irgen/IRGenDriver.cpp`
- 驱动 Visitor 遍历 AST调度各子模块完成翻译。
- `src/irgen/IRGenFunc.cpp`
- 函数翻译:函数定义、参数列表与返回值翻译;创建对应 IR 函数对象。
- `src/irgen/IRGenStmt.cpp`
- 语句翻译if/while/return 等控制流构造,生成基本块与分支。
- `src/irgen/IRGenExp.cpp`
- 表达式翻译算术运算、比较、逻辑运算、函数调用等ir指令生成。
- `src/irgen/IRGenDecl.cpp`
- 声明翻译:处理全局变量、局部变量、数组初始化与空间分配等。
#### 3.2.7 `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.8 `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`
- 寄存器表示:区分虚拟寄存器与物理寄存器,提供编号/属性等。
- 寄存器类RegClassGPR/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.9 `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/`,并汇总通过/失败信息。