#!/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"