|
|
#!/usr/bin/env bash
|
|
|
set -euo pipefail
|
|
|
|
|
|
# Lab2 一键测试脚本
|
|
|
# 用法:
|
|
|
# 1) 批量测试全部 .sy
|
|
|
# ./test_lab2.sh
|
|
|
# 2) 测试单个样例
|
|
|
# ./test_lab2.sh test/test_case/functional/simple_add.sy
|
|
|
# 3) 指定并行编译线程数
|
|
|
# JOBS=8 ./test_lab2.sh
|
|
|
# 4) 只做构建,不跑测试
|
|
|
# RUN_TESTS=0 ./test_lab2.sh
|
|
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
cd "$ROOT_DIR"
|
|
|
|
|
|
if [[ ! -f "src/antlr4/SysY.g4" || ! -f "scripts/verify_ir.sh" ]]; then
|
|
|
echo "错误:请把本脚本放在实验根目录 ~/compile/compiler 下再执行。"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
ANTLR_JAR="third_party/antlr-4.13.2-complete.jar"
|
|
|
GRAMMAR="src/antlr4/SysY.g4"
|
|
|
GEN_DIR="build/generated/antlr4"
|
|
|
BUILD_DIR="build"
|
|
|
COMPILER_BIN="$BUILD_DIR/bin/compiler"
|
|
|
VERIFY_SCRIPT="./scripts/verify_ir.sh"
|
|
|
RESULT_DIR="test/test_result/function/ir"
|
|
|
JOBS="${JOBS:-$(nproc)}"
|
|
|
RUN_TESTS="${RUN_TESTS:-1}"
|
|
|
SINGLE_CASE="${1:-}"
|
|
|
|
|
|
need_regen=0
|
|
|
for f in SysYLexer.h SysYLexer.cpp SysYParser.h SysYParser.cpp SysYBaseVisitor.h SysYVisitor.h; do
|
|
|
if [[ ! -f "$GEN_DIR/$f" ]]; then
|
|
|
need_regen=1
|
|
|
break
|
|
|
fi
|
|
|
done
|
|
|
if [[ -d "$GEN_DIR" && "$GRAMMAR" -nt "$GEN_DIR" ]]; then
|
|
|
need_regen=1
|
|
|
fi
|
|
|
|
|
|
if [[ ! -f "$ANTLR_JAR" ]]; then
|
|
|
echo "错误:找不到 $ANTLR_JAR"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
echo "[1/4] 检查/生成 ANTLR 文件"
|
|
|
mkdir -p "$GEN_DIR"
|
|
|
if [[ "$need_regen" -eq 1 ]]; then
|
|
|
java -jar "$ANTLR_JAR" \
|
|
|
-Dlanguage=Cpp \
|
|
|
-visitor -no-listener \
|
|
|
-Xexact-output-dir \
|
|
|
-o "$GEN_DIR" \
|
|
|
"$GRAMMAR"
|
|
|
echo "已生成到 $GEN_DIR"
|
|
|
else
|
|
|
echo "ANTLR 生成文件已存在,跳过"
|
|
|
fi
|
|
|
|
|
|
echo "[2/4] CMake 配置"
|
|
|
cmake -S . -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=OFF
|
|
|
|
|
|
echo "[3/4] 编译"
|
|
|
cmake --build "$BUILD_DIR" -j "$JOBS"
|
|
|
|
|
|
if [[ "$RUN_TESTS" != "1" ]]; then
|
|
|
echo "已完成构建,未执行测试(RUN_TESTS=$RUN_TESTS)"
|
|
|
exit 0
|
|
|
fi
|
|
|
|
|
|
if [[ ! -x "$COMPILER_BIN" ]]; then
|
|
|
echo "错误:找不到可执行文件 $COMPILER_BIN"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
if [[ -n "$SINGLE_CASE" ]]; then
|
|
|
if [[ ! -f "$SINGLE_CASE" ]]; then
|
|
|
echo "错误:测试文件不存在:$SINGLE_CASE"
|
|
|
exit 1
|
|
|
fi
|
|
|
echo "[4/4] 单例测试:$SINGLE_CASE"
|
|
|
echo "----- IR 输出预览 -----"
|
|
|
"$COMPILER_BIN" --emit-ir "$SINGLE_CASE"
|
|
|
echo "----- verify_ir.sh -----"
|
|
|
"$VERIFY_SCRIPT" "$SINGLE_CASE" "$RESULT_DIR" --run
|
|
|
echo "单例测试通过:$SINGLE_CASE"
|
|
|
exit 0
|
|
|
fi
|
|
|
|
|
|
echo "[4/4] 先跑 simple_add 冒烟测试"
|
|
|
SMOKE_CASE="test/test_case/functional/simple_add.sy"
|
|
|
if [[ -f "$SMOKE_CASE" ]]; then
|
|
|
"$VERIFY_SCRIPT" "$SMOKE_CASE" "$RESULT_DIR" --run
|
|
|
else
|
|
|
echo "警告:未找到 $SMOKE_CASE,跳过冒烟测试"
|
|
|
fi
|
|
|
|
|
|
echo "开始批量测试全部 .sy"
|
|
|
count=0
|
|
|
pass=0
|
|
|
while IFS= read -r case_file; do
|
|
|
((count+=1))
|
|
|
echo
|
|
|
echo "===== [$count] $case_file ====="
|
|
|
if "$VERIFY_SCRIPT" "$case_file" "$RESULT_DIR" --run; then
|
|
|
((pass+=1))
|
|
|
else
|
|
|
echo
|
|
|
echo "测试失败:$case_file"
|
|
|
echo "已通过 $pass / $count 个用例"
|
|
|
exit 1
|
|
|
fi
|
|
|
done < <(find test/test_case -type f -name '*.sy' | sort)
|
|
|
|
|
|
echo
|
|
|
echo "全部通过:$pass / $count"
|