Compare commits

..

3 Commits

Author SHA1 Message Date
helingyu 8e78addf65 yulab1
1 week ago
qingshanzack afc0a4ed41 hmxlab1
2 weeks ago
qingshanzack 19344b0c0b hmxlab1
2 weeks ago

@ -1,8 +1,4 @@
// SysY 子集语法:支持形如 // SysY 语法:支持完整的 SysY 子集
// int main() { int a = 1; int b = 2; return a + b; }
// 的最小返回表达式编译。
// 后续需要自行添加
grammar SysY; grammar SysY;
@ -11,19 +7,57 @@ grammar SysY;
/*===-------------------------------------------===*/ /*===-------------------------------------------===*/
INT: 'int'; INT: 'int';
VOID: 'void';
FLOAT: 'float';
RETURN: 'return'; RETURN: 'return';
CONST: 'const';
IF: 'if';
ELSE: 'else';
WHILE: 'while';
BREAK: 'break';
CONTINUE: 'continue';
ASSIGN: '='; ASSIGN: '=';
ADD: '+'; ADD: '+';
SUB: '-';
MUL: '*';
DIV: '/';
MOD: '%';
LT: '<';
LE: '<=';
GT: '>';
GE: '>=';
EQ: '==';
NEQ: '!=';
AND: '&&';
OR: '||';
NOT: '!';
LPAREN: '('; LPAREN: '(';
RPAREN: ')'; RPAREN: ')';
LBRACE: '{'; LBRACE: '{';
RBRACE: '}'; RBRACE: '}';
LBRACK: '[';
RBRACK: ']';
SEMICOLON: ';'; SEMICOLON: ';';
COMMA: ',';
ID: [a-zA-Z_][a-zA-Z_0-9]*; ID: [a-zA-Z_][a-zA-Z_0-9]*;
ILITERAL: [0-9]+;
ILITERAL
: [0-9]+
| '0' [xX] [0-9a-fA-F]+
;
FLITERAL
: [0-9]+ '.' [0-9]* ([eE] [+-]? [0-9]+)?
| [0-9]+ [eE] [+-]? [0-9]+
| '.' [0-9]+ ([eE] [+-]? [0-9]+)?
| '0' [xX] [0-9a-fA-F]* '.' [0-9a-fA-F]+ [pP] [+-]? [0-9]+
| '0' [xX] [0-9a-fA-F]+ [pP] [+-]? [0-9]+
;
WS: [ \t\r\n] -> skip; WS: [ \t\r\n] -> skip;
LINECOMMENT: '//' ~[\r\n]* -> skip; LINECOMMENT: '//' ~[\r\n]* -> skip;
@ -34,15 +68,38 @@ BLOCKCOMMENT: '/*' .*? '*/' -> skip;
/*===-------------------------------------------===*/ /*===-------------------------------------------===*/
compUnit compUnit
: funcDef EOF : (decl | funcDef)* EOF
; ;
decl decl
: btype varDef SEMICOLON : constDecl
| varDecl
;
constDecl
: CONST btype constDef (COMMA constDef)* SEMICOLON
;
constDef
: lValue ASSIGN initValue
;
constInitVal
: constExp
| LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE
;
constExp
: exp
;
varDecl
: btype varDef (COMMA varDef)* SEMICOLON
; ;
btype btype
: INT : INT
| FLOAT
; ;
varDef varDef
@ -51,14 +108,30 @@ varDef
initValue initValue
: exp : exp
| arrayInit
;
arrayInit
: LBRACE (initValue (COMMA initValue)*)? RBRACE
; ;
funcDef funcDef
: funcType ID LPAREN RPAREN blockStmt : funcType ID LPAREN (funcFParams)? RPAREN blockStmt
; ;
funcType funcType
: INT : INT
| VOID
| FLOAT
;
funcFParams
: funcFParam (COMMA funcFParam)*
;
funcFParam
: btype ID (LBRACK (exp)? RBRACK)*
| btype ID LBRACK RBRACK LBRACK exp RBRACK
; ;
blockStmt blockStmt
@ -72,27 +145,78 @@ blockItem
stmt stmt
: returnStmt : returnStmt
| assignStmt
| ifStmt
| whileStmt
| breakStmt
| continueStmt
| exprStmt
| blockStmt
;
continueStmt
: CONTINUE SEMICOLON
; ;
returnStmt returnStmt
: RETURN exp SEMICOLON : RETURN (exp)? SEMICOLON
;
assignStmt
: lValue ASSIGN exp SEMICOLON
;
ifStmt
: IF LPAREN cond RPAREN stmt (ELSE stmt)?
;
whileStmt
: WHILE LPAREN cond RPAREN stmt
;
breakStmt
: BREAK SEMICOLON
;
exprStmt
: exp SEMICOLON
;
cond
: exp
; ;
exp exp
: LPAREN exp RPAREN # parenExp : LPAREN exp RPAREN # parenExp
| var # varExp | var # varExp
| number # numberExp | number # numberExp
| ID LPAREN (exp (COMMA exp)*)? RPAREN # funcCallExp
| SUB exp # unaryMinusExp
| NOT exp # unaryNotExp
| exp MUL exp # multiplicativeExp
| exp DIV exp # multiplicativeExp
| exp MOD exp # multiplicativeExp
| exp ADD exp # additiveExp | exp ADD exp # additiveExp
| exp SUB exp # additiveExp
| exp LT exp # relationalExp
| exp LE exp # relationalExp
| exp GT exp # relationalExp
| exp GE exp # relationalExp
| exp EQ exp # equalityExp
| exp NEQ exp # equalityExp
| exp AND exp # logicalAndExp
| exp OR exp # logicalOrExp
; ;
var var
: ID : ID (LBRACK exp RBRACK)*
; ;
lValue lValue
: ID : ID (LBRACK exp RBRACK)*
; ;
number number
: ILITERAL : ILITERAL
| FLITERAL
; ;

@ -0,0 +1,56 @@
#!/bin/bash
echo "======================================"
echo "Lab1 语法树构建 - 完整批量测试"
echo "时间: $(date)"
echo "======================================"
PASS=0
FAIL=0
FAILED_FILES=()
TOTAL=0
# 递归查找所有 .sy 文件
while IFS= read -r file; do
((TOTAL++))
filename=$(basename "$file")
rel_path=${file#test/test_case/}
echo -n "[$TOTAL] 测试 $rel_path ... "
# 运行编译器检查解析是否成功
if ./build/bin/compiler --emit-parse-tree "$file" > /dev/null 2>&1; then
echo "✓ 通过"
((PASS++))
else
echo "✗ 失败"
((FAIL++))
FAILED_FILES+=("$rel_path")
# 输出错误信息到临时文件以便调试
echo " 错误详情:" >&2
./build/bin/compiler --emit-parse-tree "$file" 2>&1 | head -5 | sed 's/^/ /' >&2
fi
done < <(find test/test_case -name "*.sy" -type f | sort)
echo "======================================"
echo "测试结果统计"
echo "======================================"
echo "总计: $TOTAL"
echo "通过: $PASS"
echo "失败: $FAIL"
echo "成功率: $(awk "BEGIN {printf \"%.2f\", ($PASS/$TOTAL)*100}")%"
echo "======================================"
if [ $FAIL -gt 0 ]; then
echo ""
echo "失败的测试用例 ($FAIL 个):"
for f in "${FAILED_FILES[@]}"; do
echo "$f"
done
exit 1
fi
echo ""
echo "🎉 所有测试用例通过!"
exit 0
Loading…
Cancel
Save