#!/usr/bin/env bash set -euo pipefail shopt -s nullglob ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" BUILD_DIR="$ROOT_DIR/build" ANTLR_DIR="$BUILD_DIR/generated/antlr4" JAR_PATH="$ROOT_DIR/third_party/antlr-4.13.2-complete.jar" GRAMMAR_PATH="$ROOT_DIR/src/antlr4/SysY.g4" OUT_ROOT="$ROOT_DIR/test/test_result/lab2_ir_batch" RUN_FUNCTIONAL=true RUN_PERFORMANCE=true DO_BUILD=true functional_total=0 functional_passed=0 functional_failed=0 performance_total=0 performance_passed=0 performance_failed=0 failed_cases=() usage() { cat <<'EOF' Usage: ./solution/run_lab2_batch.sh [options] Options: --no-build Skip ANTLR generation and project rebuild --functional-only Run only test/test_case/functional/*.sy --performance-only Run only test/test_case/performance/*.sy --output-dir Set output directory for generated IR and logs --help Show this help message EOF } print_summary() { local total passed failed total=$((functional_total + performance_total)) passed=$((functional_passed + performance_passed)) failed=$((functional_failed + performance_failed)) echo echo "Summary:" echo " Functional cases: total=$functional_total, passed=$functional_passed, failed=$functional_failed" echo " Performance cases: total=$performance_total, passed=$performance_passed, failed=$performance_failed" echo " Overall: total=$total, passed=$passed, failed=$failed" if (( ${#failed_cases[@]} > 0 )); then echo "Failed cases:" printf ' - %s\n' "${failed_cases[@]}" fi } run_case() { local case_file=$1 local group=$2 local stem out_dir log_file stem="$(basename "${case_file%.sy}")" out_dir="$OUT_ROOT/$group" log_file="$out_dir/$stem.verify.log" mkdir -p "$out_dir" if [[ "$group" == "functional" ]]; then ((functional_total += 1)) else ((performance_total += 1)) fi if ./scripts/verify_ir.sh "$case_file" "$out_dir" --run >"$log_file" 2>&1; then echo "PASS: $case_file" if [[ "$group" == "functional" ]]; then ((functional_passed += 1)) else ((performance_passed += 1)) fi else echo "FAIL: $case_file" cat "$log_file" if [[ "$group" == "functional" ]]; then ((functional_failed += 1)) else ((performance_failed += 1)) fi failed_cases+=("$case_file") fi } while [[ $# -gt 0 ]]; do case "$1" in --no-build) DO_BUILD=false ;; --functional-only) RUN_FUNCTIONAL=true RUN_PERFORMANCE=false ;; --performance-only) RUN_FUNCTIONAL=false RUN_PERFORMANCE=true ;; --output-dir) shift if [[ $# -eq 0 ]]; then echo "Missing value for --output-dir" >&2 usage exit 1 fi if [[ "$1" = /* ]]; then OUT_ROOT="$1" else OUT_ROOT="$ROOT_DIR/$1" fi ;; --help) usage exit 0 ;; *) echo "Unknown option: $1" >&2 usage exit 1 ;; esac shift done if [[ "$RUN_FUNCTIONAL" == false && "$RUN_PERFORMANCE" == false ]]; then echo "No test set selected." >&2 exit 1 fi if [[ "$DO_BUILD" == true ]]; then echo "[1/4] Generating ANTLR sources..." mkdir -p "$ANTLR_DIR" java -jar "$JAR_PATH" \ -Dlanguage=Cpp \ -visitor -no-listener \ -Xexact-output-dir \ -o "$ANTLR_DIR" \ "$GRAMMAR_PATH" echo "[2/4] Configuring CMake..." cmake -S "$ROOT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=OFF echo "[3/4] Building project..." cmake --build "$BUILD_DIR" -j "$(nproc)" fi echo "[4/4] Running IR batch tests..." if [[ "$RUN_FUNCTIONAL" == true ]]; then for case_file in "$ROOT_DIR"/test/test_case/functional/*.sy; do run_case "$case_file" "functional" done fi if [[ "$RUN_PERFORMANCE" == true ]]; then for case_file in "$ROOT_DIR"/test/test_case/performance/*.sy; do run_case "$case_file" "performance" done fi print_summary if (( functional_failed + performance_failed > 0 )); then echo "Batch test finished with failures." exit 1 fi echo "Batch test passed."