diff --git a/src/antlr4/SysY.g4 b/src/antlr4/SysY.g4 index 263aeef..d3633df 100644 --- a/src/antlr4/SysY.g4 +++ b/src/antlr4/SysY.g4 @@ -1,67 +1,145 @@ -// 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: '='; +EQ: '=='; +NE: '!='; +LT: '<'; +GT: '>'; +LE: '<='; +GE: '>='; + ADD: '+'; +SUB: '-'; +MUL: '*'; +DIV: '/'; +MOD: '%'; +NOT: '!'; +LAND: '&&'; +LOR: '||'; LPAREN: '('; RPAREN: ')'; LBRACE: '{'; RBRACE: '}'; +LBRACK: '['; +RBRACK: ']'; +COMMA: ','; SEMICOLON: ';'; +FLOAT_CONST + : DEC_FLOAT_CONST + | HEX_FLOAT_CONST + ; + +INT_CONST + : HEX_PREFIX HEX_DIGIT+ + | '0' [0-7]+ + | '0' + | [1-9] DIGIT* + ; + ID: [a-zA-Z_][a-zA-Z_0-9]*; -ILITERAL: [0-9]+; WS: [ \t\r\n] -> skip; LINECOMMENT: '//' ~[\r\n]* -> skip; BLOCKCOMMENT: '/*' .*? '*/' -> skip; +fragment DEC_FLOAT_CONST + : DIGIT+ '.' DIGIT* EXP_PART? + | '.' DIGIT+ EXP_PART? + | DIGIT+ EXP_PART + ; + +fragment HEX_FLOAT_CONST + : HEX_PREFIX HEX_DIGIT+ '.' HEX_DIGIT* BIN_EXP_PART + | HEX_PREFIX '.' HEX_DIGIT+ BIN_EXP_PART + | HEX_PREFIX HEX_DIGIT+ BIN_EXP_PART + ; + +fragment EXP_PART: [eE] [+-]? DIGIT+; +fragment BIN_EXP_PART: [pP] [+-]? DIGIT+; +fragment HEX_PREFIX: '0' [xX]; +fragment HEX_DIGIT: [0-9a-fA-F]; +fragment DIGIT: [0-9]; + /*===-------------------------------------------===*/ /* Syntax rules */ /*===-------------------------------------------===*/ compUnit - : funcDef EOF + : (decl | funcDef)+ EOF ; decl - : btype varDef SEMICOLON + : constDecl + | varDecl ; -btype +constDecl + : CONST bType constDef (COMMA constDef)* SEMICOLON + ; + +varDecl + : bType varDef (COMMA varDef)* SEMICOLON + ; + +bType : INT + | FLOAT + ; + +constDef + : ID (LBRACK constExp RBRACK)* ASSIGN constInitVal + ; + +constInitVal + : constExp + | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE ; varDef - : lValue (ASSIGN initValue)? + : ID (LBRACK constExp RBRACK)* (ASSIGN initVal)? ; -initValue +initVal : exp + | LBRACE (initVal (COMMA initVal)*)? RBRACE ; funcDef - : funcType ID LPAREN RPAREN blockStmt + : funcType ID LPAREN funcFParams? RPAREN block ; funcType - : INT + : VOID + | INT + | FLOAT ; -blockStmt +funcFParams + : funcFParam (COMMA funcFParam)* + ; + +funcFParam + : bType ID (LBRACK RBRACK (LBRACK exp RBRACK)*)? + ; + +block : LBRACE blockItem* RBRACE ; @@ -71,28 +149,79 @@ blockItem ; stmt - : returnStmt + : lVal ASSIGN exp SEMICOLON + | exp? SEMICOLON + | block + | IF LPAREN cond RPAREN stmt (ELSE stmt)? + | WHILE LPAREN cond RPAREN stmt + | BREAK SEMICOLON + | CONTINUE SEMICOLON + | RETURN exp? SEMICOLON ; -returnStmt - : RETURN exp SEMICOLON +exp + : addExp ; -exp - : LPAREN exp RPAREN # parenExp - | var # varExp - | number # numberExp - | exp ADD exp # additiveExp +cond + : lOrExp ; -var - : ID +lVal + : ID (LBRACK exp RBRACK)* ; -lValue - : ID +primaryExp + : LPAREN exp RPAREN + | lVal + | number ; number - : ILITERAL + : INT_CONST + | FLOAT_CONST + ; + +unaryExp + : primaryExp + | ID LPAREN funcRParams? RPAREN + | unaryOp unaryExp + ; + +unaryOp + : ADD + | SUB + | NOT + ; + +funcRParams + : exp (COMMA exp)* + ; + +mulExp + : unaryExp ((MUL | DIV | MOD) unaryExp)* + ; + +addExp + : mulExp ((ADD | SUB) mulExp)* + ; + +relExp + : addExp ((LT | GT | LE | GE) addExp)* + ; + +eqExp + : relExp ((EQ | NE) relExp)* + ; + +lAndExp + : eqExp (LAND eqExp)* + ; + +lOrExp + : lAndExp (LOR lAndExp)* + ; + +constExp + : addExp ;