#!/usr/bin/env bash # Lab1 自动化构建 + 解析测评脚本 # 用法:bash scripts/lab1_build_test.sh [测试目录] # 默认测试目录:test/test_case/functional test/test_case/performance # # 退出码: # 0 全部用例解析通过 # 1 存在解析失败用例 set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" COMPILER="$REPO_ROOT/build/bin/compiler" ANTLR_JAR="$REPO_ROOT/third_party/antlr-4.13.2-complete.jar" # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # ─── Step 1:生成 Lexer/Parser ──────────────────────────────────────────────── echo "==> [1/3] 生成 ANTLR Lexer/Parser ..." mkdir -p "$REPO_ROOT/build/generated/antlr4" java -jar "$ANTLR_JAR" \ -Dlanguage=Cpp \ -visitor -no-listener \ -Xexact-output-dir \ -o "$REPO_ROOT/build/generated/antlr4" \ "$REPO_ROOT/src/antlr4/SysY.g4" echo " Lexer/Parser 生成完毕" # ─── Step 2:CMake 构建(禁用后端)──────────────────────────────────────────── echo "==> [2/3] CMake 构建(UNABLE_BACKEND=ON)..." cmake -S "$REPO_ROOT" -B "$REPO_ROOT/build" \ -DCMAKE_BUILD_TYPE=Release \ -DUNABLE_BACKEND=ON \ -DCMAKE_EXPORT_COMPILE_COMMANDS=OFF \ > /dev/null cmake --build "$REPO_ROOT/build" -j "$(nproc)" 2>&1 | grep -E "error:|warning:|Built target|Linking" || true echo " 构建完毕:$COMPILER" # ─── Step 3:批量解析测试 ───────────────────────────────────────────────────── echo "==> [3/3] 批量解析测试 ..." # 收集测试目录 if [[ $# -ge 1 ]]; then TEST_DIRS=("$@") else TEST_DIRS=( "$REPO_ROOT/test/test_case/functional" "$REPO_ROOT/test/test_case/performance" ) fi PASS=0 FAIL=0 FAIL_LIST=() for TEST_DIR in "${TEST_DIRS[@]}"; do if [[ ! -d "$TEST_DIR" ]]; then echo -e " ${YELLOW}警告:目录不存在,跳过:$TEST_DIR${NC}" continue fi while IFS= read -r -d '' sy_file; do rel="$(realpath --relative-to="$REPO_ROOT" "$sy_file")" if "$COMPILER" --emit-parse-tree "$sy_file" > /dev/null 2>&1; then echo -e " ${GREEN}PASS${NC} $rel" ((PASS++)) || true else echo -e " ${RED}FAIL${NC} $rel" FAIL_LIST+=("$rel") ((FAIL++)) || true fi done < <(find "$TEST_DIR" -name "*.sy" -print0 | sort -z) done # ─── 汇总 ───────────────────────────────────────────────────────────────────── echo "" echo "──────────────────────────────────────────" echo -e " 测试结果:${GREEN}${PASS} PASS${NC} / ${RED}${FAIL} FAIL${NC} / 总计 $((PASS + FAIL))" if [[ ${#FAIL_LIST[@]} -gt 0 ]]; then echo "" echo " 失败用例:" for f in "${FAIL_LIST[@]}"; do echo -e " ${RED}- $f${NC}" done fi echo "──────────────────────────────────────────" [[ $FAIL -eq 0 ]]