You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
4.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// SysY 子集语法
grammar SysY;
//----词法规则(优先级从高到低)----//
//keywords
Void : 'void';
Int : 'int';
Float : 'float';
Const : 'const';
If : 'if';
Else : 'else';
While : 'while';
Break : 'break';
Continue: 'continue';
Return : 'return';
//Two-character operator (long preferred)
LeOp : '<=';
GeOp : '>=';
EqOp : '==';
NeOp : '!=';
AndOp : '&&';
OrOp : '||';
//single character operators
AddOp : '+';
SubOp : '-';
MulOp : '*';
DivOp : '/';
QuoOp : '%';
NotOp : '!';
LOp : '<';
GOp : '>';
Assign : '=';
//Separator
Semi : ';';
Comma : ',';
L_PAREN : '(';
R_PAREN : ')';
L_BRACK : '[';
R_BRACK : ']';
L_BRACE : '{';
R_BRACE : '}';
//const numeric classes
//Number... change
// float first
// 16进制float first
HEX_FLOAT
: '0' [xX](
// 形式1: 0x1.921fb6p+1 (有小数点和指数)
HEX_DIGIT* '.' HEX_DIGIT+ [pP] [+-]? DECIMAL_DIGIT+
| // 形式2: 0x1p+1 (没有小数点,只有指数)
HEX_DIGIT+ [pP] [+-]? DECIMAL_DIGIT+
| // 形式3: 0x.AP-3 (小数点开头)
'.' HEX_DIGIT+ [pP] [+-]? DECIMAL_DIGIT+
)
;
fragment HEX_DIGIT: [0-9a-fA-F];
fragment DECIMAL_DIGIT: [0-9];
// 10进制float
DEC_FLOAT
: [0-9]+ '.' [0-9]* EXP? //1.2/1./1.2e10/...
| '.' [0-9]+ EXP? //.1/.1e2
| [0-9]+ EXP //1e2/1e-2
;
fragment EXP: [eE] [+-]? [0-9]+;
HEX_INT: '0' [xX] [0-9a-fA-F]+; //16进制
OCTAL_INT: '0' [0-7]*; //8进制
DECIMAL_INT: [1-9][0-9]*; //10进制
ZERO: '0'; //单独0
// TODO: 后续完善IR后移除Number兼容规则
Number
: HEX_FLOAT
| DEC_FLOAT
| HEX_INT
| OCTAL_INT
| DECIMAL_INT
| ZERO
;
// 标识符(放最后)
Ident
: [a-zA-Z_][a-zA-Z_0-9]*
;
// 注释和空白
WS
: [ \t\r\n]+ -> skip
;
COMMENT
: '//' ~[\r\n]* -> skip
;
BLOCK_COMMENT
: '/*' .*? '*/' -> skip
;
//----语法规则----//
compUnit
: (funcDef|decl|program) EOF
;
program
: (decl|funcDef)+
;
decl
: varDecl
| constDecl
;
constDecl
: Const bType constDef (Comma constDef)* Semi
;
bType
: Int
| Float
;
constDef
: Ident (L_BRACK constExp R_BRACK)* Assign constInitVal
;
constInitVal
: constExp
| L_BRACE (constInitVal (Comma constInitVal)*)? R_BRACE
;
varDecl
: bType varDef (Comma varDef)* Semi
| Int Ident (Assign exp)? Semi
;
varDef
: Ident (L_BRACK constExp R_BRACK)* (Assign initVal)?
;
initVal
: exp
| L_BRACE (initVal (Comma initVal)*)? R_BRACE
;
funcDef
: funcType Ident L_PAREN (funcFParams)? R_PAREN block
;
funcType
: Void
| Int
| Float
;
funcFParams
: funcFParam (Comma funcFParam)*
;
funcFParam
: bType Ident (L_BRACK R_BRACK (L_BRACK exp R_BRACK)*)?
;
block
: L_BRACE (blockItem)* R_BRACE
;
blockItem
: decl
| stmt
;
stmt
: lVal Assign exp Semi
| (exp)? Semi
| block
| If L_PAREN cond R_PAREN stmt (Else stmt)?
| While L_PAREN cond R_PAREN stmt
| Break Semi
| Continue Semi
| returnStmt
;
returnStmt
: Return (exp)? Semi
;
exp
: addExp
;
cond
: lOrExp
;
lVal
: Ident (L_BRACK exp R_BRACK)*
;
primary
: L_PAREN exp R_PAREN
| lVal
| Number // 让旧代码能用
| HEX_FLOAT
| DEC_FLOAT
| HEX_INT
| OCTAL_INT
| DECIMAL_INT
| ZERO
| Ident
;
unaryExp
: primary
| Ident L_PAREN (funcRParams)? R_PAREN
| unaryOp unaryExp
;
unaryOp
: AddOp
| SubOp
| NotOp
;
funcRParams
: exp (Comma exp)*
;
mulExp
: unaryExp
| mulExp (MulOp|DivOp|QuoOp) unaryExp
;
addExp
: mulExp
| addExp (AddOp|SubOp) mulExp
| primary (AddOp primary)*
;
relExp
: addExp
| relExp (LOp|GOp|LeOp|GeOp) addExp
;
eqExp
: relExp
| eqExp (EqOp|NeOp) relExp
;
lAndExp
: eqExp
| lAndExp AndOp eqExp
;
lOrExp
: lAndExp
| lOrExp OrOp lAndExp
;
constExp
: addExp
;