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]*; 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 : (decl | funcDef)+ EOF ; decl : constDecl | varDecl ; 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 : ID (LBRACK constExp RBRACK)* (ASSIGN initVal)? ; initVal : exp | LBRACE (initVal (COMMA initVal)*)? RBRACE ; funcDef : funcType ID LPAREN funcFParams? RPAREN block ; funcType : VOID | INT | FLOAT ; funcFParams : funcFParam (COMMA funcFParam)* ; funcFParam : bType ID (LBRACK RBRACK (LBRACK exp RBRACK)*)? ; block : LBRACE blockItem* RBRACE ; blockItem : decl | stmt ; stmt : 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 ; exp : addExp ; cond : lOrExp ; lVal : ID (LBRACK exp RBRACK)* ; primaryExp : LPAREN exp RPAREN | lVal | number ; number : 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 ;