本项目是对 Rust 编译器训练营 6 个阶段性实验(lab1–lab6)的整合与改造:
| 实验阶段 | 功能 | 对应模块 |
|---|---|---|
| lab1 | 词法分析 | src/lexer.rs |
| lab2 | 语法分析与代码格式化 | src/format.rs |
| lab3 | 语义检查 | src/check.rs |
| lab5 | LLVM IR 生成 | src/gen_llvm_ir.rs |
| lab6 | RISC-V 汇编生成 | src/riscv_codegen/ |
在原有实验代码的基础上,进行了模块整合、CLI 统一入口、线性扫描寄存器分配算法修复、控制流 lowering 修正以及测试体系重构,最终形成一套可完整运行的 SysY → RISC-V 编译器。
| 子命令 | 说明 |
|---|---|
tokenize |
词法分析,将 SysY 源码转为 Token 流 |
fmt |
代码格式化,输出格式化后的 SysY 代码 |
check |
语义检查,执行类型检查和作用域分析 |
gen-ir |
生成 LLVM IR,将 SysY 编译为 LLVM 中间表示 |
gen-asm |
生成 RISC-V 汇编,包含线性扫描寄存器分配优化 |
兼容模式:支持直接传入输入文件和输出文件(等同于
gen-asm),例如cargo run -- input.sy output.s。
- Rust 工具链(建议最新 stable 版本)
- LLVM 14 及相关开发库
sudo apt-get install llvm-14-dev libpolly-14-dev sudo apt-get update sudo apt-get install zlib1g-dev
- Java(用于 RARS 模拟器运行端到端代码生成验证)
cargo build --release编译完成后,可执行文件位于 target/release/compiler。
# 词法分析
cargo run -- tokenize tests/lexer/simple.in
# 代码格式化
cargo run -- fmt tests/formatter/input1.txt
# 语义检查
cargo run -- check tests/semantic/normaltest01.sy
# 生成 LLVM IR
cargo run -- gen-ir tests/llvm_ir/example01.sy -o out.ll
# 生成 RISC-V 汇编(子命令方式)
cargo run -- gen-asm tests/codegen/register_alloc.sy -o out.s
# 兼容模式:直接传参(等同于 gen-asm)
cargo run -- tests/codegen/register_alloc.sy out.s# 运行全部测试(单元测试 + 端到端集成测试)
cargo test
# 单独运行端到端代码生成验证(栈帧、load/store、控制流、运行结果)
cargo test --test end_to_end_codegen -- --nocapture├── src/
│ ├── lexer.rs # 词法分析
│ ├── format.rs # 代码格式化 / 语法分析
│ ├── check.rs # 语义检查
│ ├── gen_llvm_ir.rs # LLVM IR 生成
│ ├── riscv_codegen/ # RISC-V 汇编生成
│ │ ├── mod.rs
│ │ ├── register_alloc.rs # 线性扫描寄存器分配
│ │ └── asm_builder.rs
│ ├── main.rs # CLI 入口与命令分发
│ └── utils.rs # 工具函数
├── tests/
│ ├── lexer/ # 词法分析测试用例
│ ├── formatter/ # 格式化测试用例
│ ├── semantic/ # 语义检查测试用例
│ ├── llvm_ir/ # LLVM IR 生成测试用例
│ ├── codegen/ # RISC-V 汇编测试用例与 RARS
│ └── end_to_end_codegen.rs # 端到端代码生成验证
├── docs/
│ └── register_allocation_guide.md # 线性扫描寄存器分配算法实现指南
├── Cargo.toml
└── README.md
基于 pest Parser Generator,通过 pests/lexer.pest 定义 SysY 词法规则。支持标识符、关键字、运算符、十进制/八进制/十六进制整数常量,以及非法字符的错误识别与定位。
基于 pest 的 PEG 语法(pests/parser.pest、pests/check.pest),实现 SysY 语法的解析与结构化格式化输出,包括表达式缩进、控制流排版和数组维度对齐。
实现完整的静态语义分析,涵盖:
- 变量与函数声明的重复定义检测
- 表达式与赋值的类型兼容性检查
- 作用域管理与可见性规则
- 函数调用参数数量与类型匹配
- 数组访问验证
- 共 11 类语义错误诊断(Error type 1–11 + Error type A)
基于 inkwell(Rust 对 LLVM 的绑定),将 SysY AST 编译为 LLVM 14 中间表示。支持函数定义、局部/全局变量、控制流(if/while)、数组操作以及算术/逻辑/比较运算。
采用两次遍历架构:
- 第一次遍历:基于 LLVM IR 收集变量的活跃区间(Live Interval),执行线性扫描寄存器分配,为变量分配 RISC-V 寄存器或栈位置。
- 第二次遍历:根据寄存器/栈分配结果,逐指令生成 RISC-V 汇编代码。
寄存器分配策略:
- 优先使用临时寄存器
t0–t6,其次使用保存寄存器s0–s11 - 保留
a0–a1用于函数返回值 - 全局变量不参与寄存器分配,直接通过
la+lw/sw访问
本项目为学习用途的编译器实验代码。