Files
nudt-compiler-cpp/src/antlr4/SysY.g4
2026-03-23 20:01:25 +08:00

253 lines
4.1 KiB
ANTLR
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// SysY 语法扩展支持更多SysY特性
grammar SysY;
/*===-------------------------------------------===*/
/* Lexer rules */
/*===-------------------------------------------===*/
// 关键字
INT: 'int';
FLOAT: 'float';
VOID: 'void';
CONST: 'const';
RETURN: 'return';
IF: 'if';
ELSE: 'else';
WHILE: 'while';
BREAK: 'break';
CONTINUE: 'continue';
// 操作符
ASSIGN: '=';
ADD: '+';
SUB: '-';
MUL: '*';
DIV: '/';
MOD: '%';
LT: '<';
LE: '<=';
GT: '>';
GE: '>=';
EQ: '==';
NE: '!=';
// 逻辑操作符
NOT: '!';
AND: '&&';
OR: '||';
// 括号
LPAREN: '(';
RPAREN: ')';
LBRACE: '{';
RBRACE: '}';
LBRACK: '[';
RBRACK: ']';
// 标点
SEMICOLON: ';';
COMMA: ',';
// 标识符和字面量
ID: [a-zA-Z_][a-zA-Z_0-9]*;
ILITERAL
: DECIMAL_LITERAL
| OCTAL_LITERAL
| HEX_LITERAL
;
fragment DECIMAL_LITERAL
: [0-9]+
;
fragment OCTAL_LITERAL
: '0' [0-7]+
;
fragment HEX_LITERAL
: '0' ('x' | 'X') [0-9a-fA-F]+
;
// 浮点字面量
FLITERAL
: (DECIMAL_FLOAT | HEX_FLOAT)
;
fragment DECIMAL_FLOAT
: ((DIGIT+ '.' DIGIT* | '.' DIGIT+)
(('E' | 'e') ('+' | '-')? DIGIT+)?)
| ((DIGIT+ '.' DIGIT* | '.' DIGIT+ | DIGIT+)
(('E' | 'e') ('+' | '-')? DIGIT+))
| ('0' [0-7]+ '.' [0-7]*
(('E' | 'e') ('+' | '-')? DIGIT+)?)
;
fragment HEX_FLOAT
: '0' ('x' | 'X')
(HEXDIGIT* '.' HEXDIGIT+ | HEXDIGIT+ '.')
(('P' | 'p') ('+' | '-')? DIGIT+)
| '0' ('x' | 'X')
HEXDIGIT+
(('P' | 'p') ('+' | '-')? DIGIT+)
;
fragment DIGIT
: [0-9]
;
fragment HEXDIGIT
: [0-9a-fA-F]
;
// 空白和注释
WS: [ \t\r\n] -> skip;
LINECOMMENT: '//' ~[\r\n]* -> skip;
BLOCKCOMMENT: '/*' .*? '*/' -> skip;
/*===-------------------------------------------===*/
/* 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
| VOID
;
constDef
: ID (LBRACK exp RBRACK)* ASSIGN initValue
;
varDef
: ID (LBRACK exp RBRACK)* (ASSIGN initValue)?
;
initValue
: exp
| LBRACE (initValue (COMMA initValue)*)? RBRACE
;
// 函数定义
funcDef
: funcType ID LPAREN (funcFParams)? RPAREN blockStmt
;
funcType
: INT
| FLOAT
| VOID
;
funcFParams
: funcFParam (COMMA funcFParam)*
;
funcFParam
: btype ID (LBRACK (exp)? RBRACK)*
;
// 语句
blockStmt
: LBRACE blockItem* RBRACE
;
blockItem
: decl
| stmt
;
stmt
: assignStmt
| returnStmt
| blockStmt
| ifStmt
| whileStmt
| breakStmt
| continueStmt
| expStmt
;
expStmt
: exp SEMICOLON
;
assignStmt
: lValue ASSIGN exp SEMICOLON
;
returnStmt
: RETURN (exp)? SEMICOLON
;
ifStmt
: IF LPAREN exp RPAREN stmt (ELSE stmt)?
;
whileStmt
: WHILE LPAREN exp RPAREN stmt
;
breakStmt
: BREAK SEMICOLON
;
continueStmt
: CONTINUE SEMICOLON
;
// 表达式
lValue
: ID (LBRACK exp RBRACK)*
;
exp
: LPAREN exp RPAREN # parenExp
| lValue # lValueExp
| number # numberExp
| ID LPAREN (funcRParams)? RPAREN # funcCallExp
| NOT exp # notExp
| ADD exp # unaryAddExp
| SUB exp # unarySubExp
| exp MUL exp # mulExp
| exp DIV exp # divExp
| exp MOD exp # modExp
| exp ADD exp # addExp
| exp SUB exp # subExp
| exp LT exp # ltExp
| exp LE exp # leExp
| exp GT exp # gtExp
| exp GE exp # geExp
| exp EQ exp # eqExp
| exp NE exp # neExp
| exp AND exp # andExp
| exp OR exp # orExp
;
funcRParams
: exp (COMMA exp)*
;
number
: ILITERAL
| FLITERAL
;