You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nudt-compiler-cpp/test4.sh

219 lines
5.3 KiB

#!/bin/bash
set -e
set -o pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
TEST_ROOT="./test/testdata2022/functional"
OUTPUT_DIR="./lab4_results"
COMPILER="./build/bin/compiler"
VERIFY_SCRIPT="./scripts/verify_asm.sh"
MAX_CASES=0
STOP_ON_FIRST_FAILURE=false
START_FROM=1
KEEP_OLD=false
show_help() {
cat << 'EOF'
用法: ./test4.sh [选项]
说明:
批量执行 Lab4(基本标量优化)测试。
默认会递归扫描测试目录下所有 .sy 文件,
使用 -O 优化选项编译并运行,验证输出正确性。
选项:
-h, --help 显示此帮助信息
-n, --max-cases N 最多运行 N 个测试用例 (0=不限制)
-s, --stop-on-failure 遇到第一个失败即停止
--start-from N 从第 N 个测试开始
-k, --keep 保留旧输出目录,不删除
-t, --test-root DIR 指定测试目录
-o, --output-dir DIR 指定输出目录
示例:
./test4.sh # 运行所有测试
./test4.sh -n 10 # 只运行前 10 个测试
./test4.sh -s # 遇到失败即停止
./test4.sh --start-from 5 # 从第 5 个测试开始
./test4.sh -t ./test_merged/hidden_functional # 测试隐藏用例
EOF
}
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-n|--max-cases)
MAX_CASES="$2"
shift 2
;;
-s|--stop-on-failure)
STOP_ON_FIRST_FAILURE=true
shift
;;
--start-from)
START_FROM="$2"
shift 2
;;
-k|--keep)
KEEP_OLD=true
shift
;;
-t|--test-root)
TEST_ROOT="$2"
shift 2
;;
-o|--output-dir)
OUTPUT_DIR="$2"
shift 2
;;
*)
echo -e "${RED}未知参数: $1${NC}"
show_help
exit 1
;;
esac
done
}
parse_args "$@"
if [[ ! -x "$COMPILER" ]]; then
echo -e "${RED}错误: 编译器不存在或不可执行: $COMPILER${NC}"
echo "请先编译项目: cd build && cmake .. && make -j4"
exit 1
fi
if [[ ! -d "$TEST_ROOT" ]]; then
echo -e "${RED}错误: 测试目录不存在: $TEST_ROOT${NC}"
exit 1
fi
if [[ "$KEEP_OLD" != "true" ]]; then
rm -rf "$OUTPUT_DIR"
fi
mkdir -p "$OUTPUT_DIR"
ERROR_LOG="$OUTPUT_DIR/error_log.txt"
echo "" > "$ERROR_LOG"
collect_sy_files() {
find "$TEST_ROOT" -name "*.sy" -type f | sort
}
run_single_test() {
local sy_file="$1"
local case_num="$2"
local basename=$(basename "$sy_file" .sy)
local case_dir="$OUTPUT_DIR/$basename"
mkdir -p "$case_dir"
local expected_out="${sy_file%.sy}.out"
echo -e "${BLUE}[$case_num] $basename${NC}"
local ir_file="$case_dir/$basename.ir"
local asm_file="$case_dir/$basename.s"
local actual_out="$case_dir/output.txt"
if ! $COMPILER -O --emit-ir "$sy_file" > "$ir_file" 2>"$case_dir/ir_error.txt"; then
echo -e " ${RED}IR生成失败${NC}"
echo "[$case_num] $basename - IR生成失败" >> "$ERROR_LOG"
echo " 编译器错误输出:" >> "$ERROR_LOG"
cat "$case_dir/ir_error.txt" >> "$ERROR_LOG"
echo "" >> "$ERROR_LOG"
return 1
fi
if ! $COMPILER -O --emit-asm "$sy_file" > "$asm_file" 2>"$case_dir/asm_error.txt"; then
echo -e " ${RED}汇编生成失败${NC}"
echo "[$case_num] $basename - 汇编生成失败" >> "$ERROR_LOG"
echo " 编译器错误输出:" >> "$ERROR_LOG"
cat "$case_dir/asm_error.txt" >> "$ERROR_LOG"
echo "" >> "$ERROR_LOG"
return 1
fi
if ! $VERIFY_SCRIPT "$sy_file" "$case_dir" --run > "$case_dir/verify_output.txt" 2>&1; then
echo -e " ${RED}运行失败${NC}"
echo "[$case_num] $basename - 运行失败" >> "$ERROR_LOG"
echo " 验证脚本输出:" >> "$ERROR_LOG"
cat "$case_dir/verify_output.txt" >> "$ERROR_LOG"
echo "" >> "$ERROR_LOG"
return 1
fi
echo -e " ${GREEN}通过${NC}"
return 0
}
main() {
local sy_files=($(collect_sy_files))
local total=${#sy_files[@]}
if [[ $total -eq 0 ]]; then
echo -e "${YELLOW}警告: 未找到任何测试文件${NC}"
exit 0
fi
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}Lab4 基本标量优化测试${NC}"
echo -e "${BLUE}========================================${NC}"
echo "测试目录: $TEST_ROOT"
echo "输出目录: $OUTPUT_DIR"
echo "测试用例总数: $total"
echo ""
local passed=0
local failed=0
local case_num=0
for sy_file in "${sy_files[@]}"; do
((case_num++))
if [[ $case_num -lt $START_FROM ]]; then
continue
fi
if [[ $MAX_CASES -gt 0 && $case_num -gt $MAX_CASES ]]; then
break
fi
if run_single_test "$sy_file" "$case_num"; then
((passed++))
else
((failed++))
if [[ "$STOP_ON_FIRST_FAILURE" == "true" ]]; then
echo -e "${RED}遇到失败,停止测试${NC}"
break
fi
fi
done
echo ""
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}测试结果${NC}"
echo -e "${BLUE}========================================${NC}"
echo -e "通过: ${GREEN}$passed${NC}"
echo -e "失败: ${RED}$failed${NC}"
if [[ $failed -gt 0 ]]; then
echo ""
echo -e "${YELLOW}错误日志已保存到: $ERROR_LOG${NC}"
exit 1
fi
exit 0
}
main