%{
/*
librerias y variables
prototipos
*/
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include <stdlib.h>
void imprimeTablaCodigo() ;
void imprimeTablaSimbolo() ;
int genVarTemp();
void generaCodigo(int op,int a1,int a2,int a3);
int localizaSimbolo(char *lexema,int token);
void yyerror(char *s);
int yylex();
char lexema[100];
typedef struct {
int token;
char nombre[100];
double valor;
}TipoTablaSim;
TipoTablaSim tablaSimb[1000];
typedef struct {
int op;
int a1;
int a2;
int a3;
}TipoTablaCodigo;
TipoTablaCodigo tablaCod[1000];
int cx=-1;
int nSim=0;
int nvarTemp=1;
%}
%token MIENTRAS ID NUM SI HACER SINO IMPRIME
%token ASIGNAR SUMAR RESTAR MULTIPLICAR DIVISION COMPMAYOR SALTAR SALTARF IMPRIMIR
%%
/*gramatica*/
main:listainst;
listainst:listainst inst;
listainst:;
cond: expr '>' expr { int i=genVarTemp(); generaCodigo(COMPMAYOR,i ,$1 ,$3 );$$=i;};
inst: ID {int i=localizaSimbolo(lexema,ID); $$= i;} '=' expr {generaCodigo(ASIGNAR,$2,$4,'-');} ;
inst: HACER bloque MIENTRAS'(' expr ')'';';
inst: IMPRIME factor {generaCodigo(IMPRIMIR,$2,'-','-');} ;
inst: MIENTRAS '(' {$$=cx+1;} cond {generaCodigo(SALTARF,'?',$4,'-');$$=cx;} ')' bloque {generaCodigo(SALTAR,$3,'-','-');$$=cx;} { tablaCod[$5].a1=cx+1;};
inst:SI '('cond ')' {generaCodigo(SALTARF,'?',$3,'-');$$=cx;} bloque {generaCodigo(SALTAR,'?','-','-');$$=cx;} SINO {tablaCod[$5].a1=cx+1;}bloque { tablaCod[$7].a1=cx+1;};
bloque:'{'listainst '}' | inst ;
expr: expr '+' term {int i=genVarTemp(); generaCodigo(SUMAR,i,$1,$3);$$=i;};
expr: expr '-' term{int i=genVarTemp(); generaCodigo(RESTAR,i,$1,$3);$$=i;};
term:term '*' factor{int i=genVarTemp(); generaCodigo(MULTIPLICAR,i,$1,$3);$$=i;};
term:term '/' factor{int i=genVarTemp(); generaCodigo(DIVISION,i,$1,$3);$$=i;};
term:factor;
expr:term;
factor:'('expr')'{$$=$2;};
factor:ID {int i=localizaSimbolo(lexema,ID); $$= i;};
factor:NUM{int i=localizaSimbolo(lexema,NUM); $$= i;};
%%
void interpreta(){
int i,op, a1,a2,a3;
for(i=0;i<=cx;i++){
op=tablaCod[i].op;
a1=tablaCod[i].a1;
a2=tablaCod[i].a2;
a3=tablaCod[i].a3;
if(op==IMPRIMIR){
printf("%lf\n",tablaSimb[a1].valor);
}
if(op==DIVISION){
tablaSimb[a1].valor=tablaSimb[a2].valor/tablaSimb[a3].valor;
}
if(op==MULTIPLICAR){
tablaSimb[a1].valor=tablaSimb[a2].valor*tablaSimb[a3].valor;
}
if(op==RESTAR){
tablaSimb[a1].valor=tablaSimb[a2].valor-tablaSimb[a3].valor;
}
if(op==SUMAR){
tablaSimb[a1].valor=tablaSimb[a2].valor+tablaSimb[a3].valor;
}
if(op==ASIGNAR){
tablaSimb[a1].valor=tablaSimb[a2].valor;
}
if(op==COMPMAYOR){
printf("compara");
if(tablaSimb[a2].valor>tablaSimb[a3].valor){
tablaSimb[a1].valor=1;
}
else{
tablaSimb[a1].valor=0;
}
}
if(op==SALTARF){
if(tablaSimb[a2].valor==0){
i=a1 -1;
}
}
if(op==SALTAR){
i=a1-1;
}
}
}
int genVarTemp(){
char nomb[10];
sprintf(nomb,"temp_%d",nvarTemp);
nvarTemp++;
return localizaSimbolo(nomb,ID);
}
void imprimeTablaSimbolo() {
int i;
printf("i\tNombre\ttoken\tvalor\n");
for(i=0;i<nSim;i++){
printf("%d\t%s\t%d\t%.2lf\n", i,tablaSimb[i].nombre,tablaSimb[i].token,tablaSimb[i].valor);
}
}
int localizaSimbolo(char *lexema,int token){
int i;
for(i=0;i<nSim;i++){
if (!strcmp(lexema,tablaSimb[i].nombre))
return i;
}
tablaSimb[nSim].token=token;
if(token ==NUM){
tablaSimb[nSim].valor=atof(lexema);
}
else
tablaSimb[nSim].valor=0.0;
strcpy(tablaSimb[nSim].nombre,lexema);
nSim++;
return nSim-1;
}
/*codigo C*/
/*análisis léxico*/
int yylex(){
char c;int i;
c=getchar();
while(c==' ' || c=='\n' || c=='\t'){ c=getchar(); if(c!=' ' && c!='\n' && c!='\t') break;}
if(c=='#') return 0;
if(isalpha(c)){
i=0;
do{
lexema[i++]=c;
c=getchar();
}while(isalnum(c));
ungetc(c,stdin);
lexema[i++]='\0';
if(!strcmp(lexema,"if")) return SI;
if(!strcmp(lexema,"while")) return MIENTRAS;
if(!strcmp(lexema,"do")) return HACER;
if(!strcmp(lexema,"else")) return SINO;
if(!strcmp(lexema,"print")) return IMPRIME;
return ID;
}
if(isdigit(c)){
i=0;
do{
lexema[i++]=c;
c=getchar();
}while(isdigit(c));
ungetc(c,stdin);
lexema[i++]='\0';
return NUM;
}
return c;
}
void generaCodigo(int op,int a1,int a2,int a3){
cx++;
tablaCod[cx].op=op;
tablaCod[cx].a1=a1;
tablaCod[cx].a2=a2;
tablaCod[cx].a3=a3;
}
void imprimeTablaCodigo() {
int i;
printf("i\tOP\ta1\ta2\ta3\n");
for(i=0;i<=cx;i++){
printf("%d\t%d\t%d\t%d\t%d\n", i,tablaCod[i].op,tablaCod[i].a1,tablaCod[i].a2,tablaCod[i].a3);
}
}
void yyerror(char *s){
fprintf(stderr,"%s\n",s);
}
int main(){
if(!yyparse()){
imprimeTablaSimbolo() ;
imprimeTablaCodigo();
interpreta();
imprimeTablaSimbolo() ;
printf("cadena válida");
}
else{
printf("cadena inválida");
}
return 0;
}