|
|
12 hours ago | |
|---|---|---|
| doc | 12 hours ago | |
| src | 12 hours ago | |
| test | 12 hours ago | |
| Cargo.lock | 4 days ago | |
| Cargo.toml | 4 days ago | |
| README.md | 3 days ago | |
| build.rs | 4 days ago | |
README.md
SysY 编译器课程实验(Rust)
本仓库为“并行编译课程实验”提供一个 SysY 编译器的最小可运行示例,实验按 Lab1 至 Lab6 逐步完成: 从前端(词法/语法分析与语法树处理)到中端(IR 生成、基本标量优化),再到后端(ARM64/AArch64 汇编生成、寄存器分配与后端优化),最后进行循环/并行相关优化。目前仓库提供了面向 AArch64 的后端实现,未提供 RISC-V 后端代码;但从 SysY 源程序到中端生成的实现与机器无关,Lab1 至 Lab4 的内容对 RISC-V 同样具有参考价值,二者在后端指令集与寄存器方面存在差异,但实现思路是共通的。
一、实验内容
| 实验 | 名称 | 任务/目标 |
|---|---|---|
| Lab1 | 语法树构建 | 基于 SysY 源程序完成语法分析与语法树构建,并按约定输出语法树 |
| Lab2 | 中间表示生成 | 将语法树翻译为 LLVM 风格的中间表示(IR),并输出 IR |
| Lab3 | 指令选择与汇编生成 | 将 IR 翻译为目标平台汇编代码(本项目以 ARM64/AArch64 为主) |
| Lab4 | 基本标量优化 | 实现常量传播、死代码删除、简化控制流图等标量优化 |
| Lab5 | 寄存器分配与后端优化 | 为虚拟寄存器分配物理寄存器,完成溢出/重载、冗余指令消除与局部优化 |
| Lab6 | 并行与循环优化 | 面向循环的优化(循环变换/并行化等),进一步提升程序性能 |
二、关于 Rust
Rust 是一门由 Mozilla 开发的现代系统级编程语言,其特点在于能够在保证与 C/C++ 相媲美的性能(无垃圾收集和运行时)的同时,通过所有权系统和借用检查器,在编译期杜绝内存安全和并发安全方面的常见错误(如空指针、悬垂指针和数据竞争)。此外,Rust 还提供零成本抽象、模式匹配、包管理器 Cargo 以及友好的编译器错误提示。
结合编译比赛的实际经验,提供几点参考:
- Rust 学习曲线较 C/C++ 稍陡,但本实验所设计的编译器较为基础,未涉及过于复杂的 Rust 高级用法。网上存在许多可用参考资料:
- 菜鸟教程
- Rust 程序设计语言
- Rust 语言圣经
- 此外,南开大学编译系统原理的实验文档同时提供了 C++ 和 Rust 的实现介绍。
- Rust 提供成熟的项目管理工具 Cargo,无需手写 Makefile,可一站式解决依赖、编译和运行问题。
- Rust 编译器检查严格,若实现逻辑正确且通过编译,通常可避免运行时的内存错误,调试时配合 VSCode 的
CodeLLDB插件即可。 - Rust 并非面向对象语言,不存在类的概念,结构体之间的关系可能不如 C++ 直观,但枚举类型为语法树操作提供了便利。
- Rust 提供
lalrpop等语法解析工具,便于实现语法分析器和灵活的 AST 操作。 - Rust 生态系统丰富,许多库可直接使用,相关资源可访问 Rust 官方学习页面。
三、实验环境配置
3.1 系统建议
建议使用 Ubuntu 22.04 或 WSL(Ubuntu 22.04 环境)。虽然 Rust 在 Windows 和 Linux 上均可方便配置,但后续可能使用 ARM 或 RISC-V 工具链,在 Linux 环境下配置更为便捷。
3.2 Rust 环境配置
在 Ubuntu 中安装 Rust 环境:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
安装完成后,验证:
rustc --version
建议搭配 VSCode 使用,并安装插件 rust-analyzer。
3.3 安装 LLVM 工具链
LLVM 工具链可用于生成中间表示(IR),若输出的 IR 符合 LLVM-IR 语法,可在 IR 层验证中间代码生成和优化的正确性,便于与后端开发解耦。
sudo apt update
sudo apt install -y llvm clang
3.4 安装 ARM64 交叉编译工具链与 QEMU
后续实验将生成 ARM64/AArch64 汇编代码,并使用 ARM64 交叉编译工具链完成汇编与链接;通过 QEMU 用户态模拟器运行生成的 ARM 可执行文件。
# 安装 ARM64 交叉编译工具链
sudo apt update
sudo apt install gcc-aarch64-linux-gnu
# 安装 QEMU 用户模式模拟器
sudo apt install qemu-user
四、目录结构
.
├── doc
│ └── Git Commit Message 规范.md
├── src
│ ├── backend
│ │ ├── mir
│ │ ├── regalloc
│ │ ├── asm2string.rs
│ │ ├── mirgen.rs
│ │ └── mod.rs
│ ├── frontend
│ │ ├── ir
│ │ ├── lalrpop
│ │ ├── ir2string.rs
│ │ ├── irgen.rs
│ │ ├── mod.rs
│ │ ├── symboltable.rs
│ │ └── typecheck.rs
│ ├── passes
│ ├── utils
│ │ ├── linked_list.rs
│ │ ├── mod.rs
│ │ └── storage.rs
│ └── main.rs
├── test
│ ├── output
│ │ ├── test
│ │ ├── test.ll
│ │ └── test.s
│ └── test_case
│ ├── functional
│ ├── performance
│ └── test.sy
├── Cargo.lock
├── Cargo.toml
├── README.md
└── build.rs
五、编译与运行
5.1 编译编译器
使用以下命令编译生成可执行文件:
cargo build --release
编译生成的可执行文件 compiler 位于 nudt-compiler-rust/target/release/ 中。
--release表示以发布模式编译,开启优化,生成的可执行文件运行速度快,但调试信息较少,适合最终测试。- 若需调试,可去掉
--release使用默认的 debug 模式,编译速度更快,包含完整调试信息。
5.2 运行编译器
- 基本用法
compiler [选项] source_file
- 参数列表
| 参数 | 类型 | 描述 | 示例 |
|---|---|---|---|
-ast <file> |
可选 | 将抽象语法树(AST)输出到指定文件 | -ast ast.txt |
-ir <file> |
可选 | 将中间表示(IR)输出到指定文件 | -ir ir.txt |
-asm <file> |
可选 | 将汇编代码输出到指定文件(优先级高于 -S 和 -o) |
-asm output.s |
-S |
标志 | 生成汇编代码,输出到 stdout 或通过 -o 指定的文件 |
-S |
-o <file> |
可选 | 指定汇编代码的输出文件(仅当同时使用 -S 时有效) |
-o output.s |
-O1 |
标志 | 启用一级优化 | -O1 |
-h |
标志 | 显示帮助信息 | -h |
- 示例
-
生成中间文件(用于调试)
compiler -ast test.ast -ir test.ll -asm test.s test.sy -
生成优化后的中间文件
compiler -O1 -ast test.ast -ir test.ll -asm test.s test.sy -
仅生成汇编并输出到文件(比赛功能用例的编译命令)
compiler -S -o test.s test.sy -
启用优化(比赛性能用例的编译命令)
compiler -O1 -S -o test.s test.sy
说明:-ast、-ir、-asm 参数主要用于开发调试,比赛环境中仅使用上述 3、4 所示的命令格式。