compiler.y

 avatar
unknown
c_cpp
a year ago
14 kB
5
Indexable
/* Definition section */
%{
    #include "compiler_common.h"
    #include "compiler_util.h"
    #include "main.h"

    int yydebug = 1;
%}

/* Union to define types for semantic values */
%union {
    ObjectType var_type;

    bool b_var;
    char c_var;
    int32_t i_var;
    int64_t l_var;
    float f_var;
    double d_var;
    char *s_var;

    Object object_val;

    // LinkList<Object*>
    // LinkedList* array_subscript;
}


/* Token definitions without return types */
%token COUT
%token SHR SHL BAN BOR BNT BXO ADD SUB MUL DIV REM NOT GTR LES GEQ LEQ EQL NEQ LAN LOR
%token VAL_ASSIGN ADD_ASSIGN SUB_ASSIGN MUL_ASSIGN DIV_ASSIGN REM_ASSIGN BAN_ASSIGN BOR_ASSIGN BXO_ASSIGN SHR_ASSIGN SHL_ASSIGN INC_ASSIGN DEC_ASSIGN
%token IF ELSE FOR WHILE RETURN BREAK CONTINUE
//%token '{' '}' '(' ')' '[' ']'
//%token ',' ':' ';'

/* Token definitions with return types */
%token <var_type> VARIABLE_T
%token <b_var> BOOL_LIT
%token <c_var> CHAR_LIT
%token <i_var> INT_LIT
%token <f_var> FLOAT_LIT
%token <s_var> STR_LIT
%token <s_var> IDENT
%token <var_type> AUTO

/* Nonterminal definitions with return types */
%type <object_val> Expression
%type <object_val> Assign
%type <object_val> ARG
%type <object_val> num
%type <object_val> boolean
%type <object_val> id

/* Operator precedence and associativity */
%left LOR
%left LAN
%left GEQ
%left NEQ EQL
%left GTR LES
%left ADD SUB
%left MUL DIV REM
%left VAL_ASSIGN
//%left '(' ')'

/* Start symbol */
%start Program

%%

/* Grammar section */

Program
    : { pushScope(); } GlobalStmtList { dumpScope(); }
    | /* Empty file */
    ;

GlobalStmtList
    : GlobalStmtList GlobalStmt
    | GlobalStmt
    ;

GlobalStmt
    : FunctionDefStmt
    ;


/* Function definitions */
FunctionDefStmt
    : VARIABLE_T IDENT { createFunction($<var_type>1, $<s_var>2);} { pushScope(); } '(' FunctionParameterStmtList ')' '{' StmtList {codeRaw("return"); codeRaw(".end method");} '}' { dumpScope(); }
    | VARIABLE_T IDENT '[' ']' { createFunction($<var_type>1, $<s_var>2); } '(' FunctionParameterStmtList ')' '{' StmtList '}' { dumpScope(); }
    ;

FunctionParameterStmtList
    : FunctionParameterStmtList ',' FunctionParameterStmt
    | FunctionParameterStmt
    | /* Empty function parameter */
    ;

FunctionParameterStmt
    : VARIABLE_T IDENT { pushFunParm($<var_type>1, $<s_var>2, VAR_FLAG_DEFAULT); }
    | VARIABLE_T IDENT '[' ']' { pushFunParm($<var_type>1, $<s_var>2, VAR_FLAG_DEFAULT); }
    ;

/* Statement lists and individual statements */
StmtList
    : StmtList Stmt
    | Stmt
    ;

Stmt
    : ';'
    | COUT CoutParmListStmt ';' { stdoutPrint(); }
    | RETURN Expression ';' { printf("RETURN\n");}
    | VARIABLE_T {setVarT($<var_type>1); } MultiVar ';'
    | Assign ';'
    | IfStmt
    | WHILE { printf("WHILE\n");} { ifExp = true; } { whileStart(); } '(' Expression ')'{ whileBody(); } { ifExp = false; } {pushScope();} '{' StmtList '}' { whileEnd(); } {dumpScope();}
    | FOR { printf("FOR\n");} { forStart(); } { pushScope(); } '(' StmtForList { printf("cool\n"); } ')' { forBody(); } '{' StmtList '}' { forEnd(); } { dumpScope(); }
    | BREAK {printf("BREAK\n");}
    | Expression
    | RETURN ';' { printf("RETURN\n"); }
;

IfStmt
    : IF { ifExp = true; } '(' Expression ')' { ifExp = false; } { ifStart(); } {printf("IF\n");} { pushScope(); } '{' StmtList '}'  { ifEnd(); } { dumpScope(); } Elsepart
    | IF { ifExp = true; }'(' Expression ')' { ifExp = false; } { ifStart(); } {printf("IF\n");} StmtList { ifEnd(); } Elsepart
;

Elsepart
    : ELSE { elseStart(); } { printf("ELSE\n");} { pushScope(); } '{' StmtList '}' { elseEnd(); dumpScope(); }
    | { elseStart(); } { elseEnd(); }
;

StmtForList
    : StmtFor
    | VARIABLE_T IDENT ':' IDENT {
        setVarT(findVarType($4));
        createVNoT($<s_var>2, VAR_FLAG_DEFAULT);
        } {idFunc($4);}
;

StmtFor
    : InitFor ';' { ifExp = true; } EqaFor { ifExp = false; } ';' { forUpBegin(); } OptFor { forUpEnd(); }
;

InitFor
    : InitFor ',' IDENT {right = true;} VAL_ASSIGN ARG {
        createVNoT($<s_var>3, VAR_FLAG_DEFAULT);
        Object *variable = findVariable($<s_var>3);
        if (variable != NULL) {
            objectValueAssign(variable, &$<object_val>5, NULL);
        }
        assStore();
    }{right = false;}
    | IDENT {right = true;} VAL_ASSIGN ARG {
        createVNoT($<s_var>1, VAR_FLAG_DEFAULT);
        Object *variable = findVariable($<s_var>1);
        if (variable != NULL) {
            objectValueAssign(variable, &$<object_val>3, NULL);
        }
        assStore();
    }{right = false;}
    | VARIABLE_T IDENT {right = true;} VAL_ASSIGN ARG {
        setVarT($1);
        createVNoT($<s_var>2, VAR_FLAG_DEFAULT);
        Object *variable = findVariable($<s_var>2);
        if (variable != NULL) {
            objectValueAssign(variable, &$<object_val>4, NULL);
        }
        assStore();
    }{right = false;}
    |
;

EqaFor
    : { forCondBegin(); } Expression { forCondEnd(); }
    |
;

OptFor
    : Expression INC_ASSIGN { printf("INC_ASSIGN\n"); ippFunc(); }
    | Expression DEC_ASSIGN { printf("DEC_ASSIGN\n"); }
    | Expression SUB_ASSIGN { right = true; } Expression { printf("SUB_ASSIGN\n"); operGen("sub"); assStore(); } { right = false; }
    | Expression ADD_ASSIGN { right = true; } Expression { printf("ADD_ASSIGN\n"); operGen("add"); assStore(); } { right = false; }
    |
;


MultiVar
    : MultiVar ',' IDENT {createVNoT($<s_var>3, VAR_FLAG_DEFAULT); }
    | MultiVar ',' IDENT {right = true;} VAL_ASSIGN Expression {
        createVNoT($<s_var>3, VAR_FLAG_DEFAULT);
        Object *variable = findVariable($<s_var>3);
        if (variable != NULL) {
            objectValueAssign(variable, &$<object_val>5, NULL);
        }
        assStore();
        }{right = false;}
    | IDENT VAL_ASSIGN {right = true;} Expression {
        createVNoT($<s_var>1, VAR_FLAG_DEFAULT);
        Object *variable = findVariable($<s_var>1);
        if (variable != NULL) {
            objectValueAssign(variable, &$<object_val>3, NULL);
        }
        assStore();
        } {right = false;}
    | IDENT { createVNoT($<s_var>1, VAR_FLAG_DEFAULT);}
    | '(' IDENT ')'{ createVNoT($<s_var>2, VAR_FLAG_DEFAULT);}
    | IDENT '[' num ']' VAL_ASSIGN '{' ARGS '}' {PrintArrParam();createVNoT($<s_var>1, VAR_FLAG_DEFAULT);}
    | IDENT '[' num ']' '[' num ']' {createVNoT($<s_var>1, VAR_FLAG_DEFAULT);}
;

/* Print statement parameter list */
CoutParmListStmt
    : CoutParmListStmt SHL { codeRaw("getstatic java/lang/System/out Ljava/io/PrintStream;"); } Expression  { coutLoad(); pushFunInParm(&$<object_val>3); invokeFunc(); }
    | SHL { codeRaw("getstatic java/lang/System/out Ljava/io/PrintStream;"); } Expression { coutLoad(); pushFunInParm(&$<object_val>2); invokeFunc(); }
;

/* Expressions */
Expression
    : Assign ';'
    | '(' Expression ')' {Object obj; obj.type = $2.type; $$ = obj;}
    | Expression LOR Expression {printf("LOR\n");Object obj; obj.type = $3.type; $$ = obj; codeRaw("ior"); }
    | Expression LAN Expression {printf("LAN\n");Object obj; obj.type = $3.type; $$ = obj; codeRaw("iand"); }
    | Expression BOR Expression {printf("BOR\n");Object obj; obj.type = $3.type; $$ = obj; operGen("or");}
    | Expression BXO Expression {printf("BXO\n");Object obj; obj.type = $3.type; $$ = obj; operGen("xor");}
    | Expression BAN Expression {printf("BAN\n");Object obj; obj.type = $3.type; $$ = obj; operGen("and");}
    | Expression NEQ Expression {printf("NEQ\n");Object obj; obj.type = $3.type; $$ = obj; notEqualToLabel(); }
    | Expression EQL Expression {printf("EQL\n");Object obj; obj.type = $3.type; $$ = obj; cmpEqualLabel(); }
    | Expression GTR Expression {printf("GTR\n");Object obj; obj.type = $3.type; $$ = obj; greaterThanLabel(); }
    | Expression LES Expression {printf("LES\n");Object obj; obj.type = $3.type; $$ = obj; lessThanLabel(); }
    | Expression GEQ Expression {printf("GEQ\n");Object obj; obj.type = $3.type; $$ = obj; greaterThanEqlLabel(); }
    | Expression LEQ Expression {printf("LEQ\n");Object obj; obj.type = $3.type; $$ = obj; lessThanEqlLabel(); }
    | Expression SHR Expression {printf("SHR\n");Object obj; obj.type = $3.type; $$ = obj; operGen("shr"); }
    | Expression SUB Expression {printf("SUB\n");Object obj; obj.type = $3.type; $$ = obj; operGen("sub"); }
    | Expression ADD Expression {printf("ADD\n");Object obj; obj.type = $3.type; $$ = obj; operGen("add"); }
    | Expression REM Expression {printf("REM\n");Object obj; obj.type = $3.type; $$ = obj; operGen("rem"); }
    | Expression DIV Expression {printf("DIV\n");Object obj; obj.type = $3.type; $$ = obj; operGen("div"); }
    | Expression MUL Expression {printf("MUL\n");Object obj; obj.type = $3.type; $$ = obj; operGen("mul"); }
    | ARG {Object obj; obj.type = $1.type; $$ = obj;}
    | Expression INC_ASSIGN { printf("INC_ASSIGN\n"); Object obj; obj.type = $1.type; $$ = obj; }
    | Expression DEC_ASSIGN { printf("DEC_ASSIGN\n"); Object obj; obj.type = $1.type; $$ = obj; }
    | '(' VARIABLE_T ')' '(' IDENT ')'{ idFunc($<s_var>5); Object obj; obj.type = findVarType($<s_var>5); $$ = obj; } {assLoad(); changeVType($<var_type>2); }
    | '(' VARIABLE_T ')' IDENT { idFunc($<s_var>4); Object obj; obj.type = findVarType($<s_var>4); $$ = obj; } {assLoad(); changeVType($<var_type>2);}
    | '(' VARIABLE_T ')' num { Object obj; obj.type = $2; $$ = obj; }{changeVType($<var_type>2); }
    | '(' VARIABLE_T ')' '(' num ')'{ Object obj; obj.type = $2; $$ = obj; }{changeVType($<var_type>2);}
    | IDENT '(' ARGS ')' {idFunc($1); printcall($1);}
    | IDENT '[' num ']' {idFunc($1); Object obj; obj.type = findVariable($<s_var>1)->type; $$ = obj;}
    | IDENT '[' num ']' '[' num ']' {idFunc($1);Object obj; obj.type = findVariable($<s_var>1)->type; $$ = obj;}
    | IDENT '[' IDENT ']' {idFunc($1); Object obj; obj.type = findVariable($<s_var>1)->type; $$ = obj;idFunc($3);}
    | IDENT '[' IDENT ']' '[' IDENT ']' {idFunc($3); idFunc($6); Object obj; obj.type = findVariable($<s_var>1)->type; $$ = obj; } {idFunc($1);}
;

/* Assignment expressions */
Assign
    : Expression { valueAssChecker = true; } VAL_ASSIGN {right = true;} Expression { printf("EQL_ASSIGN\n"); assStore(); } {right = false;} { valueAssChecker = false; }
    | Expression { assLoad(); } ADD_ASSIGN {right = true;} Expression { printf("ADD_ASSIGN\n"); operGen("add"); assStore(); } {right = false;}
    | Expression { assLoad(); } SUB_ASSIGN {right = true;} Expression { printf("SUB_ASSIGN\n"); operGen("sub"); assStore(); } {right = false;}
    | Expression { assLoad(); } MUL_ASSIGN {right = true;} Expression { printf("MUL_ASSIGN\n"); operGen("mul"); assStore(); } {right = false;}
    | Expression { assLoad(); } DIV_ASSIGN {right = true;} Expression { printf("DIV_ASSIGN\n"); operGen("div"); assStore(); } {right = false;}
    | Expression { assLoad(); } REM_ASSIGN {right = true;} Expression { printf("REM_ASSIGN\n"); operGen("rem"); assStore(); } {right = false;}
    | Expression { assLoad(); } SHR_ASSIGN {right = true;} Expression { printf("SHR_ASSIGN\n"); operGen("shr"); assStore(); } {right = false;}
    | Expression { assLoad(); } SHL_ASSIGN {right = true;} Expression { printf("SHL_ASSIGN\n"); operGen("shl"); assStore(); } {right = false;}
    | Expression { assLoad(); } BAN_ASSIGN {right = true;} Expression { printf("BAN_ASSIGN\n"); operGen("and"); assStore(); } {right = false;}
    | Expression { assLoad(); } BOR_ASSIGN {right = true;} Expression { printf("BOR_ASSIGN\n"); operGen("or"); assStore(); } {right = false;}
    | Expression { assLoad(); } BXO_ASSIGN {right = true;} Expression { printf("BOX_ASSIGN\n"); operGen("xor"); assStore(); } {right = false;}
    | Expression { assLoad(); } INC_ASSIGN Expression { printf("INC_ASSIGN\n"); }
    | Expression { assLoad(); } DEC_ASSIGN Expression { printf("DEC_ASSIGN\n"); }
    ;


/* Numeric expressions */
num
    : SUB num { operGen("neg"); printf("NEG\n"); }
    | NOT num { printf("NOT\n"); }
    | BNT num { codeRaw("iconst_m1"); codeRaw("ixor"); printf("BNT\n"); }
    | FLOAT_LIT { stackFloat($1); printf("FLOAT_LIT %f\n", $1);Object obj; obj.type = OBJECT_TYPE_FLOAT; $$ = obj;}
    | INT_LIT { stackInt($1); printf("INT_LIT %d\n", $1); $$.type = OBJECT_TYPE_INT; }
    ;

/* Argument list for function calls */
ARGS
    : ARGS ',' ARG {countParam();}
    | ARG {countParam();}
    |
    ;

/* Individual argument in a function call */
ARG
    : STR_LIT { coutStackString($1); printf("STR_LIT \"%s\"\n", $1); Object obj; obj.type = OBJECT_TYPE_STR; $$ = obj; }
    | boolean { $$ = $1; Object obj; obj.type = $1.type; $$ = obj; }
    | num { $$ = $1; $$.type = $1.type; }
    | id {$$ = $1; Object obj; obj.type = $1.type; $$ = obj; }
    | CHAR_LIT { coutStackChar($1); }
    ;

/* Boolean expressions */
boolean
    : NOT boolean { notBool(); printf("NOT\n"); Object obj; obj.type = OBJECT_TYPE_BOOL; $$ = obj; }
    | BNT boolean { operGen("const_m"); printf("BNT\n"); Object obj; obj.type = OBJECT_TYPE_BOOL; $$ = obj; }
    | BOOL_LIT { stackBool($1); printf("BOOL_LIT %s\n", $1 ? "TRUE" : "FALSE"); Object obj; obj.type = OBJECT_TYPE_BOOL; $$ = obj; }
    ;

/* Identifier expressions */
id
    : SUB id { operGen("neg"); printf("NEG\n"); }
    | NOT id { printf("NOT\n"); }
    | BNT id { operGen("const_m"); printf("BNT\n"); }
    | IDENT { coutVar = true; idFunc($<s_var>1); Object obj; obj.type = findVarType($<s_var>1); $$ = obj; if(right || ifExp) {assLoad();} }
    ;

%%

/* C code section for supporting functions and utilities */
Editor is loading...
Leave a Comment