Commit for experimental 1

This commit is contained in:
rain2133
2025-03-04 10:03:07 +08:00
parent 767bcbb609
commit 6f51e76804
4 changed files with 472 additions and 329 deletions

View File

@@ -4,6 +4,52 @@ grammar SysY;
/* Lexer rules */
/*===-------------------------------------------===*/
// keywords
CONST: 'const';
INT: 'int';
FLOAT: 'float';
VOID: 'void';
IF: 'if';
ELSE: 'else';
WHILE: 'while';
BREAK: 'break';
CONTINUE: 'continue';
RETURN: 'return';
// operators
ADD: '+';
SUB: '-';
MUL: '*';
DIV: '/';
MOD: '%';
// relational operators
EQ: '==';
NE: '!=';
LT: '<';
LE: '<=';
GT: '>';
GE: '>=';
// logical operators
AND: '&&';
OR: '||';
NOT: '!';
// assignment operators
ASSIGN: '=';
// punctuations
COMMA: ',';
SEMICOLON: ';';
LPAREN: '(';
RPAREN: ')';
LBRACE: '{';
RBRACE: '}';
LBRACK: '[';
RBRACK: ']';
// fragments
fragment DecDigit: [0-9];
fragment OctDigit: [0-7];
@@ -11,112 +57,122 @@ fragment HexDigit: [0-9a-fA-F];
fragment OctPrefix: '0';
fragment HexPrefix: '0' [xX];
fragment NonZeroDecDigit: [1-9];
fragment Sign: '+' | '-';
fragment DecFractional: DecDigit* '.' DecDigit+ | DecDigit+ '.';
fragment Exponent: [eE] Sign? DecDigit+;
fragment DecFloat: DecFractional Exponent? | DecDigit+ Exponent;
fragment HexFractional: HexDigit* '.' HexDigit+ | HexDigit+ '.';
fragment BinExponent: [pP] Sign? DecDigit+;
fragment HexFloat:
HexPrefix HexFractional BinExponent
| HexPrefix HexDigit+ BinExponent;
fragment ESC: '\\"' | '\\\\';
// keywords
INT: 'int';
FLOAT: 'float';
CONST: 'const';
// operators
ADD: '+';
// punctuations
// identifier
IDENT: IDENTNONDIGIT (IDENTNONDIGIT | DecDigit)*;
IDENTNONDIGIT: [a-zA-Z_];
fragment ALPHA: [a-zA-Z];
fragment ALPHANUM: [a-zA-Z0-9];
fragment NONDIGIT: [a-zA-Z_];
Ident: NONDIGIT (ALPHANUM | '_')*;
// IntConst -> ILITERAL
// FloatConst -> FLITERAL
// literals
ILITERAL: INTCONST | FLOATCONST;
ILITERAL:
NonZeroDecDigit DecDigit*
| OctPrefix OctDigit*
| HexPrefix HexDigit+;
// fliteral
FLITERAL: DecFloat | HexFloat;
// string
STRING: '"' (ESC | .)*? '"';
// white space and comments
WS: [ \t\r\n] -> skip;
WS: [\t\r\n ] -> skip;
LINECOMMENT: '//' .*? '\r'? '\n' -> skip;
BLOCKCOMMENT: '/*' .*? '*/' -> skip;
INTCONST: NonZeroDecDigit DecDigit*
| OctPrefix OctDigit*
| HexPrefix HexDigit+;
DIGITSEQUENCE: DecDigit+;
// Floating point constants
FLOATCONST: DecimalFloatingConstant
| HexadecimalFloatingConstant;
DecimalFloatingConstant: FractionalConstant ExponentPart? // 允许无指数
| DIGITSEQUENCE ExponentPart; // 保留原有形式
HexadecimalFloatingConstant: HexPrefix HexadecimalFractionalConstant BinaryExponentPart
| HexPrefix HexadecimalDigitSequence BinaryExponentPart;
FractionalConstant: DIGITSEQUENCE? '.' DIGITSEQUENCE
| DIGITSEQUENCE '.';
ExponentPart:
[eE] [+-]? DIGITSEQUENCE;
HexadecimalFractionalConstant: HexadecimalDigitSequence? '.' HexadecimalDigitSequence
| HexadecimalDigitSequence '.';
HexadecimalDigitSequence: HexDigit+;
BinaryExponentPart:
[pP] [+-]? DIGITSEQUENCE;
/*===-------------------------------------------===*/
/* Syntax rules */
/*===-------------------------------------------===*/
// module: funcRParams;
// compUnit: (dcl | funcDef)+;
module: (dcl | funcDef)+ | funcRParams;
funcRParams: funcRParam (',' funcRParam)*;
// CompUnit: (CompUnit)? (decl |funcDef);
funcRParam: number # expAsRParam | string # stringAsRParam | exp (',' exp)* # expsAsRParam;
// funcRParam: exp (',' exp)*;
compUnit: (decl |funcDef)+;
number: ILITERAL;
decl: constDecl | varDecl;
string: STRING;
constDecl: CONST bType constDef (COMMA constDef)* SEMICOLON;
bType: INT | FLOAT;
dcl: constDecl | varDecl;
constDecl: CONST bType constDef (',' constDef)* ';';
constDef: IDENT ( '[' constExp ']' )* '=' constInitVal;
constInitVal: constExp
| '{' (constInitVal (',' constInitVal)*)? '}';
varDecl: bType varDef (',' varDef)* ';';
varDef: IDENT ( '[' constExp ']' )* initVal?
| IDENT ( '[' constExp ']' )* '=' initVal;
initVal: exp | '{' ( initVal ( ',' initVal )* )? '}';
funcDef: funcType IDENT '(' funcFParams? ')' block;
funcType: bType | 'void';
funcFParams: funcFParam (',' funcFParam )*;
funcFParam: bType IDENT ( '[' ']' ( '[' exp ']' )* )?;
block: '{' blockItem* '}';
blockItem: dcl | stmt;
stmt: lVal '=' exp ';'
| exp? ';'
// | IDENT '(' funcRParams? ')' ';'
| block
| 'if' '(' cond ')' stmt ('else' stmt)?
| 'while' '(' cond ')' stmt
| 'break' ';'
| 'continue' ';'
| 'return' exp? ';';
constDef: Ident (LBRACK constExp RBRACK)* ASSIGN constInitVal;
constInitVal: constExp
| LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE;
varDecl: bType varDef (COMMA varDef)* SEMICOLON;
varDef: Ident (LBRACK constExp RBRACK)*
| Ident (LBRACK constExp RBRACK)* ASSIGN initVal;
initVal: exp
| LBRACE (initVal (COMMA initVal)*)? RBRACE;
funcType: VOID | INT | FLOAT;
funcDef: funcType Ident LPAREN funcFParams? RPAREN blockStmt;
funcFParams: funcFParam (COMMA funcFParam)*;
// 函数形参感觉定义有问题
// 应该是funcFParam: bType Ident ((LBRACK RBRACK)* (LBRACK exp RBRACK)*)?;
funcFParam: bType Ident (LBRACK RBRACK (LBRACK exp RBRACK)*)?;
blockStmt: LBRACE blockItem* RBRACE;
blockItem: decl | stmt;
stmt: lValue ASSIGN exp SEMICOLON
| blockStmt
| IF LPAREN cond RPAREN stmt (ELSE stmt)?
| WHILE LPAREN cond RPAREN stmt
| BREAK SEMICOLON
| CONTINUE SEMICOLON
| RETURN exp? SEMICOLON;
exp: addExp;
cond: lorExp;
lVal: IDENT ( '[' exp ']' )*;
primaryExp: '(' exp ')' | lVal | number;
// number: INTCONST | FLOATCONST;
unaryExp: primaryExp | IDENT '(' funcRParams? ')'
| unaryOp unaryExp;
unaryOp: '+' | '-' | '!';
mulExp: unaryExp (('*' | '/' | '%') unaryExp)*;
addExp: mulExp | addExp ('+' | '-') mulExp;
relExp: addExp | relExp ('<' | '>' | '<=' | '>=') addExp;
eqExp: relExp | eqExp ('==' | '!=') relExp;
landExp: eqExp | landExp '&&' eqExp;
lorExp: landExp | lorExp '||' landExp;
constExp: addExp;
cond: lOrExp;
lValue: Ident (LBRACK exp RBRACK)*;
// 为了方便测试 primaryExp 可以是一个string
primaryExp: LPAREN exp RPAREN
| lValue
| number
| string;
number: ILITERAL | FLITERAL;
unaryExp: primaryExp
| Ident LPAREN (funcRParams)? RPAREN
| unaryOp unaryExp;
unaryOp: ADD|SUB|NOT;
funcRParams: exp (COMMA exp)*;
string: STRING;
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 (AND eqExp)*;
lOrExp: lAndExp (OR lAndExp)*;
constExp: addExp;
// mulExp: unaryExp ((MUL|DIV|MOD) unaryExp)*;
// addExp: mulExp | addExp (ADD|SUB) mulExp;
// relExp: addExp | relExp (LT|GT|LE|GE) addExp;
// eqExp: relExp | eqExp (EQ|NE) relExp;
// lAndExp: eqExp | lAndExp AND eqExp;
// lOrExp: lAndExp | lOrExp OR lAndExp;
// constExp: addExp;