Files
nudt-compiler-cpp/doc/Lab2-中间表示生成.md
2026-03-12 16:25:20 +08:00

91 lines
3.1 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.
# Lab2中间表示生成
## 1. 本实验定位
Lab2 的目标是在该示例基础上扩展语义覆盖范围,逐步把更多 SysY 语法正确翻译为 IR。
## 2. Lab2 要求
需要同学完成:
1. 熟悉 IR 相关数据结构与构建接口。
2. 理解当前语法树 -> IR 的最小实现流程。
3. 在现有框架上扩展 IR 生成能力使其覆盖课程要求的Sysy语法。
## 3. 当前代码框架
1. IR 定义与打印
- `include/ir/IR.h`
- `src/ir/IRBuilder.cpp`
- `src/ir/IRPrinter.cpp`
2. 语法树 -> IR 生成器
- `include/irgen/IRGen.h`
- `src/irgen/IRGenDriver.cpp`
- `src/irgen/IRGenFunc.cpp`
- `src/irgen/IRGenDecl.cpp`
- `src/irgen/IRGenStmt.cpp`
- `src/irgen/IRGenExp.cpp`
3. 入口流程
- `src/main.cpp`
## 4. Lab2 需要补充的内容
1. 必须修改的文件
- `src/irgen/IRGenDecl.cpp`
- `src/irgen/IRGenStmt.cpp`
- `src/irgen/IRGenExp.cpp`
- `include/ir/IR.h`(当现有 IR 指令/类型不够用时)
- `src/ir/IRBuilder.cpp`(当需要新增构建接口时)
- `src/ir/IRPrinter.cpp`(新增 IR 指令后补齐打印)
- `include/irgen/IRGen.h`(当需要扩展状态或辅助接口时)
2. 视实现需要可能修改
- `src/main.cpp`(当需要调整输出阶段行为)
## 5. 当前最小示例实现说明
当前语法树 -> IR 仅覆盖最小子集:
1. 常量整数、变量引用、二元加法表达式。
2. 局部变量声明(当前采用 LLVM 前端常见的 `alloca/load/store` 内存模型)。
3. `return` 语句。
4. 单函数 `main` 的最小流程。
说明:当前阶段变量统一采用内存模型:先 `alloca` 分配栈槽,再通过 `store/load` 读写。即使变量由常量初始化(如 `int a = 1;`),也会先 `store` 到栈槽,而不是直接把变量替换成 SSA 值。后续实验中,同学可按需求再重构。
此外,当前 IR 还维护了最基本的 use-def 关系:每个 `Value` 会记录哪些 `Instruction` 使用了它。
这对后续做数据流分析、死代码删除、常量传播等优化会很有帮助;但目前相关实现,接口仍不完整,后续实验中还需要同学继续补充和完善。
## 6. 构建与运行
```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j "$(nproc)"
```
## 7. Lab2 验证方式
可先用单个样例检查 IR 输出是否基本正确:
```bash
./build/bin/compiler --emit-ir test/test_case/simple_add.sy
```
如需打印语法树:
```bash
./build/bin/compiler --emit-parse-tree test/test_case/simple_add.sy
```
推荐使用统一脚本验证 “IR -> LLVM 后端 -> 可执行程序” 整体链路。`--run` 模式下会自动读取同名 `.in`,并将程序输出与退出码和同名 `.out` 比对,用于验证 IR 的正确性:
```bash
./scripts/verify_ir.sh test/test_case/simple_add.sy test/test_result/ir --run
```
但最终不能只检查 `simple_add`。完成 Lab2 后,应对 `test/test_case` 下全部测试用例逐个回归,确认 IR 生成与 `--run` 链路都能通过;如有需要,也可以自行编写批量测试脚本统一执行。