SysY 编译器是一个支持 SysY 语言的编译器,能够将 SysY 源代码编译为 ARM 汇编代码。编译器支持多种输出格式和调试选项。
cd antlr/antlr4-runtime-4.13.2/
cmake -S . -B build -DANTLR_JAR_LOCATION=$(realpath ../antlr-4.13.2-complete.jar) -DWITH_DEMO=True
cmake --build build -j4
cp dist/libantlr4-runtime.a runtime/libantlr4-runtime.a
cd ..
cd ..
rm -rf build/
cmake -S . -B build
cmake --build build -j8
./build/bin/compiler -s ir ./classtest/test/01_add.sycompiler [options] inputfile| 选项 | 长选项 | 参数 | 描述 |
|---|---|---|---|
-h |
--help |
无 | 显示帮助信息并退出 |
-o |
无 | <file> |
指定输出文件(默认:自动生成在 <filename>/ 目录下) |
| 选项 | 参数 | 描述 |
|---|---|---|
-s |
{ast,ir,opt-ir,mir,opt-mir,asm,opt-s} |
在指定阶段后停止编译 |
| 选项 | 长选项 | 参数 | 描述 |
|---|---|---|---|
| 无 | --enable-ir-opt |
无 | 启用 IR 级别优化 |
| 无 | --enable-mir-opt |
无 | 启用 MIR 级别优化 |
| 无 | --enable-s-opt |
无 | 启用汇编代码优化 |
| 无 | --enable-all-opt |
无 | 启用所有级别的优化 |
| 无 | --no-output-dir |
无 | 禁用创建输出目录,所有输出文件直接生成在当前目录 |
注意: 默认情况下,所有优化都是禁用的,需要使用上述选项明确启用优化。
| 选项 | 参数 | 描述 |
|---|---|---|
-d |
无 | 启用调试输出 |
-v |
无 | 启用详细调试输出 |
-l |
<file> |
将调试信息记录到指定文件(未指定时会生成默认的日志文件) |
# 编译为汇编代码(无优化)
compiler main.sy
# 启用所有优化并编译
compiler main.sy --enable-all-opt -o output.s
# 仅启用 IR 优化
compiler main.sy --enable-ir-opt
# 仅启用 MIR 优化
compiler main.sy --enable-mir-opt
# 仅启用汇编代码优化
compiler main.sy --enable-s-opt# 查看抽象语法树
compiler main.sy -s ast
# 查看 IR 中间表示(无优化)
compiler main.sy -s ir -o output.ir # 输出 IR 到指定文件
# 查看优化后的 IR 中间表示
compiler main.sy -s opt-ir --enable-ir-opt
# 查看 MIR 机器中间表示(无优化)
compiler main.sy -s mir
# 查看优化后的 MIR 机器中间表示
compiler main.sy -s opt-mir --enable-mir-opt
# 查看未优化的汇编代码
compiler main.sy -s asm
# 查看优化后的汇编代码
compiler main.sy -s opt-s --enable-s-opt# 启用基本调试信息,自动生成日志文件 main/main.log
compiler main.sy -d
# 启用详细调试信息
compiler main.sy -v
# 调试信息保存到指定文件
compiler main.sy -d -l custom_debug.log
# 生成 MIR 并启用调试
compiler main.sy -s mir -v# 启用 IR 优化并在 opt-ir 阶段停止,将结果输出到指定文件
compiler main.sy -s opt-ir --enable-ir-opt -o optimized.ir
# 启用所有优化并生成优化后的汇编代码
compiler main.sy --enable-all-opt -s opt-s
# 仅执行到 MIR 阶段并启用调试
compiler main.sy -s mir -d当编译 example.sy 文件时,编译器会自动创建以下文件结构:
example/ # 以源文件名创建的目录
├── example.ir # IR 中间表示
├── example.opt.ir # 优化后的 IR(如果启用 IR 优化)
├── example.mir # MIR 中间表示
├── example.opt.mir # 优化后的 MIR(如果启用 MIR 优化)
├── example.s # 汇编代码
├── example.opt.s # 优化后的汇编代码(如果启用汇编优化)
└── example.log # 调试日志(如果启用调试)
如需禁用自动创建输出目录,可加上 --no-output-dir 选项。
#1)bash ./fresh.sh 这一步是重新编译 #2)bash ./IR.sh 这一步是生成IR,没有留报错日志。log/cplog里面是刘学长写的那个debug日志 #3)bash ./comb.sh 这一步是复制库IR到文件头,没有留报错日志 #4)bash ./exec1.sh 这一步是生成s文件,报错日志在log/s_log(空的就是对的) #5)bash ./exec2.sh 这一步是生成exe文件,报错日志在log/e_log(空的就是对的,缺的就是没编s的) #6)bash ./run.sh 这一步是运行exe文件,输出结果在log/r_log #7)bash ./cmp.sh 这一是统计输出结果。命令行有显示,但是会留存用时间戳命名的日志到testLOG文件夹里。每一个执行成功的都会有记录,/xxx/xxx.ir:执行结果相同or不同。testdata里面的.out和r_log里的.rlog比。
#这种是对整个testdata文件夹进行编译 bash ./temp_file/shells/fresh.sh #bash ./temp_file/shells/IR.sh bash ./temp_file/shells/opt-ir.sh bash ./temp_file/shells/comb.sh bash ./temp_file/shells/exec1.sh bash ./temp_file/shells/exec2.sh bash ./temp_file/shells/run.sh bash ./temp_file/shells/cmp.sh
#这种是对单独的sysy文件进行编译 ./compile_ir.sh testdata/h_functional/02_ret_in_block.sy
test_arm.sh 是一个用于测试 ARM 汇编代码的工具脚本。它能够将编译器生成的 ARM 汇编代码进行处理、编译并在模拟环境中执行,验证汇编代码的正确性。脚本主要功能包括:
- 分析汇编文件结构,检查 main 函数、ret 指令等关键组件
- 修复汇编代码中可能存在的问题(如处理重复的 ret 指令)
- 将 main 函数重命名为 asm_main 以避免冲突
- 创建适当的 C 语言主程序调用汇编函数
- 使用 ARM 交叉编译工具链编译和链接
- 使用 QEMU 模拟器运行生成的 ARM 可执行文件
要使用 test_arm.sh 脚本,需要安装以下软件包:
# 安装 ARM64 交叉编译工具链
sudo apt update
sudo apt install gcc-aarch64-linux-gnu
# 安装 QEMU 用户模式模拟器
sudo apt install qemu-user- 首先确保编译器已经生成了名为
test_output.s的 ARM 汇编文件 - 然后运行测试脚本:
# 基本使用
./test_arm.sh
# 保留临时文件以便调试
./test_arm.sh --keep-temp
# 显示详细信息,包括汇编代码内容
./test_arm.sh --verbose- 环境检查:验证所需的工具是否已安装
- 分析汇编文件:检查汇编文件结构并统计关键组件
- 创建临时汇编文件:处理和修复汇编代码
- 创建 C 主程序:生成用于测试的 C 程序
- 编译 ARM 汇编:将汇编代码编译为对象文件
- 编译 C 主程序:编译 C 主程序为对象文件
- 链接程序:链接汇编和 C 对象文件
- 执行程序:使用 QEMU 执行生成的 ARM 可执行文件
如果遇到 "Segmentation fault" 错误,可能是由于汇编代码中的函数结构问题。可以通过以下方法排查:
- 使用
--verbose选项查看详细信息 - 检查 ret 指令使用是否正确
- 确认函数序言和尾声结构完整
- 查看是否有重复的返回指令
单个文件测试:
-
生成无优化ir的汇编文件 bash ./temp_file/shells/to_s.sh -d 文件夹名(无前缀,仅func/h_func/perf) -f 文件名(无前缀后缀,例:00_main) e.g. bash ./temp_file/shells/to_s.sh -d functional -f 00_main
-
生成优化ir的汇编文件 bash ./temp_file/shells/opt_to_s.sh -d 文件夹名(无前缀,仅func/h_func/perf) -f 文件名(无前缀后缀,例:00_main) e.g. bash ./temp_file/shells/opt_to_s.sh -d functional -f 00_main
-
执行汇编文件 bash ./temp_file/shells/to_cmp.sh -d 文件夹名(无前缀,仅func/h_func/perf) -f 文件名(无前缀后缀,例:00_main) e.g. bash ./temp_file/shells/to_cmp.sh -d performance -f h-9-02 <第三步优化了功能,对于单个文件也有cmp.sh的添加错误功能;当错误被修改,cmp_log下的文件夹会自动删除>
使用clang生成汇编码以供参考 clang-14 -x c -target aarch64-linux-gnu -march=armv8-a -fno-addrsig -S testdata/functional/09_func_defn.sy -o ./09_func_defn.s