#!/bin/bash # DO NOT MODIFY! # If you need customized behavior, please create your own script. function run_tests() { local TESTCASE_DIR=$1 local OUTPUT_DIR=$2 local OUTPUT_STD_DIR=$3 local score=0 local total=0 mkdir -p "$OUTPUT_DIR" # 对每个 .cminus 文件生成 ast 文件 for testcase in "$TESTCASE_DIR"/*.cminus; do filename="$(basename "$testcase")" # 检查文件名是否以 FAIL 开头,跳过该文件 if [[ "$filename" == FAIL* ]]; then echo "[info] Skipping $filename (starts with FAIL)" continue fi echo "[info] Analyzing $filename" # 生成学生的 AST 文件 "$BUILD_DIR"/cminusfc "$testcase" > "$OUTPUT_DIR/${filename%.cminus}.ast" # 比较当前文件的输出与标准输出 if [[ ${2:-no} != "no" ]]; then echo "[info] Comparing $filename..." # 如果是详细模式 if [[ ${2:-no} == "verbose" ]]; then diff "$OUTPUT_DIR/${filename%.cminus}.ast" "$OUTPUT_STD_DIR/${filename%.cminus}.ast" else diff -q "$OUTPUT_DIR/${filename%.cminus}.ast" "$OUTPUT_STD_DIR/${filename%.cminus}.ast" fi # 检查 diff 的返回值 if [ $? -eq 0 ]; then echo "[info] $filename is correct!" let score=score+1 # 正确时得分+1 else echo "[info] $filename differs from the expected output." fi fi let total=total+1 # 总文件数+1 rm -f "$CUR_DIR/${filename%.cminus}" done # 输出当前测试集的得分 echo "[info] Score for $TESTCASE_DIR: $score/$total" return $score } # 检查命令行参数是否足够 if [[ $# -lt 1 ]]; then echo "usage: ./eval_phase2.sh []" echo " can be one of 'easy', 'normal', 'hard', 'testcases_general', or '-all'." echo " can be one of 'no', 'yes', and 'verbose'. the default value is 'no'" exit 1 fi CUR_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" BUILD_DIR="$CUR_DIR/../../build" # 检查是否使用了 -all 选项 if [[ $1 == "-all" ]]; then TOTAL_SCORE=0 TOTAL_FILES=0 # 定义四个测试集 TESTCASES=("easy" "normal" "hard" "testcases_general") for TESTCASE in "${TESTCASES[@]}"; do if [[ $TESTCASE == "testcases_general" ]]; then TESTCASE_DIR="$CUR_DIR/../$TESTCASE" else TESTCASE_DIR="$CUR_DIR/input/$TESTCASE" fi OUTPUT_DIR="$CUR_DIR/output_student_ast/$TESTCASE" OUTPUT_STD_DIR="$CUR_DIR/output_standard_ast/$TESTCASE" # 计算有效文件数,跳过以 FAIL 开头的文件 VALID_FILES=$(find "$TESTCASE_DIR" -maxdepth 1 -name '*.cminus' ! -name 'FAIL*' | wc -l) echo "[info] Found $VALID_FILES valid files in $TESTCASE_DIR" # 运行测试集并跳过以 FAIL 开头的文件 run_tests "$TESTCASE_DIR" "$OUTPUT_DIR" "$OUTPUT_STD_DIR" $2 CURRENT_SCORE=$? let TOTAL_SCORE+=CURRENT_SCORE TOTAL_FILES=$(($TOTAL_FILES + $VALID_FILES)) done # 输出总分 echo "[info] Total score for all testcases: $TOTAL_SCORE/$TOTAL_FILES" else # 单个测试集处理 TESTCASE="$1" if [[ $TESTCASE == "easy" || $TESTCASE == "normal" || $TESTCASE == "hard" ]]; then TESTCASE_DIR="$CUR_DIR/input/$TESTCASE" elif [[ $TESTCASE == "testcases_general" ]]; then TESTCASE_DIR="$CUR_DIR/../$TESTCASE" fi OUTPUT_DIR="$CUR_DIR/output_student_ast/$TESTCASE" OUTPUT_STD_DIR="$CUR_DIR/output_standard_ast/$TESTCASE" # 运行单个测试集 run_tests "$TESTCASE_DIR" "$OUTPUT_DIR" "$OUTPUT_STD_DIR" $2 fi