#!/bin/bash # 测试脚本(支持动态输出目录) # 用法: ./run_tests.sh [--verbose] [--mode <模式>] [<单个测试文件>] # 模式: parse-tree, ir, asm, run (默认 run) COMPILER="./build/bin/compiler" TEST_SCRIPT="./scripts/verify_asm.sh" TEST_DIR="test/test_case" RESULT_FILE="result.txt" VERBOSE=0 MODE="run" # 默认模式为完整测试 # 解析参数 while [[ $# -gt 0 ]]; do case "$1" in --verbose|-v) VERBOSE=1 shift ;; --mode) MODE="$2" shift 2 ;; --emit-parse-tree) MODE="parse-tree" shift ;; --emit-ir) MODE="ir" shift ;; --emit-asm) MODE="asm" shift ;; --run) MODE="run" shift ;; -*) echo "未知选项: $1" exit 1 ;; *) # 非选项参数视为测试文件 SINGLE_FILE="$1" shift ;; esac done # 检查编译器是否存在 if [ ! -f "$COMPILER" ]; then echo "错误: 编译器未找到于 $COMPILER" echo "请先完成项目构建 (cmake 和 make)" exit 1 fi # 如果是 run 模式,检查测试脚本是否存在 if [ "$MODE" = "run" ] && [ ! -f "$TEST_SCRIPT" ]; then echo "错误: 测试脚本未找到于 $TEST_SCRIPT" exit 1 fi # 如果指定了单个文件,检查文件是否存在 if [ -n "$SINGLE_FILE" ] && [ ! -f "$SINGLE_FILE" ]; then echo "错误: 文件 $SINGLE_FILE 不存在" exit 1 fi # 清空(或创建)结果文件 > "$RESULT_FILE" # 计数器 total=0 passed=0 failed=0 echo "开始测试 (模式: $MODE)..." echo "输出将保存到 $RESULT_FILE" echo "------------------------" # 确定测试文件列表 if [ -n "$SINGLE_FILE" ]; then TEST_FILES=("$SINGLE_FILE") else mapfile -t TEST_FILES < <(find "$TEST_DIR" -type f -name "*.sy" | sort) fi # 根据模式执行测试 for file in "${TEST_FILES[@]}"; do ((total++)) if [ $VERBOSE -eq 1 ]; then echo "测试文件: $file" else echo -n "测试 $file ... " fi echo "========== $file ==========" >> "$RESULT_FILE" # 根据模式构建命令 case "$MODE" in parse-tree) cmd="$COMPILER --emit-parse-tree \"$file\"" ;; ir) cmd="$COMPILER --emit-ir \"$file\"" ;; asm) cmd="$COMPILER --emit-asm \"$file\"" ;; run) # 根据输入文件所在子目录确定输出目录 # 提取 test/test_case/ 之后的子目录名(functional 或 performance) rel_path="${file#$TEST_DIR/}" subdir=$(echo "$rel_path" | cut -d'/' -f1) if [[ "$subdir" != "functional" && "$subdir" != "performance" ]]; then echo "警告: 未知子目录 $subdir,使用默认输出目录" >> "$RESULT_FILE" out_dir="test/test_result/asm" else out_dir="test/test_result/$subdir/asm" fi cmd="$TEST_SCRIPT \"$file\" \"$out_dir\" --run" ;; *) echo "未知模式: $MODE" >&2 exit 1 ;; esac if [ $VERBOSE -eq 1 ]; then eval "$cmd" 2>&1 | tee -a "$RESULT_FILE" result=${PIPESTATUS[0]} else eval "$cmd" >> "$RESULT_FILE" 2>&1 result=$? fi echo "" >> "$RESULT_FILE" if [ $result -eq 0 ]; then if [ $VERBOSE -eq 0 ]; then echo "通过" fi ((passed++)) else if [ $VERBOSE -eq 0 ]; then echo "失败" else echo ">>> 测试失败: $file" fi ((failed++)) fi done echo "------------------------" echo "总计: $total" echo "通过: $passed" echo "失败: $failed" echo "详细输出已保存至 $RESULT_FILE" if [ $failed -gt 0 ]; then exit 1 else exit 0 fi