From 995e159f6f2c9c1ec8d15a4d60b4626da09e403a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=92=E9=92=B0=E6=9D=83?= <2080784847@qq.com> Date: Mon, 23 Mar 2026 09:45:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E6=B5=81=E8=AF=AD=E5=8F=A5=E3=80=81=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E4=BC=98=E5=85=88=E7=BA=A7=E5=8F=8A=E6=B5=8B=E8=AF=95=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/run_all_tests.sh | 48 ++++++++++++++++++++++++++++++ src/antlr4/SysY.g4 | 63 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 scripts/run_all_tests.sh diff --git a/scripts/run_all_tests.sh b/scripts/run_all_tests.sh new file mode 100644 index 0000000..ad67323 --- /dev/null +++ b/scripts/run_all_tests.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# 批量测试所有.sy文件的语法解析 + +test_dir="/home/lingli/nudt-compiler-cpp/test/test_case/functional" +compiler="/home/lingli/nudt-compiler-cpp/build/bin/compiler" + +if [ ! -f "$compiler" ]; then + echo "错误:编译器不存在,请先构建项目" + exit 1 +fi + +success_count=0 +failed_count=0 +failed_tests=() + +echo "开始测试所有.sy文件的语法解析..." +echo "=" + +# 获取所有.sy文件并排序 +for test_file in $(find "$test_dir" -name "*.sy" | sort); do + echo "测试: $(basename "$test_file")" + + # 运行解析测试,将输出重定向到/dev/null + "$compiler" --emit-parse-tree "$test_file" > /dev/null 2>&1 + + if [ $? -eq 0 ]; then + echo " ✓ 成功" + ((success_count++)) + else + echo " ✗ 失败" + ((failed_count++)) + failed_tests+=($(basename "$test_file")) + fi +done + +echo "=" +echo "测试完成!" +echo "总测试数: $((success_count + failed_count))" +echo "成功: $success_count" +echo "失败: $failed_count" + +if [ $failed_count -gt 0 ]; then + echo "失败的测试用例:" + for test in "${failed_tests[@]}"; do + echo " - $test" + done +fi diff --git a/src/antlr4/SysY.g4 b/src/antlr4/SysY.g4 index 5115f15..d36eafa 100644 --- a/src/antlr4/SysY.g4 +++ b/src/antlr4/SysY.g4 @@ -171,23 +171,76 @@ blockItem ; stmt - : returnStmt + : assignStmt + | returnStmt + | blockStmt + | ifStmt + | whileStmt + | breakStmt + | continueStmt + | expStmt + ; + +expStmt + : exp SEMICOLON + ; + +assignStmt + : lValue ASSIGN exp SEMICOLON ; returnStmt : RETURN (exp)? SEMICOLON ; -exp - : LPAREN exp RPAREN # parenExp - | lValue # lValueExp - | number # numberExp +ifStmt + : IF LPAREN exp RPAREN stmt (ELSE stmt)? + ; + +whileStmt + : WHILE LPAREN exp RPAREN stmt ; +breakStmt + : BREAK SEMICOLON + ; + +continueStmt + : CONTINUE SEMICOLON + ; + +// 表达式 lValue : ID (LBRACK exp RBRACK)* ; +exp + : LPAREN exp RPAREN # parenExp + | lValue # lValueExp + | number # numberExp + | ID LPAREN (funcRParams)? RPAREN # funcCallExp + | NOT exp # notExp + | ADD exp # unaryAddExp + | SUB exp # unarySubExp + | exp MUL exp # mulExp + | exp DIV exp # divExp + | exp MOD exp # modExp + | exp ADD exp # addExp + | exp SUB exp # subExp + | exp LT exp # ltExp + | exp LE exp # leExp + | exp GT exp # gtExp + | exp GE exp # geExp + | exp EQ exp # eqExp + | exp NE exp # neExp + | exp AND exp # andExp + | exp OR exp # orExp + ; + +funcRParams + : exp (COMMA exp)* + ; + number : ILITERAL | FLITERAL