docs(doc): 清理冗余文件

This commit is contained in:
Lane0218
2026-03-12 10:52:55 +08:00
parent 69a6951f84
commit f3d0102376
3 changed files with 0 additions and 620 deletions

View File

@@ -1,143 +0,0 @@
# SysY Compiler
用于实现SysY编译器的代码框架。
## Getting Started
建议使用Ubuntu 22.04系统原生版本与WSL版本均可。
[Ubuntu下载与安装说明](https://ubuntu.com/download/desktop)
[WSL Ubuntu安装说明](https://learn.microsoft.com/en-us/windows/wsl/install)
SysY编译器前端基于[ANTLR](https://www.antlr.org/index.html)工具实现本仓库已经包含ANTLR 4.9.3版本的可执行程序与C++运行时库但编译ANTLR运行时库存在一些依赖需要提前安装。
```bash
sudo apt update
sudo apt install -y uuid-dev libutfcpp-dev pkg-config make git cmake openjdk-11-jre
```
依赖安装完成后可以开始构建SysY编译器构建过程包含了ANTLR运行时库的构建
```bash
git clone https://gitee.com/xsu1989/sysy.git
cd sysy
cmake -S . -B build
cmake --build build
```
构建完成后,可以运行一个小的测试用例。该测试将逗号分隔的整数或字符串列表进行格式化后重新输出,即将相邻参数之间的分隔统一调整为逗号外加一个空格。
```bash
cat /test/funcrparams.sysy
# -> 1,0xa , 011, "hellow"
./build/bin/sysyc test/funcrparams.sy
# -> 1, 0xa, 011, "hellow"
```
## Documentation
[ANTLR手册](doc/The%20Definitive%20ANTLR%204%20Reference.pdf)
[SysY语言规范](doc/sysy-2022-spec.pdf)
[SysY运行时库](doc/sysy-2022-runtime.pdf)
## 实验1用ANTLR实现SysY词法/语法分析器
当前的代码框架已经部署好了编译环境,同学们可专注于程序开发。
在实验1中同学们需要完成的任务包括
- 参照SysY语言规范修改`src/SysY.g4`文件实现SysY词法/语法的完整定义
- 修改任意代码后需要重新执行`cmake --build build`命令重新构建项目ANTLR工具会从`SysY.g4`生成词法/语法分析器,生成的文件位于`./build/src`目录
- (进阶内容)修改`src/ASTPrinter.h``src/ASTPrinter.cpp`实现从AST输出源程序但输出的源程序是经过格式化的
## 实验2生成中间表示
exp2分支为大家准备好了进行实验2的基本代码框架包括
- IR相关数据结构的定义`src/IR.h`
- 创建IR对象的工具类`src/IRBuilder.h`
- IR生成器的示例代码`src/SysYIRGenerator.h`
在实验2中同学们需要完成的任务包括
- 熟悉掌握IR定义与相关数据结构
- 从语法树生成IR
请同学们仔细阅读代码学习IR的定义。
## 实验3从SysY IR 生成ARMv7汇编代码
### 后端相关源码
当前ref2分支为ARMv7后端代码实验,已经包含了后端代码生成的代码框架,包含
- 后端生成代码源文件`src/backend/codegen.cpp`
- 后端生成代码头文件`src/backend/codegen.hpp`
本实验需要基于以上两个源文件添加ARMv7后端生成代码(也可以按照自己的设计重头编写整个后端生成代码),完成这两个源文件中所有空函数的实现.不局限于本实验提供的后端代码框架,自由设计自己的ARMv7后端实现.
### 后端代码的编译与运行
本实验也修改了驱动代码sysyc.cpp, sysyc.cpp可以调用后端生成的最顶层函数接口code_gen().该函数会逐层调用各层级的代码生产函数并最终生成ARMv7汇编代码并打印至屏幕.通过下列命令编译
```bash
cmake -S . -B build
cmake --build build
```
通过下列命令运行编译产生的sysyc
```bash
./sysyc 01_add.sy
```
或者通过下列命令只生成SysY IR代码
```bash
./sysyc 01_add.sy ir
```
### 测试
本实验提供了两个sysy源文件用于测试,分别是位于sysy-backend/test的01_add.sy 11_add2.sy; 当完成sysyc的编译器后端后,可以通过sysy-backend/test下的Makefile文件编译生成测试程序的可执行二进制.
#### 在x86平台编译运行测试代码
##### 下载并配置ARMv7交叉编译器工具链
在[Arm GNU Toolchain](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads)下载安装交叉编译工具链,并设置环境变量PATH来使用交叉编译工具链
```bash
export PATH=${your_arm-gnu-toolchain_path}/bin:$PATH;
```
##### 安装qemu模拟器
```bash
sudo apt update
sudo apt install qemu-system-arm qemu-user
```
##### 编译测试程序
使用如下命令调用完成后端实现的sysyc生成ARMv7汇编代码,并调用ARMv7交叉编译工具链汇编并连接生成可执行文件.
```bash
cd test
../build/bin/sysyc 01_add.sy > 01_add.s
arm-none-linux-gnueabihf-gcc 01_add.s -o 01_add.out -static #注意使用-static选项来静态链接
```
##### 使用qemu-arm模拟运行测试程序
```bash
cd test
qemu-arm ./01_add.out
echo $? #查看测试程序返回值
```
##### 使用makefile编译与运行
```bash
cd test
make all -r #利用sysyc编译两个测试程序
make run -r #使用qemu-arm模拟运行两个测试程序
```
#### 在树莓派上编译运行测试代码
参见'Raspberry.pptx'设置树莓派的编译运行环境,也可以在自己的x86电脑上利用ARMv7交叉编译工具链来编译测试程序, 将编译产生的可执行文件上传到树莓派上运行.
### 交叉编译器生成汇编代码
可以通过如下的命令让交叉编译器生成汇编代码,以参考gcc后端的编译行为.
```bash
cd test
cp 01_add.sy 01_add.c # 修改代码后缀名
arm-none-linux-gnueabihf-gcc 01_add.c -O0 -S -o 01_add.S #O0编译优化
```
请自己构造一些简单的c程序,阅读交叉编译器编译产生的汇编代码来理解ARMv7汇编代码与编译器后端行为.
### 参考文档
参见doc/backend/下的ARMv7相关文档

View File

@@ -1,271 +0,0 @@
# SysY 编译器目录结构设计
## 1. 编译流程图
```text
[ 前端 Frontend ]
C 源代码
Lexer / ParserANTLR
语法树构建 + 语义分析Sema
语法树(附加语义信息)
[ 中端 Middle-end ]
语法树
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
│ │ └── SyntaxTreePrinter.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/
│ ├── 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/`:语法解析与语法树输出
- `src/frontend/AntlrDriver.cpp`
- 读取源代码并调用解析流程,得到语法树。
- 由于语法正确性由测试保证,该模块只需提供“可用的解析入口”,不需要实现复杂的语法错误报告体系。
- `src/frontend/SyntaxTreePrinter.cpp`
- 语法树调试打印:用于验证语法规则与前端解析行为是否符合预期。
#### 3.2.4 `src/sem/`语义分析Sema
- `src/sem/Sema.cpp`
- 语义分析主流程:符号解析、类型检查、控制流规则检查、必要的隐式转换插入/记录等。
- 在语法树基础上完成语义检查,并为后续 IR 生成提供约束。
- `src/sem/SymbolTable.cpp`
- 符号表与作用域管理:支持嵌套作用域、变量/函数/参数/常量的注册与查找。
- `src/sem/ConstEval.cpp`
- 常量求值:用于数组维度、全局初始化、`const` 表达式等需要编译期计算的场景。
#### 3.2.5 `src/irgen/`:语法树 → IR平台无关LLVM 风格)
- `src/irgen/IRGenDriver.cpp`
- 驱动语法树遍历,调度各子模块完成翻译。
- `src/irgen/IRGenFunc.cpp`
- 函数翻译:函数定义、参数列表与返回值翻译;创建对应 IR 函数对象。
- `src/irgen/IRGenStmt.cpp`
- 语句翻译if/while/return 等控制流构造,生成基本块与分支。
- `src/irgen/IRGenExp.cpp`
- 表达式翻译算术运算、比较、逻辑运算、函数调用等ir指令生成。
- `src/irgen/IRGenDecl.cpp`
- 声明翻译:处理全局变量、局部变量、数组初始化与空间分配等。
#### 3.2.6 `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.7 `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.8 `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/`,并汇总通过/失败信息。