Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
6.3 kB
3
Indexable
%{

/*
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;
}