Skip to content

Repository files navigation

SysY 编译器使用说明

📖 概述

SysY 编译器是一个支持 SysY 语言的编译器,能够将 SysY 源代码编译为 ARM 汇编代码。编译器支持多种输出格式和调试选项。

⚠️解决antlr编译报错问题

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.sy

🚀 基本用法

compiler [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

功能说明

test_arm.sh 是一个用于测试 ARM 汇编代码的工具脚本。它能够将编译器生成的 ARM 汇编代码进行处理、编译并在模拟环境中执行,验证汇编代码的正确性。脚本主要功能包括:

  1. 分析汇编文件结构,检查 main 函数、ret 指令等关键组件
  2. 修复汇编代码中可能存在的问题(如处理重复的 ret 指令)
  3. 将 main 函数重命名为 asm_main 以避免冲突
  4. 创建适当的 C 语言主程序调用汇编函数
  5. 使用 ARM 交叉编译工具链编译和链接
  6. 使用 QEMU 模拟器运行生成的 ARM 可执行文件

环境配置要求

要使用 test_arm.sh 脚本,需要安装以下软件包:

# 安装 ARM64 交叉编译工具链
sudo apt update
sudo apt install gcc-aarch64-linux-gnu

# 安装 QEMU 用户模式模拟器
sudo apt install qemu-user

使用方法

  1. 首先确保编译器已经生成了名为 test_output.s 的 ARM 汇编文件
  2. 然后运行测试脚本:
# 基本使用
./test_arm.sh

# 保留临时文件以便调试
./test_arm.sh --keep-temp

# 显示详细信息,包括汇编代码内容
./test_arm.sh --verbose

脚本运行流程

  1. 环境检查:验证所需的工具是否已安装
  2. 分析汇编文件:检查汇编文件结构并统计关键组件
  3. 创建临时汇编文件:处理和修复汇编代码
  4. 创建 C 主程序:生成用于测试的 C 程序
  5. 编译 ARM 汇编:将汇编代码编译为对象文件
  6. 编译 C 主程序:编译 C 主程序为对象文件
  7. 链接程序:链接汇编和 C 对象文件
  8. 执行程序:使用 QEMU 执行生成的 ARM 可执行文件

故障排除

如果遇到 "Segmentation fault" 错误,可能是由于汇编代码中的函数结构问题。可以通过以下方法排查:

  1. 使用 --verbose 选项查看详细信息
  2. 检查 ret 指令使用是否正确
  3. 确认函数序言和尾声结构完整
  4. 查看是否有重复的返回指令

单个文件测试:

  1. 生成无优化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

  2. 生成优化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

  3. 执行汇编文件 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

About

面向编译比赛场景的 SysY 编译器,覆盖词法、语法、语义分析到目标代码生成全流程

Resources

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages