compiler.y 88
unknown
c_cpp
a year ago
14 kB
6
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 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 /* 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 { code("%sreturn", currentReturn); 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 ';' | 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 { code("iload %d", currentAddr); } SUB_ASSIGN { right = true; } Expression { printf("SUB_ASSIGN\n"); operGen("sub"); assStore(); } { right = false; } | Expression { code("iload %d", currentAddr); } 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 { codeRaw("newarray int"); isArrayInit = true; } '{' ARGS '}' { PrintArrParam();createVNoT($<s_var>1, VAR_FLAG_DEFAULT); isArrayInit = false; code("astore %d", ++arrayAddress); } | IDENT '[' num ']' '[' num ']' { codeRaw("multianewarray [[I 2"); createVNoT($<s_var>1, VAR_FLAG_DEFAULT); code("astore %d", arrayAddress); } | IDENT '[' num ']' { codeRaw("newarray int"); PrintArrParam();createVNoT($<s_var>1, VAR_FLAG_DEFAULT); code("astore %d", ++arrayAddress); } ; /* Print statement parameter list */ CoutParmListStmt : CoutParmListStmt SHL { codeRaw("getstatic java/lang/System/out Ljava/io/PrintStream;"); isCout = true; } Expression { coutArray = false; isCout = false; coutLoad(); pushFunInParm(&$<object_val>3); invokeFunc(); } | SHL { codeRaw("getstatic java/lang/System/out Ljava/io/PrintStream;"); isCout = true; } Expression { coutArray = false; isCout = false; 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); } {assLoad(); changeVType($<var_type>2); } | '(' VARIABLE_T ')' IDENT { idFunc($<s_var>4); } {assLoad(); changeVType($<var_type>2);} | '(' VARIABLE_T ')' num {changeVType($<var_type>2); } | '(' VARIABLE_T ')' '(' num ')'{changeVType($<var_type>2);} | IDENT '(' ARGS ')' {idFunc($1); printcall($1);} | IDENT '[' { assArray = true; getArrayVal = true; if(isCout){coutArray = true;} } num ']' { getArrayVal = false; } {idFunc($1); Object obj; obj.type = findVariable($<s_var>1)->type; $$ = obj;} | IDENT '[' { getArrayVal = true; } num ']' '[' num ']' { getArrayVal = false; } {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); } {idFunc($1);} ; /* Assignment expressions */ Assign : Expression { valueAssChecker = true; } VAL_ASSIGN {right = true;} Expression { printf("EQL_ASSIGN\n"); assStore(); } {right = false;} { valueAssChecker = false; assArray = 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 INC_ASSIGN Expression { printf("INC_ASSIGN\n"); } | Expression 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 { if(isArrayInit){ arrayinitStore($1); } else {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 { checkRightBool = true; 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 (isCout && hasRem){assLoad();} if(right || ifExp) {assLoad();} } ; %% /* C code section for supporting functions and utilities */
Editor is loading...
Leave a Comment