From 3e4165c4bb8c65f7b4bc7b5b5722db822ee788ed Mon Sep 17 00:00:00 2001 From: Oliveira <1350121858@qq.com> Date: Mon, 23 Mar 2026 15:59:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(grammar):=20=E5=AE=8C=E5=96=84=20SysY.g4?= =?UTF-8?q?=20=E8=AF=AD=E6=B3=95=E5=AE=9A=E4=B9=89=E6=94=AF=E6=8C=81=20Lab?= =?UTF-8?q?1=20=E8=A6=81=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 扩展 SysY 语法定义以支持更多合法程序 - 完善词法和语法规则,增强解析能力 - 确保符合 SysY 语言规范 --- src/antlr4/SysY.g4 | 138 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 112 insertions(+), 26 deletions(-) diff --git a/src/antlr4/SysY.g4 b/src/antlr4/SysY.g4 index 263aeef..487fc1e 100644 --- a/src/antlr4/SysY.g4 +++ b/src/antlr4/SysY.g4 @@ -1,31 +1,61 @@ -// SysY 子集语法:支持形如 -// int main() { int a = 1; int b = 2; return a + b; } -// 的最小返回表达式编译。 - -// 后续需要自行添加 - grammar SysY; /*===-------------------------------------------===*/ /* Lexer rules */ /*===-------------------------------------------===*/ +CONST: 'const'; INT: 'int'; +FLOAT: 'float'; +VOID: 'void'; +IF: 'if'; +ELSE: 'else'; +WHILE: 'while'; +BREAK: 'break'; +CONTINUE: 'continue'; RETURN: 'return'; ASSIGN: '='; ADD: '+'; +SUB: '-'; +MUL: '*'; +DIV: '/'; +MOD: '%'; +EQ: '=='; +NEQ: '!='; +LT: '<'; +GT: '>'; +LE: '<='; +GE: '>='; +NOT: '!'; +AND: '&&'; +OR: '||'; LPAREN: '('; RPAREN: ')'; +LBRACK: '['; +RBRACK: ']'; LBRACE: '{'; RBRACE: '}'; +COMMA: ','; SEMICOLON: ';'; ID: [a-zA-Z_][a-zA-Z_0-9]*; -ILITERAL: [0-9]+; -WS: [ \t\r\n] -> skip; +ILITERAL + : '0' | [1-9][0-9]* // Decimal + | '0' [0-7]+ // Octal + | ('0x' | '0X') [0-9a-fA-F]+ // Hex + ; + +FLITERAL + : ([0-9]* '.' [0-9]+ | [0-9]+ '.') ([eE] [+-]? [0-9]+)? + | [0-9]+ [eE] [+-]? [0-9]+ + | ('0x'|'0X') ([0-9a-fA-F]* '.' [0-9a-fA-F]+ | [0-9a-fA-F]+ '.') ([pP] [+-]? [0-9]+)? + | ('0x'|'0X') [0-9a-fA-F]+ [pP] [+-]? [0-9]+ + ; + +WS: [ \t\r\n]+ -> skip; LINECOMMENT: '//' ~[\r\n]* -> skip; BLOCKCOMMENT: '/*' .*? '*/' -> skip; @@ -34,31 +64,62 @@ BLOCKCOMMENT: '/*' .*? '*/' -> skip; /*===-------------------------------------------===*/ compUnit - : funcDef EOF + : (decl | funcDef)+ EOF ; decl - : btype varDef SEMICOLON + : constDecl + | varDecl + ; + +constDecl + : CONST btype constDef (COMMA constDef)* SEMICOLON ; btype : INT + | FLOAT + ; + +constDef + : ID (LBRACK constExp RBRACK)* ASSIGN constInitVal + ; + +constInitVal + : constExp + | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE + ; + +varDecl + : btype varDef (COMMA varDef)* SEMICOLON ; varDef - : lValue (ASSIGN initValue)? + : ID (LBRACK constExp RBRACK)* + | ID (LBRACK constExp RBRACK)* ASSIGN initValue ; initValue : exp + | LBRACE (initValue (COMMA initValue)*)? RBRACE ; funcDef - : funcType ID LPAREN RPAREN blockStmt + : funcType ID LPAREN funcFParams? RPAREN blockStmt ; funcType - : INT + : VOID + | INT + | FLOAT + ; + +funcFParams + : funcFParam (COMMA funcFParam)* + ; + +funcFParam + : btype ID (LBRACK RBRACK (LBRACK exp RBRACK)*)? ; blockStmt @@ -71,28 +132,53 @@ blockItem ; stmt - : returnStmt - ; - -returnStmt - : RETURN exp SEMICOLON + : lValue ASSIGN exp SEMICOLON # assignStmt + | exp? SEMICOLON # exprStmt + | blockStmt # blockStmtStmt + | IF LPAREN cond RPAREN stmt (ELSE stmt)? # ifStmt + | WHILE LPAREN cond RPAREN stmt # whileStmt + | BREAK SEMICOLON # breakStmt + | CONTINUE SEMICOLON # continueStmt + | RETURN exp? SEMICOLON # returnStmt ; exp - : LPAREN exp RPAREN # parenExp - | var # varExp - | number # numberExp - | exp ADD exp # additiveExp + : LPAREN exp RPAREN # parenExp + | lValue # lvalExp + | number # numberExp + | ID LPAREN funcRParams? RPAREN # callExp + | unaryOp exp # unaryExp + | exp (MUL | DIV | MOD) exp # mulExp + | exp (ADD | SUB) exp # addExp + | exp (LT | GT | LE | GE) exp # relExp + | exp (EQ | NEQ) exp # eqExp + | exp AND exp # lAndExp + | exp OR exp # lOrExp ; -var - : ID +cond + : exp ; lValue - : ID + : ID (LBRACK exp RBRACK)* ; number - : ILITERAL + : ILITERAL # intConst + | FLITERAL # floatConst + ; + +unaryOp + : ADD + | SUB + | NOT + ; + +funcRParams + : exp (COMMA exp)* + ; + +constExp + : exp ;