%{ #include #include #include #include "lvg.h" #include "tabelaHash.h" extern char * yytext; //Para os erros FILE *fp; Lvg lvg = NULL; int num_parametros = 0; int *parametros; int tamanho = 0; Variavel aux; char *stringLida = NULL; TabelaHash tabelaVar; int contCiclos = 0; int contIf = 0; int ciclosU = 0; int cf = 0; int iff = 0; int *cresce(int *array, int t1, int t2) { int *aux = (int *)malloc(sizeof(int) * t2); int i = 0; while(i < t1) { aux[i] = array[i]; i++; } tamanho += t2; return aux; } void adiciona_array(int valor) { if(num_parametros >= tamanho) parametros = cresce(parametros, tamanho, 50); parametros[num_parametros] = valor; num_parametros++; } void valor_variavel(int posicao, int tamanho, int indice) { if(tamanho == 1) fprintf(fp,"PUSHG %d\n", posicao); else{ fprintf(fp,"PUSHGP\n"); fprintf(fp,"PUSHI %d\n", posicao); fprintf(fp,"PADD\n"); if(indice != -1) fprintf(fp,"PUSHI %d\n", indice); else fprintf(fp,"SWAP\n"); fprintf(fp,"DUP 1\n"); fprintf(fp,"CHECK 0, %d\n", tamanho - 1); fprintf(fp,"LOADN\n"); } } %} %left BB EE %left IGUAL DIFERENTE '<' '>' MENORIGUAL MAIORIGUAL %left '+' '-' %left '*' '/' %token PROGRAM SAYL DECLARATIONS STATEMENTS INTEGER BOOLEAN ARRAY SIZE TRUE FALSE SAY ASK IF THEN ELSE WHILE AT BB EE AA IGUAL DIFERENTE MENORIGUAL MAIORIGUAL IN SAYS OPENWINDOW LINHA PONTO CIRCULO COR REFRESH CLEAR %token number %token string identifier %type Type Var Vars Inic_Var Value_Var Expression %type Array_Acess Add_Op Mul_Op Rel_Op While_Stat Else_Expression IfThenElse_Stat Constant Single_Expression Term Factor %type Variable %union { int num; char *nome; struct var { char *nome; int posicao; int tamanho; int indice; } variavel; } %% /* Program */ Liss : PROGRAM identifier '{' Body '}' {/*mostraidentificadores(ident);*/} ; Body : DECLARATIONS {fprintf(fp,"//--- DECALARACAO DE VARIAVEIS\n");} Declarations {fprintf(fp,"\n\n//--- INICIO PROGRAMA\n\nSTART\n");} STATEMENTS Statements {fprintf(fp,"STOP\n\n//--- FIM DO PROGRAMA\n");} ; /* Declarations */ Declarations : Declaration | Declarations Declaration ; Declaration : Variable_Declaration ; /* Declarations: Variables */ Variable_Declaration : Vars AT Type ';' {} //Por função que vai armazenar na tabela com tipo ; Vars : Var {$$ = $1;} | Vars ',' Var {$$ = $3;} ; Var : identifier Value_Var { adiciona(&lvg, $1, parametros, num_parametros); num_parametros = 0; tamanho = 0; free(parametros); } ; Value_Var : { parametros = (int *)malloc(sizeof(int)); parametros[0] = 0; num_parametros = 1; } | '=' Inic_Var {;} ; Type : INTEGER { //print(lvg); insereLvg(&tabelaVar, lvg, fp); elimina(&lvg); } | BOOLEAN { //print(lvg); insereLvg(&tabelaVar, lvg, fp); elimina(&lvg); } | ARRAY SIZE number { redimenciona(&lvg, $3); //print(lvg); insereLvg(&tabelaVar, lvg, fp); elimina(&lvg); } ; Inic_Var : Constant { parametros = (int *)malloc(sizeof(int)); parametros[0] = (int)$1; num_parametros = 1; } | Array_Definition {;} ; Constant : number {$$ = (int)$1;} | string {$$ = -1;} | TRUE {$$ = 1;} | FALSE {$$ = 0;} ; Array_Definition : '[' Array_Initialization ']' ; Array_Initialization : number {adiciona_array($1);} | Array_Initialization ',' number {adiciona_array($3);} ; /* Statements */ Statements : Statement | Statements Statement ; Statement : Graficos | Say_Statement | Ask_Statement | Assignment | Conditional_Statement | Iterative_Statement ; /* Parte grafica */ Graficos : OPENWINDOW '(' Variable ',' Variable ')'';' { valor_variavel($3.posicao, $3.tamanho, $3.indice); valor_variavel($5.posicao, $5.tamanho, $5.indice); fprintf(fp,"OPENDRAWINGAREA\n"); } | LINHA '(' Variable ',' Variable ',' Variable ',' Variable ')'';' { valor_variavel($3.posicao, $3.tamanho, $3.indice); valor_variavel($5.posicao, $5.tamanho, $5.indice); valor_variavel($7.posicao, $7.tamanho, $7.indice); valor_variavel($9.posicao, $9.tamanho, $9.indice); fprintf(fp,"DRAWLINE\n"); } | PONTO '(' Variable ',' Variable ')'';' { valor_variavel($3.posicao, $3.tamanho, $3.indice); valor_variavel($5.posicao, $5.tamanho, $5.indice); fprintf(fp,"DRAWPOINT\n"); } | CIRCULO '(' Variable ',' Variable ',' Variable ')'';' { valor_variavel($3.posicao, $3.tamanho, $3.indice); valor_variavel($5.posicao, $5.tamanho, $5.indice); valor_variavel($7.posicao, $7.tamanho, $7.indice); fprintf(fp,"DRAWCIRCLE\n"); } | COR '(' Variable ',' Variable ',' Variable ')'';' { fprintf(fp,"SETCOLOR\n"); } | REFRESH ';' {fprintf(fp,"REFRESH\n");} | CLEAR ';' {fprintf(fp,"CLEARDRAWINGAREA\n");} ; /* Assignment Statement */ Assignment : Variable '=' { if($1.tamanho != 1) { fprintf(fp,"DUP 1\n"); fprintf(fp,"CHECK 0, %d\n", $1.tamanho - 1); fprintf(fp,"PUSHGP\n"); fprintf(fp,"PUSHI %d\n", $1.posicao); fprintf(fp,"PADD\n"); fprintf(fp,"SWAP\n"); } } Expression ';' { if($1.tamanho != 1) fprintf(fp,"STOREN\n"); else fprintf(fp,"STOREG %d\n",$1.posicao); } ; Variable : identifier Array_Acess { aux = getVariavel(tabelaVar, $1); $$.nome = strdup(aux.nome); $$.posicao = aux.posicao; $$.tamanho = aux.tamanho; $$.indice = $2; } ; Array_Acess : {$$ = 0;} | '[' Single_Expression ']' {$$ = $2;} ; /* Expression */ Expression : Single_Expression {}//printf("\nVALOR4: %d\n", $1); $$=$1;} | Expression Rel_Op Single_Expression { if($2 == 0) fprintf(fp,"EQUAL\n"); if($2 == 1) fprintf(fp,"EQUAL\nNOT\n"); if($2 == 2) fprintf(fp,"INF\n"); if($2 == 3) fprintf(fp,"SUP\n"); if($2 == 4) fprintf(fp,"INFEQ\n"); if($2 == 5) fprintf(fp,"SUPEQ\n"); if($2 == 6) fprintf(fp,"\n"); if($2 == 7) fprintf(fp,"ADD\nPUSHI 1\nSUPEQ\n"); if($2 == 8) fprintf(fp,"MUL\nPUSHI 1\nEQUAL\n"); } ; /* Single_Expression */ Single_Expression : Term {$$ = $1;} | Single_Expression Add_Op Term { if($2 == 0) fprintf(fp,"ADD\n"); if($2 == 1) fprintf(fp,"SUB\n"); } ; /* Term */ Term : Factor {$$ = $1;}//printf("\nVALOR2: %d\n", $1); $$=$1;} | Term Mul_Op Factor { if($2 == 0) fprintf(fp,"MUL\n"); if($2 == 1) fprintf(fp,"DIV\n"); } ; /* Factor */ Factor : Constant { //printf("\nVALOR1: %d\n", $1); $$ = $1; fprintf(fp,"PUSHI %d\n", $1); } | Variable { if($1.tamanho == 1) fprintf(fp,"PUSHG %d\n", $1.posicao); else{ fprintf(fp,"PUSHGP\n"); fprintf(fp,"PUSHI %d\n", $1.posicao); fprintf(fp,"PADD\n"); if($1.indice != -1) fprintf(fp,"PUSHI %d\n", $1.indice); else fprintf(fp,"SWAP\n"); fprintf(fp,"DUP 1\n"); fprintf(fp,"CHECK 0, %d\n", $1.tamanho - 1); fprintf(fp,"LOADN\n"); } $$ = -1; } | '!' Expression | '+' Expression | '-' Expression | '(' Expression ')' ; /* Operators */ Add_Op : '+' {$$ = 0;} | '-' {$$ = 1;} ; Mul_Op : '*' {$$ = 0;} | '/' {$$ = 1;} | AA ; Rel_Op : IGUAL {$$ = 0;} | DIFERENTE {$$ = 1;} | '<' {$$ = 2;} | '>' {$$ = 3;} | MENORIGUAL {$$ = 4;} | MAIORIGUAL {$$ = 5;} | IN {$$ = 6;} | BB {$$ = 7;} | EE {$$ = 8;} ; /* IO Statements */ Say_Statement : SAY '(' Expression ')'';' {fprintf(fp,"WRITEI\n");} | SAYL '(' Expression ')'';' { fprintf(fp,"STRI\n"); fprintf(fp,"PUSHS \"\\n\"\n"); fprintf(fp,"SWAP\n"); fprintf(fp,"CONCAT\n"); fprintf(fp,"WRITES\n"); } | SAYS '(' string ')'';' { fprintf(fp,"PUSHS \"%s\"\n", $3); fprintf(fp,"WRITES\n"); } ; Ask_Statement : ASK '(' Variable ')'';' { if($3.tamanho != 1) { fprintf(fp,"DUP 1\n"); fprintf(fp,"CHECK 0, %d\n", $3.tamanho - 1); fprintf(fp,"PUSHGP\n"); fprintf(fp,"PUSHI %d\n", $3.posicao); fprintf(fp,"PADD\n"); fprintf(fp,"SWAP\n"); } fprintf(fp,"READ\n"); fprintf(fp,"ATOI\n"); if($3.tamanho != 1) fprintf(fp,"STOREN\n"); else fprintf(fp,"STOREG %d\n",$3.posicao); } ; /* Conditional & Iterative Statements */ Conditional_Statement : IfThenElse_Stat {iff++;} ; Iterative_Statement : While_Stat { fprintf(fp,"JUMP CICLO%d\n", $1); fprintf(fp,"FIM%d:\n", $1); cf++; if(cf == contCiclos - ciclosU) { cf = 0; ciclosU++; } } ; /* IfThenElse_Stat */ IfThenElse_Stat : IF Expression { contIf++; fprintf(fp,"JZ FIF%d\n", contIf); } THEN '{' Statements '}' Else_Expression { if($8 == 0) { fprintf(fp,"FIF%d:\n", contIf); } } ; Else_Expression : {$$ = 0;} | ELSE { fprintf(fp,"JUMP FIFE%d\nFIF%d:\n", contIf - iff, contIf - iff); } '{' Statements '}' { fprintf(fp,"FIFE%d:\n", contIf - iff); $$ = 1; } ; /* While_Stat */ While_Stat : WHILE {contCiclos++; fprintf(fp,"CICLO%d:\n", contCiclos);} '(' Expression ')' {fprintf(fp,"JZ FIM%d\n", contCiclos);} '{' Statements '}' {$$ = contCiclos - cf;} ; %% int yyerror(char *s) { fprintf(stderr, "%s: %s \n",s,yytext); return 1; } int main(int argc, char *argv[]) { inicia(&tabelaVar, 1000); if(argv[1] == NULL) fp = fopen("OMeuPrograma.vm", "w"); else { char *ficheiro = (char *)malloc(sizeof(char) * (strlen(argv[1]) + 20)); strcpy(ficheiro, argv[1]); ficheiro = strcat(ficheiro, ".vm"); fp = fopen(ficheiro, "w"); } yyparse(); fclose(fp); //print_tabela(tabelaVar); return 0; }