Untitled

Anonymous
Plain Text
02/08/2026 7:50 AM
4.5 KB
10
Indexable
Never
    grammar TyC;

    @lexer::header {
    from lexererr import *
    }

    @lexer::members {
    def emit(self):
        tk = self.type
        if tk == self.UNCLOSE_STRING:       
            result = super().emit();
            raise UncloseString(result.text);
        elif tk == self.ILLEGAL_ESCAPE:
            result = super().emit();
            raise IllegalEscape(result.text);
        elif tk == self.ERROR_CHAR:
            result = super().emit();
            raise ErrorToken(result.text); 
        else:
            return super().emit();
    }

    options{
        language=Python3;
    }

    // ==LEXER==

    //Keywords
    AUTO: 'auto';
    BREAK: 'break';
    CASE: 'case';
    CONTINUE: 'continue';
    DEFAULT: 'default';
    ELSE: 'else';
    FLOAT: 'float';
    FOR: 'for';
    IF: 'if';
    INT: 'int';
    RETURN: 'return';
    STRING: 'string';
    STRUCT: 'struct';
    SWITCH: 'switch';
    VOID: 'void';
    WHILE: 'while';

    //Operators
    ADD: '+';
    SUB: '-';
    MUL: '*';
    DIV: '/';
    MOD: '%';
    EQ: '==';
    NEQ: '!=';
    LES: '<';
    GRE: '>';
    LESEQ: '<=';
    GREEQ: '>=';
    OR: '||';
    AND: '&&';
    NOT: '!';
    INC: '++';
    DEC: '--';
    ASSIGN: '=';
    MEMACCESS: '.';

    //Separators
    LBRACE: '{';
    RBRACE: '}';
    LPAREN: '(';
    RPAREN: ')';
    SEMI: ';';
    COMMA: ',';
    COLON: ':';

    //Identifiers
    IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;

    //Literals
    INTLIT: [0-9]+;
    FLOATLIT:
        [0-9]+ '.' [0-9]* ([eE][+-]?[0-9]+)?
        | '.' [0-9]+ ([eE][+-]?[0-9]+)?
        | [0-9]+ [eE][+-]?[0-9]+
        ;

    fragment ESC: '\\' [bfrnt"'\\];
    fragment CHAR: ~["\\\r\n] | ESC;
    //with tokens
    
    ILLEGAL_ESCAPE: '"' CHAR* '\\' ~[bfrnt"'\\\r\n] {
        self.text = self.text[1:]
    };
    UNCLOSE_STRING: '"' CHAR* ([\r\n] | EOF) {
        self.text = self.text[1:]
    };
    STRINGLIT: '"' CHAR* '"' {
        self.text = self.text[1:-1]
    };

    WS: [ \t\r\n\f]+ -> skip;
    BLOCK_COMMENT: '/*' .*? '*/' -> skip;
    LINE_COMMENT: '//' ~[\r\n]* -> skip;
    ERROR_CHAR: .;

    //==PARSER==

    // TODO: Define grammar rules here
    program: (structDec1 | funcDec1)* EOF;

    structDec1: STRUCT IDENTIFIER LBRACE memberDec1* RBRACE SEMI;
    memberDec1: type IDENTIFIER SEMI;

    funcDec1: (type | VOID)? IDENTIFIER LPAREN paramList? RPAREN block;
    paramList: param (COMMA param)*;
    param: type IDENTIFIER;

    type: primitiveType | IDENTIFIER;
    primitiveType: INT | FLOAT | STRING;

    block: LBRACE stmt* RBRACE;
    stmt:
        varDec1Stmt
        | assignStmt SEMI
        | ifStmt
        | whileStmt
        | forStmt
        | switchStmt
        | returnStmt SEMI
        | breakStmt SEMI
        | continueStmt SEMI
        | callStmt SEMI
        | expr SEMI
        | block
        ;

    //Vari declaration
    varDec1Stmt: (AUTO | type) IDENTIFIER (ASSIGN expr)? SEMI;

    //Assign
    assignStmt: lhs ASSIGN expr;
    lhs: IDENTIFIER | expr MEMACCESS IDENTIFIER;

    //Control
    ifStmt: IF LPAREN expr RPAREN stmt (ELSE stmt)?;
    whileStmt: WHILE LPAREN expr RPAREN stmt;
    forStmt: FOR LPAREN forInit SEMI expr? SEMI forUpdate? RPAREN stmt;
    forInit: (AUTO IDENTIFIER (ASSIGN expr)? | type IDENTIFIER (ASSIGN expr)? | assignStmt)?;
    forUpdate: assignStmt | incDecExpr;

    //Switch
    switchStmt: SWITCH LPAREN expr RPAREN LBRACE switchCase* RBRACE;
    switchCase: CASE expr COLON stmt* | DEFAULT COLON stmt*;

    //Others
    breakStmt: BREAK;
    continueStmt: CONTINUE;
    returnStmt: RETURN expr?;

    //callStmt: IDENTIFIER LPAREN argList? RPAREN;

    expr1:
        literal
        | IDENTIFIER
        | LPAREN expr RPAREN
        | IDENTIFIER LPAREN argList? RPAREN
        | expr1 MEMACCESS IDENTIFIER
        ;

    //Literals
    literal: INTLIT | FLOATLIT | STRINGLIT | structLiteral;
    structLiteral: LBRACE exprList? RBRACE;

    incDecExpr: (INC | DEC) expr1 | expr1 (INC | DEC);
    argList: expr (COMMA expr)*;
    exprList: expr (COMMA expr)*;

    expr2: expr1 (INC | DEC)?;

    expr3: (SUB | NOT | INC | DEC) expr3 | expr2;

    expr4: expr3 ((MUL | DIV | MOD) expr3)*;

    expr5: expr4 ((ADD | SUB) expr4)*;

    expr6: expr5 ((LES | GRE | LESEQ | GREEQ) expr5)*;

    expr7: expr6 ((EQ | NEQ) expr6)*;

    expr8: expr7 (AND expr7)*;

    expr9: expr8 (OR expr8)*;

    expr: 
        expr9
        | expr ASSIGN expr
        ;
Editor is loading...
Leave a Comment