%{ #include "main.h" #define YYPARSE_PARAM _pPrg #define YYLEX_PARAM _pPrg int yylex( YYSTYPE* yylval, void* _pPrg); #define pPrg ((Program*)_pPrg) %} %pure_parser %defines %start program %token PROGRAM ENDPROGRAM BYREF BYVAL %token DIM AS NL %token MINUS /* operatori booleeni */ %left OR %left AND %nonassoc NOT /* operatori aritmetici */ %left ADD SUB %left MUL DIV %left CONCAT %nonassoc UMINUS %union { int TipVar; char* VarName; double FloatVal; VarList* PtrVar; long IntVal; GenNumNode* NumExprNode; char BoolVal; GenBoolNode* BoolExprNode; char* StringVal; GenStrNode* StrExprNode; GenInstElem* InstList; ElseIfCell* ElseIfLst; Param* ParamGen; GenFncElem* FncElem; TipParamSpec TipSpec; }; %token ID %type variabila %type param_spec %token TYPE_FLOAT TYPE_INT TYPE_STRING TYPE_BOOL %type tip /* date de tip string */ %token CT_STRING %token ID_STRING %type var_str %type expr_str /* date de tip numeric */ %token CT_FLOAT %token CT_INT %token ID_INT ID_FLOAT %type var_num %type expr_num /* date de tip boolean */ %token CT_TRUE CT_FALSE %token ID_BOOL %type var_bool %type expr_bool /* instructiuni */ %type instructiuni %type instructiune %type atrib_num %type atrib_bool %type atrib_str %token REPEAT UNTIL ENDREPEAT %type repeat_instr %token WHILE DO ENDWHILE %type while_instr %token IF THEN ELSEIF ELSE ENDIF %type elseif_list elseif_part %type else_part %type if_then_else %token FOR TO STEP NEXT %type step %type counter %type for_to_next %token BREAK EXIT %type break_instr %type exit_instr /* comparatii numerice */ %token LT LE GT GE EQ NE ASSIGN /* apeluri de functii */ %token FNC5 FNC6 FNC7 FNC8 %type fnc fnc_no_ret fnc_ret_num fnc_ret_bool /* functia print */ %token PRINT %type fnc_print_param2 %type fnc_print /* ZileLucratoare */ %token FNC_NUM_1 /* GrilaImpozitare */ %token FNC_NUM_2 /* AngajatCC */ %token FNC_BOOL_1 /* AngajatNegociere */ %token FNC_BOOL_2 /* ConfigDeducereGenrala */ %token FNC_BOOL_3 /* DeducereSuplimentara */ %token FNC_BOOL_4 /* ExecProgram */ %token EXECPROGRAM %type fnc_exprg_prm fnc_exprg_params_list fnc_exprg_params %type fnc_exprg %destructor {free($$);} fnc_exprg %% fnc_exprg_prm : ID_INT { $$ = NewParamIdInt($1);} | ID_FLOAT { $$ = NewParamIdFloat($1);} | ID_STRING { $$ = NewParamIdStr($1);} | ID_BOOL { $$ = NewParamIdBool($1);} | expr_num { $$ = NewParamExprNum($1);} | expr_str { $$ = NewParamExprStr($1);} | expr_bool { $$ = NewParamExprBool($1);} ; program : empty_lines PROGRAM '(' parametrii_formali ')' NL declaratii instructiuni ENDPROGRAM empty_lines { pPrg->pInstrList = $8;} ; empty_lines : /* empty */ | empty_lines NL ; parametrii_formali : /* empty */ | lista_parametrii ; lista_parametrii : parametru | lista_parametrii ',' parametru ; parametru : param_spec variabila AS tip { AddToParamList(pPrg,$2,$4,$1); } ; param_spec : /* empty */ { $$ = TipByVal;} | BYVAL { $$ = TipByVal;} | BYREF { $$ = TipByRef;} ; declaratii : /* empty */ | declaratii declaratie ; declaratie : DIM lista_variabile_tip NL ; lista_variabile_tip : variabila_tip | lista_variabile_tip ',' variabila_tip ; variabila_tip : variabila AS tip { AddToVarList(pPrg,$1,$3); } ; variabila : ID { $$ = $1 ;} ; tip : TYPE_INT { $$ = TYPE_INT; } | TYPE_FLOAT { $$ = TYPE_FLOAT; } | TYPE_STRING { $$ = TYPE_STRING; } | TYPE_BOOL { $$ = TYPE_BOOL; } ; instructiuni : /* empty */ { $$ = (GenInstElem*)NULL;} | instructiuni instructiune { $$ = AddInstToList($1,$2);} ; instructiune : /* empty */ NL { $$ = (GenInstElem*)NULL;} | atrib_num { $$ = $1; } | atrib_bool { $$ = $1; } | atrib_str { $$ = $1; } | while_instr { $$ = $1; } | repeat_instr { $$ = $1; } | if_then_else { $$ = $1; } | for_to_next { $$ = $1; } | break_instr { $$ = $1; } | exit_instr { $$ = $1; } | fnc NL { $$ = NewFncCallInst($1);} ; /*------------------------------------------------------------ * atribuire numerica , expresii numerice *------------------------------------------------------------*/ atrib_num : var_num ASSIGN expr_num NL {$$ = NewAssignNumInst($1,$3);} ; var_num : ID_INT { $$ = $1; } | ID_FLOAT { $$ = $1; } ; expr_num : expr_num ADD expr_num { $$ = NewOprNode(ADD,2,$1,$3);} | expr_num SUB expr_num { $$ = NewOprNode(SUB,2,$1,$3);} | expr_num MUL expr_num { $$ = NewOprNode(MUL,2,$1,$3);} | expr_num DIV expr_num { $$ = NewOprNode(DIV,2,$1,$3);} | '(' expr_num ')' { $$ = $2; } | SUB expr_num %prec UMINUS { $$ = NewOprNode(MINUS,1,$2);} | ID_INT { $$ = NewIdNode($1);} | ID_FLOAT { $$ = NewIdNode($1);} | CT_INT { $$ = NewCtIntNode($1);} | CT_FLOAT { $$ = NewCtFloatNode($1);} | CT_INT '%' { $$ = NewCtFloatNode((double)$1/100);} | CT_FLOAT '%' { $$ = NewCtFloatNode($1/100);} | fnc_ret_num { $$ = NewNumFncNode($1);} ; /*------------------------------------------------------------ * atribuire booleana , expresii booleene *------------------------------------------------------------*/ atrib_bool : var_bool ASSIGN expr_bool NL {$$ = NewAssignBoolInst($1,$3);} ; var_bool : ID_BOOL {$$ = $1} ; expr_bool : expr_num LT expr_num { $$ = NewBoolCmpNode(LT,$1,$3); } | expr_num LE expr_num { $$ = NewBoolCmpNode(LE,$1,$3); } | expr_num GT expr_num { $$ = NewBoolCmpNode(GT,$1,$3); } | expr_num GE expr_num { $$ = NewBoolCmpNode(GE,$1,$3); } | expr_num EQ expr_num { $$ = NewBoolCmpNode(EQ,$1,$3); } | expr_num NE expr_num { $$ = NewBoolCmpNode(NE,$1,$3); } | '(' expr_bool ')' { $$ = $2; } | expr_bool OR expr_bool { $$ = NewBoolOprNode(OR,2,$1,$3); } | expr_bool AND expr_bool { $$ = NewBoolOprNode(AND,2,$1,$3); } | NOT expr_bool { $$ = NewBoolOprNode(NOT,1,$2); } | ID_BOOL { $$ = NewIdBoolNode($1);} | CT_TRUE { $$ = NewCtBoolNode(TRUE);} | CT_FALSE { $$ = NewCtBoolNode(FALSE);} | fnc_ret_bool { $$ = NewBoolFncNode($1);} ; /*------------------------------------------------------------ * atribuire string , expresii string *------------------------------------------------------------*/ atrib_str : var_str ASSIGN expr_str NL { $$ = NewAssignStrInst($1,$3); } ; var_str : ID_STRING { $$ = $1 } ; expr_str : expr_str CONCAT expr_str { $$ = NewStrOprNode(CONCAT,2,$1,$3);} | '(' expr_str ')' { $$ = $2 } | ID_STRING { $$ = NewIdStrNode($1); } | CT_STRING { $$ = NewCtStrNode($1); } | fnc_ret_str { $$ = NewCtStrNode(""); } ; /*------------------------------------------------------------ * intructiunea " if then {elseif then} [else] " *------------------------------------------------------------*/ if_then_else : IF expr_bool THEN NL instructiuni elseif_list else_part ENDIF NL { $$ = NewIfThenElseInst($2,$5,$6,$7); } ; elseif_list : /* empty */ { $$ = (ElseIfCell*)NULL; } | elseif_list elseif_part { $$ = AddElseIfToList($1,$2); } ; elseif_part : ELSEIF expr_bool THEN NL instructiuni { $$ = NewElseIfCell($2,$5); } ; else_part : /* empty */ { $$ = (GenInstElem*)NULL; } | ELSE NL instructiuni { $$ = $3 } ; /*------------------------------------------------------------ * intructiunea " while " *------------------------------------------------------------*/ while_instr : WHILE expr_bool DO NL instructiuni ENDWHILE NL { $$ = NewWhileInst($2,$5);} ; /*------------------------------------------------------------ * intructiunea " repeat " *------------------------------------------------------------*/ repeat_instr : REPEAT NL instructiuni UNTIL expr_bool ENDREPEAT NL { $$ = NewRepeatInst($5,$3);} ; /*------------------------------------------------------------ * intructiunea " for to next " *------------------------------------------------------------*/ for_to_next : FOR counter ASSIGN expr_num TO expr_num step NL instructiuni NEXT NL { $$ = NewForToNextInst($2,$4,$6,$7,$9); } ; counter : ID_FLOAT { $$ = $1; } | ID_INT { $$ = $1; } ; step : /* empty */ { $$ = (GenNumNode*)NULL; } | STEP expr_num { $$ = $2; } ; /*------------------------------------------------------------ * intructiunea " break " *------------------------------------------------------------*/ break_instr : BREAK NL { $$ = NewBreakInst(); } ; /*------------------------------------------------------------ * intructiunea " exit " *------------------------------------------------------------*/ exit_instr : EXIT NL { $$ = NewExitInst(); } ; /*------------------------------------------------------------- * functii *------------------------------------------------------------*/ fnc : fnc_ret_str { $$ = (GenFncElem*)NULL;} | fnc_no_ret { $$ = $1;} | fnc_ret_bool { $$ = $1;} | fnc_ret_num { $$ = $1;} ; fnc_ret_num : FNC_NUM_1 '(' expr_num ',' expr_num ')' { $$ = NewFncNum1Elem($3,$5);} | FNC_NUM_2 '(' expr_num ')' { $$ = NewFncNum2Elem($3);} ; fnc_ret_bool : FNC_BOOL_1 '(' expr_num ',' expr_num ',' expr_num ',' expr_num ',' ID_FLOAT ',' ID_FLOAT ',' ID_FLOAT ',' ID_FLOAT ',' ID_FLOAT ',' ID_FLOAT ')' { $$ = NewFncBool1Elem($3,$5,$7,$9,$11,$13,$15,$17,$19,$21); } | FNC_BOOL_2 '(' expr_num ',' expr_num ',' expr_num ',' expr_num ',' ID_FLOAT ',' ID_FLOAT ',' ID_STRING ')' { $$ = NewFncBool2Elem($3,$5,$7,$9,$11,$13,$15); } | FNC_BOOL_3 '(' expr_num ',' expr_num ',' ID_FLOAT ',' ID_FLOAT ')' { $$ = NewFncBool3Elem($3,$5,$7,$9); } | FNC_BOOL_4 '(' expr_num ',' expr_num ',' expr_num ',' ID_FLOAT ')' { $$ = NewFncBool4Elem($3,$5,$7,$9); } ; fnc_ret_str : FNC5 '(' ID_INT ')' | FNC6 '(' ID_FLOAT ')' ; fnc_no_ret : FNC7 '(' ID_INT ')' { $$ = (GenFncElem*)NULL;} | FNC8 '(' ID_FLOAT ')' { $$ = (GenFncElem*)NULL;} | fnc_print { $$ = $1; } | fnc_exprg { $$ = $1; } ; fnc_print : PRINT '(' CT_STRING fnc_print_param2 ')' {$$ = NewPrintFncElem(NewCtStrNode($3),$4);} ; fnc_print_param2 : /* empty */ { $$ = (Param*)NULL; } | ',' expr_num { $$ = NewParamExprNum($2); } | ',' expr_str { $$ = NewParamExprStr($2); } | ',' expr_bool { $$ = NewParamExprBool($2); } ; /*----------------------------------. | Functia ExecPogram | '----------------------------------*/ fnc_exprg : EXECPROGRAM '(' CT_STRING fnc_exprg_params ')' { $$ = NewExecPrgElem($3,$4);} ; fnc_exprg_params : /* empty */ { $$ = (Param*)NULL;} | fnc_exprg_params_list { $$ = $1; } ; fnc_exprg_params_list : ',' fnc_exprg_prm { $$ = $2;} | fnc_exprg_params_list ',' fnc_exprg_prm { $$ = AddParamToParamList($1,$3); } ; /*------------------------------------------------------------------------------. | nonterminalul 'fnc_exprg_prm' este definit la inceputul fisierului | | deoarece apare un conflict reduce/reduce | '------------------------------------------------------------------------------*/ %% int yyerror( char * s) { OutputMsg ( "line %ld,program \"%s\": %s\n", pCurrentProgram->LineNo, pCurrentProgram->strPrgName, s ); OutputMsg("last token:\"%s\"\n",yytext); return 0; };