You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
李仁哲 e104a3d546
fix(frontend): 移除前端对全局变量的支持
12 hours ago
doc fix(frontend): 移除前端对全局变量的支持 12 hours ago
src fix(frontend): 移除前端对全局变量的支持 12 hours ago
test fix(frontend): 移除前端对全局变量的支持 12 hours ago
Cargo.lock refactor(src): 重构目录结构 4 days ago
Cargo.toml refactor(src): 重构目录结构 4 days ago
README.md docs(Lab2.md): 上传Lab2文档 3 days ago
build.rs refactor(src): 重构目录结构 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 提供成熟的项目管理工具 Cargo无需手写 Makefile可一站式解决依赖、编译和运行问题。
  • Rust 编译器检查严格,若实现逻辑正确且通过编译,通常可避免运行时的内存错误,调试时配合 VSCode 的 CodeLLDB 插件即可。
  • Rust 并非面向对象语言,不存在类的概念,结构体之间的关系可能不如 C++ 直观,但枚举类型为语法树操作提供了便利。
  • Rust 提供 lalrpop 等语法解析工具,便于实现语法分析器和灵活的 AST 操作。
  • Rust 生态系统丰富,许多库可直接使用,相关资源可访问 Rust 官方学习页面

三、实验环境配置

3.1 系统建议

建议使用 Ubuntu 22.04WSLUbuntu 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
  • 示例
  1. 生成中间文件(用于调试)

    compiler -ast test.ast -ir test.ll -asm test.s test.sy
    
  2. 生成优化后的中间文件

    compiler -O1 -ast test.ast -ir test.ll -asm test.s test.sy
    
  3. 仅生成汇编并输出到文件(比赛功能用例的编译命令)

    compiler -S -o test.s test.sy
    
  4. 启用优化(比赛性能用例的编译命令)

    compiler -O1 -S -o test.s test.sy
    

说明-ast-ir-asm 参数主要用于开发调试,比赛环境中仅使用上述 3、4 所示的命令格式。