grammar Sysy; program: compUnit; compUnit: (funcDef | decl)+; decl: constDecl | varDecl; constDecl: 'const' bType constDef (',' constDef)* ';'; bType: 'int'; constDef: IDENT ('[' constExp ']')* '=' constInitVal; constInitVal: constExp | ('{' (constInitVal (',' constInitVal)*)? '}'); varDecl: bType varDef (',' varDef)* ';'; varDef: IDENT ('[' constExp ']')* ('=' initVal)?; initVal: exp | ('{' (initVal (',' initVal)*)? '}'); funcDef: funcType IDENT '(' (funcFParams)? ')' block; funcType: 'void' | 'int'; funcFParams: funcFParam (',' funcFParam)*; funcFParam: bType IDENT ('[' ']' ('[' exp ']')*)?; block: '{' (blockItem)* '}'; blockItem: decl | stmt; stmt: lVal '=' exp ';' # assignStmt | (exp)? ';' # expStmt | block # blockStmt | 'if' '(' cond ')' stmt ('else' stmt)? # ifStmt | 'while' '(' cond ')' stmt # whileStmt | 'break' ';' # breakStmt | 'continue' ';' # continueStmt | 'return' (exp)? ';' # returnStmt; exp: addExp; cond: lOrExp; lVal: IDENT ('[' exp ']')*; primaryExp: ('(' exp ')') | lVal | number; number: intConst; intConst: DECIMAL_CONST | OCTAL_CONST | HEXADECIMAL_CONST; unaryExp: primaryExp | IDENT '(' (funcRParams)? ')' | unaryOp unaryExp; unaryOp: '+' | '-' | '!'; // 注:'!'仅出现在条件表达式中 funcRParams: funcRParam (',' funcRParam)*; funcRParam: exp | StringLiteral; mulExp: unaryExp | mulExp ('*' | '/' | '%') unaryExp; // ANTLR4 has support for direct left recursion addExp: mulExp | addExp ('+' | '-') mulExp; relExp: addExp | relExp ('<' | '>' | '<=' | '>=') addExp; eqExp: relExp | eqExp ('==' | '!=') relExp; lAndExp: eqExp | lAndExp '&&' eqExp; lOrExp: lAndExp | lOrExp '||' lAndExp; constExp: addExp; // 注:使用的 Ident 必须是常量 // -------- Terminals --------- IDENT: [_a-zA-Z] | [_a-zA-Z] [_a-zA-Z0-9]+; DECIMAL_CONST: [1-9] | [1-9] [0-9]+; OCTAL_CONST: '0' | ('0' [0-7]+); HEXADECIMAL_CONST: ('0x' | '0X') [a-fA-F0-9]+; WS: [ \r\n\t]+ -> skip; SINGLELINE_COMMENT: '//' ~ [\r\n]* -> skip; MULTILINE_COMMENT: '/*' .*? '*/' -> skip; fragment EscapeSequence: '\\' ['"?abfnrtv\\] | '\\' [0-7] [0-7]? [0-7]? | '\\x' [0-9a-fA-F]+; // https://github.com/antlr/grammars-v4/blob/master/c/C.g4 fragment SChar: ~["\\\r\n] | EscapeSequence | '\\\n' // Added line | '\\\r\n' ; // Added line StringLiteral: '"' (SChar+)? '"'; // https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md