// 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 | DIV | MOD) exp  # mulDivModExp
    | exp (ADD | SUB) exp        # addSubExp
    | exp (LT | LE | GT | GE) exp # relExp
    | exp (EQ | NE) exp          # eqNeExp
    | exp AND exp                # andExp
    | exp OR exp                 # orExp
    ;

funcRParams
    : exp (COMMA exp)*
    ;

number
    : ILITERAL
    | FLITERAL
    ;
