毕恩凯 2 weeks ago
parent 63953bd4ae
commit 86ce9bcf50

5
.gitignore vendored

@ -68,3 +68,8 @@ Thumbs.db
# Project outputs
# =========================
test/test_result/
# Added by cargo
/target

@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.20)
project(compiler LANGUAGES C CXX)
find_package(Java REQUIRED COMPONENTS Runtime)
# C++
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@ -39,6 +41,11 @@ endif()
option(COMPILER_PARSE_ONLY "Build only the frontend parser pipeline" OFF)
set(ANTLR4_JAR "${PROJECT_SOURCE_DIR}/third_party/antlr-4.13.2-complete.jar")
if(NOT EXISTS "${ANTLR4_JAR}")
message(FATAL_ERROR "ANTLR jar not found: ${ANTLR4_JAR}")
endif()
# 使 third_party ANTLR4 C++ runtime
# third_party runtime third_party/antlr4-runtime-4.13.2/runtime/src
set(ANTLR4_RUNTIME_SRC_DIR "${PROJECT_SOURCE_DIR}/third_party/antlr4-runtime-4.13.2/runtime/src")

7
Cargo.lock generated

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "nudt-compiler-cpp"
version = "0.1.0"

@ -0,0 +1,6 @@
[package]
name = "nudt-compiler-cpp"
version = "0.1.0"
edition = "2024"
[dependencies]

@ -225,3 +225,4 @@ lOrExp
constExp
: addExp
;

@ -3,15 +3,44 @@ add_library(frontend STATIC
SyntaxTreePrinter.cpp
)
set(ANTLR4_GRAMMAR "${PROJECT_SOURCE_DIR}/src/antlr4/SysY.g4")
set(ANTLR4_GENERATED_FILES
"${ANTLR4_GENERATED_DIR}/SysYLexer.cpp"
"${ANTLR4_GENERATED_DIR}/SysYLexer.h"
"${ANTLR4_GENERATED_DIR}/SysYLexer.interp"
"${ANTLR4_GENERATED_DIR}/SysYLexer.tokens"
"${ANTLR4_GENERATED_DIR}/SysYParser.cpp"
"${ANTLR4_GENERATED_DIR}/SysYParser.h"
"${ANTLR4_GENERATED_DIR}/SysY.interp"
"${ANTLR4_GENERATED_DIR}/SysY.tokens"
"${ANTLR4_GENERATED_DIR}/SysYBaseVisitor.h"
"${ANTLR4_GENERATED_DIR}/SysYVisitor.h"
)
add_custom_command(
OUTPUT ${ANTLR4_GENERATED_FILES}
COMMAND ${CMAKE_COMMAND} -E make_directory "${ANTLR4_GENERATED_DIR}"
COMMAND ${Java_JAVA_EXECUTABLE} -jar "${ANTLR4_JAR}"
-Dlanguage=Cpp
-visitor
-no-listener
-Xexact-output-dir
-o "${ANTLR4_GENERATED_DIR}"
"${ANTLR4_GRAMMAR}"
DEPENDS "${ANTLR4_GRAMMAR}" "${ANTLR4_JAR}"
COMMENT "Generating ANTLR4 parser sources from SysY.g4"
VERBATIM
)
add_custom_target(antlr4_generated DEPENDS ${ANTLR4_GENERATED_FILES})
add_dependencies(frontend antlr4_generated)
target_sources(frontend PRIVATE
"${ANTLR4_GENERATED_DIR}/SysYLexer.cpp"
"${ANTLR4_GENERATED_DIR}/SysYParser.cpp"
)
target_link_libraries(frontend PUBLIC
build_options
${ANTLR4_RUNTIME_TARGET}
)
# Lexer/Parser
file(GLOB_RECURSE ANTLR4_GENERATED_SOURCES CONFIGURE_DEPENDS
"${ANTLR4_GENERATED_DIR}/*.cpp"
)
if(ANTLR4_GENERATED_SOURCES)
target_sources(frontend PRIVATE ${ANTLR4_GENERATED_SOURCES})
endif()

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

@ -0,0 +1,78 @@
#!/bin/bash
# ================================================
# SysY 编译器 Lab1 批量解析测试脚本
# 文件名scripts/test_parse.sh
# 适用环境Arch Linuxbash 原生支持,无需额外安装)
# 功能:
# - 遍历 test/test_case 下所有 .sy 文件functional + performance
# - 执行 --emit-parse-tree 检查是否能成功解析
# - 输出简洁的 PASS/FAIL 结果 + 统计
# - 错误文件会自动打印最后 10 行报错信息(方便调试)
# - 所有结果保存到 test/test_result/parse_test.log
# ================================================
set -u # 遇到未定义变量直接报错
# ================== 配置 ==================
COMPILER="./build/bin/compiler"
TEST_DIR="test/test_case"
LOG_FILE="test/test_result/parse_test.log"
MAX_ERROR_LINES=10
# 检查编译器是否存在
if [[ ! -x "$COMPILER" ]]; then
echo "❌ 错误:找不到编译器 $COMPILER"
echo " 请先执行 Lab1 构建命令:"
echo " cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=ON"
echo " cmake --build build -j \"\$(nproc)\""
exit 1
fi
# 创建日志目录(如果不存在)
mkdir -p "$(dirname "$LOG_FILE")"
> "$LOG_FILE" # 清空日志
echo "开始 Lab1 批量语法树测试..." | tee -a "$LOG_FILE"
echo "测试目录:$TEST_DIR" | tee -a "$LOG_FILE"
echo "编译器:$COMPILER" | tee -a "$LOG_FILE"
echo "========================================" | tee -a "$LOG_FILE"
pass=0
fail=0
total=0
# 遍历所有 .sy 文件(支持子目录)
while IFS= read -r -d '' sy_file; do
((total++))
echo -n "[$total] 测试: $sy_file ... " | tee -a "$LOG_FILE"
# 执行解析(把输出丢到 /dev/null防止刷屏
if "$COMPILER" --emit-parse-tree "$sy_file" > /dev/null 2>&1; then
echo "✅PASS" | tee -a "$LOG_FILE"
((pass++))
else
echo "FAIL" | tee -a "$LOG_FILE"
((fail++))
# 打印错误信息到日志(最后几行)
echo " └── 错误详情(最后 $MAX_ERROR_LINES 行):" >> "$LOG_FILE"
"$COMPILER" --emit-parse-tree "$sy_file" 2>&1 | tail -n "$MAX_ERROR_LINES" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
fi
done < <(find "$TEST_DIR" -name "*.sy" -print0 | sort -z)
# ================== 总结 ==================
echo "========================================" | tee -a "$LOG_FILE"
echo "测试完成!" | tee -a "$LOG_FILE"
echo "总文件数 : $total" | tee -a "$LOG_FILE"
echo "通过 : $pass" | tee -a "$LOG_FILE"
echo "失败 : $fail" | tee -a "$LOG_FILE"
if [[ $fail -eq 0 ]]; then
echo "恭喜Lab1 语法树构建全部通过!可以进入 Lab2 啦~" | tee -a "$LOG_FILE"
else
echo "$fail 个文件解析失败,请检查 SysY.g4 或报错日志" | tee -a "$LOG_FILE"
echo " 日志文件:$LOG_FILE" | tee -a "$LOG_FILE"
fi
echo "========================================" | tee -a "$LOG_FILE"
Loading…
Cancel
Save