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.

11 KiB

Lab1 运行说明

1. 环境要求

建议环境中具备以下工具:

  • java
  • cmake
  • g++ / clang++
  • makeninja

可先检查:

java -version
cmake --version
g++ --version

2. 手动生成 ANTLR 代码

在仓库根目录执行:

mkdir -p build/generated/antlr4
java -jar third_party/antlr-4.13.2-complete.jar \
  -Dlanguage=Cpp \
  -visitor -no-listener \
  -Xexact-output-dir \
  -o build/generated/antlr4 \
  src/antlr4/SysY.g4

3. 手动配置与编译

在仓库根目录执行:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j "$(nproc)"

编译成功后,可执行文件位于:

./build/bin/compiler

4. 单个样例运行

4.1 仅输出语法树

./build/bin/compiler --emit-parse-tree test/test_case/functional/simple_add.sy

4.2 验证最小 IR 仍可工作

./build/bin/compiler --emit-ir test/test_case/functional/simple_add.sy

5. 批量测试

我提供了一个批量测试脚本:

./solution/run_lab1_batch.sh

该脚本默认使用 parse-only 构建模式

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=ON

这样即使 sem / irgen / mir 还没有完成Lab1 的语法树验证也不会被后续实验模块阻塞。

如果希望在批量测试时把每个样例的语法树保存到 test_tree/ 目录,可以加可选项:

./solution/run_lab1_batch.sh --save-tree

该脚本会自动完成:

  1. 重新生成 build/generated/antlr4 下的 ANTLR 文件
  2. 执行 cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=ON
  3. 执行 cmake --build build -j "$(nproc)"
  4. 批量测试 test/test_case/functional/*.sy
  5. 批量测试 test/test_case/performance/*.sy
  6. 批量测试 test/test_case/negative/*.sy,确认非法输入会触发 parse 报错

若使用 --save-tree,还会额外:

  1. 在仓库根目录下创建 test_tree/
  2. 将语法树按测试集目录结构保存,例如:
test_tree/functional/simple_add.tree
test_tree/performance/fft0.tree

脚本结束时会输出:

  • 正例总数 / 通过数 / 失败数
  • 反例总数 / 通过数 / 失败数
  • 总覆盖样例数与整体通过情况
  • 失败样例列表

若某个用例失败,脚本会打印失败用例名并返回非零退出码。

6. 反例测试说明

新增了负例目录:

test/test_case/negative

当前提供了 3 个非法样例:

  • missing_semicolon.sy
  • missing_rparen.sy
  • unexpected_else.sy

这些样例用于验证:

  • 合法输入能够成功输出语法树
  • 非法输入能够触发 parse 报错
  • 报错信息带有位置,便于定位问题

7. 常用附加命令

7.1 查看帮助

./build/bin/compiler --help

7.2 指定单个样例文件

./build/bin/compiler --emit-parse-tree <your_case.sy>

7.3 重新从零开始构建

rm -rf build
mkdir -p build/generated/antlr4
java -jar third_party/antlr-4.13.2-complete.jar \
  -Dlanguage=Cpp \
  -visitor -no-listener \
  -Xexact-output-dir \
  -o build/generated/antlr4 \
  src/antlr4/SysY.g4
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j "$(nproc)"

8. 结果判定

Lab1 主要检查点是:

  • 合法 SysY 程序可以被 SysY.g4 成功解析
  • --emit-parse-tree 能输出语法树
  • test/test_case 下正例可以批量通过语法树模式
  • test/test_case/negative 下反例会稳定触发 parse 报错

本项目当前实现中Lab1 的重点是“语法分析与语法树构建”,不是完整语义分析和完整 IR/汇编支持。

Lab2 运行说明

1. 额外环境要求

在 Lab1 的基础上,若需要运行 IR 并校验输出,还需要:

  • llc
  • clang

可先检查:

llc --version
clang --version

2. 配置与编译

Lab2 需要启用完整编译流程,不能使用 parse-only

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=OFF
cmake --build build -j "$(nproc)"

3. 单个样例运行

3.1 仅生成 IR

./build/bin/compiler --emit-ir test/test_case/functional/simple_add.sy

3.2 生成 IR 并运行校验

./scripts/verify_ir.sh test/test_case/functional/simple_add.sy test/test_result/lab2_ir --run

脚本会自动完成:

  1. 调用 ./build/bin/compiler --emit-ir
  2. 使用 llc.ll 编译为目标文件
  3. 使用 clang 链接 sylib/sylib.c
  4. 运行生成的可执行文件
  5. 将“标准输出 + 退出码”与对应的 .out 文件比较

如果只想生成 IR 而不运行,可去掉 --run

./scripts/verify_ir.sh test/test_case/functional/simple_add.sy test/test_result/lab2_ir

4. 批量测试

Lab2 批量脚本:

./solution/run_lab2_batch.sh

默认行为:

  1. 重新生成 build/generated/antlr4 下的 ANTLR 文件
  2. 执行完整配置与编译
  3. 批量运行 test/test_case/functional/*.sy
  4. 批量运行 test/test_case/performance/*.sy
  5. 默认输出到 test/test_result/lab2_ir_batch/

常用选项:

./solution/run_lab2_batch.sh --no-build
./solution/run_lab2_batch.sh --functional-only
./solution/run_lab2_batch.sh --performance-only
./solution/run_lab2_batch.sh --output-dir test/test_result/my_lab2_ir

5. 结果判定

Lab2 的通过标准通常包括:

  • IR 成功生成
  • 生成的 IR 可以被 llc 接受
  • 可以正确链接 sylib
  • 程序运行输出与 .out 一致
  • 程序退出码与 .out 中最后一行一致

Lab3 运行说明

1. 额外环境要求

在 Lab2 的基础上,若需要生成并运行 AArch64 汇编,还需要:

  • aarch64-linux-gnu-gcc
  • qemu-aarch64

可先检查:

aarch64-linux-gnu-gcc --version
qemu-aarch64 --version

2. 配置与编译

Lab3 同样使用完整构建:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=OFF
cmake --build build -j "$(nproc)"

3. 单个样例运行

3.1 仅生成汇编

./build/bin/compiler --emit-asm test/test_case/functional/simple_add.sy

3.2 生成汇编、链接并运行校验

./scripts/verify_asm.sh test/test_case/functional/simple_add.sy test/test_result/lab3_asm --run

脚本会自动完成:

  1. 调用 ./build/bin/compiler --emit-asm
  2. 使用 aarch64-linux-gnu-gcc 汇编并链接 sylib/sylib.c
  3. 使用 qemu-aarch64 运行生成的 AArch64 可执行文件
  4. 将“标准输出 + 退出码”与对应的 .out 文件比较

如果当前只想验证“能生成并链接汇编”,可去掉 --run

./scripts/verify_asm.sh test/test_case/functional/simple_add.sy test/test_result/lab3_asm

4. 批量测试

Lab3 批量脚本:

./solution/run_lab3_batch.sh

默认行为:

  1. 重新生成 build/generated/antlr4 下的 ANTLR 文件
  2. 执行完整配置与编译
  3. 批量运行 test/test_case/functional/*.sy
  4. 批量运行 test/test_case/performance/*.sy
  5. 默认输出到 test/test_result/lab3_asm_batch/

常用选项:

./solution/run_lab3_batch.sh --no-build
./solution/run_lab3_batch.sh --functional-only
./solution/run_lab3_batch.sh --performance-only
./solution/run_lab3_batch.sh --emit-only
./solution/run_lab3_batch.sh --no-run
./solution/run_lab3_batch.sh --timeout 30
./solution/run_lab3_batch.sh --output-dir test/test_result/my_lab3_asm

其中:

  • --emit-only / --no-run:只生成并链接汇编,不执行 qemu
  • --timeout <sec>:给每个用例增加超时限制,适合性能样例

5. 结果判定

Lab3 的通过标准通常包括:

  • 汇编成功生成
  • 生成的汇编可以被 aarch64-linux-gnu-gcc 汇编与链接
  • 可执行文件可以在 qemu-aarch64 下运行
  • 程序运行输出与 .out 一致
  • 程序退出码与 .out 中最后一行一致

Lab4 运行说明

1. 环境要求

Lab4 会同时覆盖 IR 优化链路和 AArch64 汇编链路。

若需要验证 IR 并运行:

  • llc
  • clang

若需要验证汇编并运行:

  • aarch64-linux-gnu-gcc
  • qemu-aarch64

可先检查:

llc --version
clang --version
aarch64-linux-gnu-gcc --version
qemu-aarch64 --version

2. 配置与编译

Lab4 仍使用完整构建:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=OFF
cmake --build build -j "$(nproc)"

3. 单个样例运行

3.1 观察 -O0/-O1 IR

./build/bin/compiler -O0 --emit-ir test/test_case/functional/simple_add.sy
./build/bin/compiler -O1 --emit-ir test/test_case/functional/simple_add.sy

其中:

  • -O0:输出未启用 Lab4 标量优化的 IR
  • -O1:输出经过 Mem2Reg + ConstProp + ConstFold + CSE + DCE + CFGSimplify 的 IR

3.2 生成 IR 并运行校验

./scripts/verify_ir.sh test/test_case/functional/simple_add.sy test/test_result/lab4_ir_o0 --run
./scripts/verify_ir.sh test/test_case/functional/simple_add.sy test/test_result/lab4_ir_o1 --run -- -O1

如果只想生成 IR 而不运行,可去掉 --run

./scripts/verify_ir.sh test/test_case/functional/simple_add.sy test/test_result/lab4_ir_o0
./scripts/verify_ir.sh test/test_case/functional/simple_add.sy test/test_result/lab4_ir_o1 -- -O1

3.3 生成汇编并运行校验

./scripts/verify_asm.sh test/test_case/functional/simple_add.sy test/test_result/lab4_asm_o0 --run
./scripts/verify_asm.sh test/test_case/functional/simple_add.sy test/test_result/lab4_asm_o1 --run -- -O1

如果只想验证“能生成并链接汇编”,可去掉 --run

./scripts/verify_asm.sh test/test_case/functional/simple_add.sy test/test_result/lab4_asm_o0
./scripts/verify_asm.sh test/test_case/functional/simple_add.sy test/test_result/lab4_asm_o1 -- -O1

4. 批量测试

Lab4 批量脚本:

./solution/run_lab4_batch.sh -O0
./solution/run_lab4_batch.sh -O1

默认行为:

  1. 重新生成 build/generated/antlr4 下的 ANTLR 文件
  2. 执行完整配置与编译
  3. 依次批量运行 verify_ir
  4. 依次批量运行 verify_asm
  5. 覆盖 test/test_case/functional/*.sytest/test_case/performance/*.sy
  6. 默认输出到 test/test_result/lab4_batch_o<level>/

常用选项:

./solution/run_lab4_batch.sh --no-build -O1
./solution/run_lab4_batch.sh --functional-only -O0
./solution/run_lab4_batch.sh --performance-only -O1
./solution/run_lab4_batch.sh --ir-only -O1
./solution/run_lab4_batch.sh --asm-only -O1
./solution/run_lab4_batch.sh --no-run -O1
./solution/run_lab4_batch.sh --timeout 300 -O1
./solution/run_lab4_batch.sh --output-dir test/test_result/my_lab4_batch -O1

其中:

  • -O0/-O1:显式切换 Lab4 优化档位
  • --ir-only:只跑 IR 验证链路
  • --asm-only:只跑汇编验证链路
  • --no-run / --emit-only:只生成 IR 或汇编,不执行产物
  • --timeout <sec>:为每个样例增加超时限制,适合长时间性能样例

5. 结果判定

Lab4 的通过标准通常包括:

  • -O0-O1 两档都能成功生成 IR / asm
  • -O1 下优化前后程序语义一致
  • IR 路径生成物可以被 llcclang 接受
  • asm 路径生成物可以被 aarch64-linux-gnu-gcc 汇编与链接
  • 可执行文件运行输出与 .out 一致
  • 程序退出码与 .out 中最后一行一致