Вы находитесь на странице: 1из 22

Analizador Lexico y Sintactico Este es el analizador lexico #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.

h> typedef enum { Entrada,Salida,XD,Inicio_programa,Fin_programa,Fin_hacer,If, Then, Else,Fin_if,Hacer_mientras, ID, CONST, OPREL, FIN } tipotoken; //ESTRUCTURA QUE GUARDA LOS ERRORES(SOLAMENTE LOS CARACTERES INCORRECTOS typedef struct errorL { int cuentaerrores; int lineaerror;//GUARDA EN DONDE OCURRE EL ERROR char charerror; // GUARDA EL CARACTER INCORRECTO }tipoerror; //ESTRUCTURA QUE GUARDA LOS IDENTIFICADORES NO VALIDOS typedef struct errorL2 { int lineaerror2; //GUARDA LINEA EN DONDE OCUURE EL ERROR char cadenaerror2[100]; //GUARDA EL IDENTIFICADOR NO VALIDO }tipoerror2; //AREGLOS DE TIPO LA ESTRUCTURA TIPOERROR2 tipoerror2 strerrorr[100]; tipoerror cerror[100]; //ESTRUCTURA (lista) PARA ALMASENAR LOS DATOS DE LA TABLA DE SIMBOLO typedef struct nodo { int indice; //CORRESPONDE AL INDICE DE CADA TOKEN char lexema[255]; //GUARDA EL LEXEMA char token[255]; //GUARDA EL TOKEN struct nodo *siguiente; } tipoNodo; typedef tipoNodo *TSimbolo; //PROTOTIPOS DE FUNCIONES ************************** /* FUNCIONES PARA LA lista2 */ //PUSH2 ALMACENA EN LA lista EL INDICE,TOKEN Y LEXEMA void Push2(TSimbolo *l, int v,char pt1[50],char pt2[50]); void imprime2(TSimbolo *l);// IMPRIME TODA LA lista(TABLA DE SIMBOLO int buscaTS2(TSimbolo *l,char *lex); //BUSCA SI SE ENCUENTRA EL LEXEMA A INSERTAR EN LA lista // FUNCIONES QUE SE UTLIZAN EN EL LA FUNCION LEXICOS tipotoken reserv(); tipotoken siguientetoken(); void retrocede(); char siguientechar(); int cambestado();//DELVUELVE EL SIGUIENTE ESTADO void genbuffer();// void cuadro(int inii,int inij,int an,int al,int text,int bak,int sombra); //VARIABLES GLOBALES********************************

FILE *archivo;//PUNTERO PARA EL ARCHIVO EL CUAL ESTA EL CODIGO FUENTE A ANALIZAR FILE *archivo2;//PUNTERO PARA EL ARCHIVO DONDE SE ALMACENALOS PARES DE TOKEN FILE *archivo3;//PUNTERO PARA EL ARCHIVO DONDE SE ALMACENALOS PARES DE TOKEN TSimbolo lista2 = NULL; //SE INICIALIZA EN NULL A LA lista //char c2; int lin=1;// VARIABLE PARA SABER DONDE SE ENCUENTRA LA LIEA DE ERROR int uu=0;//PARA QUE LOS ERRORES int uuu=0; int lexema = 0; int estado = 0; int auxestado= 0; int ji = 0; char tokenaux[255]; char buffer[255]; int relac; //IMPLEMENTACION DE LAS FUNCIONES DE LA lista****** void Push2(TSimbolo *pil, int v,char *pt1,char *pt2) { TSimbolo nuevo, previo, actual; nuevo = (TSimbolo)malloc(sizeof(tipoNodo)); nuevo->indice = v; strcpy(nuevo->lexema,pt1); strcpy(nuevo->token,pt2); nuevo->siguiente = NULL; previo = NULL; actual = *pil; while(actual) { previo = actual; actual = actual ->siguiente; } if(!previo) *pil = nuevo; else previo->siguiente = nuevo;

} void imprime2(TSimbolo *lista) { TSimbolo nodo; nodo = *lista; while(nodo!=NULL){ printf("%i ", nodo->indice); printf("%s ", nodo->lexema);

printf("%s \n", nodo->token); nodo = nodo->siguiente; }

int buscaTS(TSimbolo *p,char *lex){ TSimbolo pt; pt=*p; while(pt!=NULL){ if (!strcmp(pt->lexema,lex)) return pt->indice; pt = pt->siguiente; } return -1; }

int lexicos(char nr[50]) { lin=1; uu=0; uuu=0; lexema = 0; estado = 0; auxestado= 0; ji = 0; uu=0;//PARA QUE LOS ERRORES uuu=0; int swww=0; int ind=0;//VARIABLE ENTERA PARA SABER NUMERO DEL INDICE DE LA TABLA DE SIMBOLO cerror[0].cuentaerrores=0; tipotoken token; archivo2=fopen("d://pares.txt","w"); archivo3=fopen("d://token.txt","w"); archivo= fopen(nr, "r"); rewind(archivo); genbuffer(); ji = -1; for(;;){ estado = 0; auxestado = 0; token = siguientetoken(); lexema = ji + 1; swww=0; switch(token) { case ID:

if(-1==buscaTS(&lista2,tokenaux)) { Push2(&lista2,ind,tokenaux,"ID"); swww=1; } if(swww==0) { fprintf(archivo2, "(ID ,%i )\n",buscaTS(&lista2,tokenaux)); fprintf(archivo3, "ID\n");} else{ fprintf(archivo2, "(ID ,%i )\n",ind); fprintf(archivo3, "ID\n"); ind++; } break; case CONST: if(-1==buscaTS(&lista2,tokenaux)) { Push2(&lista2,ind,tokenaux,"CONST"); swww=1; } if(swww==0){ fprintf(archivo2, "(CONST ,%i )\n",buscaTS(&lista2,tokenaux)); fprintf(archivo3, "CONST\n");} else{ fprintf(archivo2, "(CONST ,%i )\n",ind); fprintf(archivo3, "CONST\n"); ind++; } break; case FIN: fclose(archivo); fclose(archivo2); fclose(archivo3); printf("FIN DEL ANALISIS LEXICO, PRESS Esc"); return 0;

case If: fprintf(archivo2,"(If, )\n"); fprintf(archivo3,"If\n"); break; case Then: fprintf(archivo2,"(Then, )\n"); fprintf(archivo3,"Then\n"); break; case Else: fprintf(archivo2,"(Else, )\n"); fprintf(archivo3,"Else\n"); break; case Inicio_programa:

fprintf(archivo2,"(Inicio_programa, )\n"); fprintf(archivo3,"Inicio_programa\n"); break; case Fin_programa: fprintf(archivo2,"(Fin_programa, )\n"); fprintf(archivo3,"Fin_programa\n"); break; case Entrada:

fprintf(archivo2,"(Entrada, )\n"); fprintf(archivo3,"Entrada\n"); break; case Salida: fprintf(archivo2,"(Salida, )\n"); fprintf(archivo3,"Salida\n"); break; case Fin_if: fprintf(archivo2,"(Fin_if, )\n"); fprintf(archivo3,"Fin_if\n"); break; case Fin_hacer: fprintf(archivo2,"(Fin_hacer, )\n"); fprintf(archivo3,"Fin_hacer\n");

break; case Hacer_mientras: fprintf(archivo2,"(Hacer_mientras, )\n"); fprintf(archivo3,"Hacer_mientras\n"); break; case XD: strerrorr[uuu].lineaerror2=lin; strcpy((strerrorr[uuu].cadenaerror2),tokenaux); uuu++; cerror[0].cuentaerrores++; break; case OPREL: switch (relac) { case 0: fprintf(archivo2,"( < , )\n"); fprintf(archivo3,"<\n"); break;

case 1: fprintf(archivo2,"( <= , )\n"); fprintf(archivo3,"<=\n"); break; case 2: fprintf(archivo2,"( = , )\n"); fprintf(archivo3,"=\n"); break; case 3: fprintf(archivo2,"( <> , )\n"); fprintf(archivo3,"<>\n"); break; case 4: fprintf(archivo2,"( > , )\n"); fprintf(archivo3,">\n"); break; case 5: fprintf(archivo2,"( >= , )\n"); fprintf(archivo3,">=\n"); break; case 6: fprintf(archivo2,"( ( , )\n"); fprintf(archivo3,"(\n"); break; case 7: fprintf(archivo2,"( ) , )\n"); fprintf(archivo3,")\n"); break; case 8: fprintf(archivo2,"( := , )\n"); fprintf(archivo3,":=\n"); break; case 9: fprintf(archivo2,"( + , )\n"); fprintf(archivo3,"+\n"); break; case 10: fprintf(archivo2,"( - , )\n"); fprintf(archivo3,"-\n"); break; case 11: fprintf(archivo2,"( * , )\n"); fprintf(archivo3,"*\n"); break; case 12: fprintf(archivo2,"( / , )\n"); fprintf(archivo3,"/\n"); break; } break; } }

} // FUNCIONES QUE IMPLEMENTA LOS AUTOMATAS // EN LA CUAL tipotoken siguientetoken() { //int uu=0;//PARA QUE LOS ERRORES //int uuu=0;

int g=1,n=0; char c,c2; for(;;) { switch (estado) { case 0: c = siguientechar(); if ((c == ' ') || (c == '\n')) { estado = 0; lexema++; if(c=='\n') lin++; } else if (c ==(char)EOF) { printf("NUMERO DE ERRORES LEXICOS: %d ",cerror[0].cuentaerrores); for(g=0;g<uu;g++){ if(g==17) {

g=0; } printf("ERROR LEXICO %d: %c EN LINEA %d ",g,cerror[g].charerror,cerror[g].lineaerror); } for(n=0;n<uuu;n++){ if(g==17) {

g=0; }

printf("ERROR LEXICO %d: %s EN LINEA %d ",g,strerrorr[n].cadenaerror2,strerrorr[n].lineaerror2); g++; } if(g==17) {

g=0; } return(FIN);} else if (c == '<') estado = 1; else if (c == '=')

estado = 5; else if (c == '>') estado = 6; else if (c == '(') estado = 18; else if (c == ')') estado = 19; else if (c == ':') estado = 20; else if (c=='+') estado=22; else if (c=='-') estado=24; else if (c=='*') estado=26; else if (c=='/') estado=28; else estado =cambestado(); break; case 1: c = siguientechar(); if (c == '=') estado = 2; else if (c == '>') estado = 3; else estado = 4; break; case 2: relac = 1; return(OPREL); case 3: relac = 3; return(OPREL); case 4: retrocede(); //RETROCEDE relac = 0; return(OPREL); case 5: relac = 2; return(OPREL); case 6: c = siguientechar(); if (c == '=') estado = 7; else estado = 8; break; case 7: relac = 5; return(OPREL);

case 8: retrocede(); relac = 4; return(OPREL); //estados para<,>=>>etc. //*************************************** case 9: int l; l=0; tokenaux[l]='\0'; if (isalpha(c)) { //SI ES LETRA tokenaux[l]=c; estado=10; } else estado = cambestado(); break; case 10: c = siguientechar(); if ((isalpha(c))||(c=='_')||(isdigit(c))){ tokenaux[l++]=c; estado = 10; } else estado = 11; break; case 11: tokenaux[l++]='\0'; retrocede(); return(reserv());

//DIGITO O NUMERO O CONSTANTE case 12: l=0; tokenaux[l]='\0'; c = siguientechar(); if (isdigit(c)) { tokenaux[l++]=c; estado = 13; } else { cerror[uu].charerror=c; cerror[uu].lineaerror=lin; cerror[0].cuentaerrores++; uu++; estado = cambestado(); } break; case 13: c = siguientechar(); if (isdigit(c)){ tokenaux[l++]=c; estado = 13; }

else estado =17; case 17: retrocede(); tokenaux[l++]='\0'; return(CONST); //retorna constante case 18 : relac = 6; return(OPREL); case 19: relac = 7; return(OPREL); case 20: c2=c; c = siguientechar(); if (c == '=') estado = 21; else{ cerror[uu].charerror=c2; cerror[uu].lineaerror=lin; cerror[0].cuentaerrores++; uu++; estado = 9; } case 21:relac = 8; return(OPREL); case 22: relac = 9; return(OPREL); case 24: relac = 10; return(OPREL); case 26: relac = 11; return(OPREL); case 28: relac = 12; return(OPREL); } } } //FUNCION QUE BA CAMBIANDO ESTADO int cambestado() { ji = lexema - 1; switch(auxestado) { case 0: auxestado = 9; //SI ES IDENTIFICADOR break; break;

case 9: auxestado = 12; //SI ES CONSTANTE break;

case 12: auxestado=0; ji=lexema++; //DEVUELVE ESTADO 0 Y ADEMAS CONTROLAR ERRORES break; } return(auxestado); }

// FUNCION QUE RETROCEDE UNCARACTER ATRAS EN EL ARRGLE BUFFER void retrocede() { ji =ji-1; return; }

//FUNCION QUE LEE HASTA EL FINAL DEL ARCHIVO PARA ALMACENAR //CADA CADENA EN EL ARREGLO BUFFER[],LINEA A LINEA void genbuffer() { int i; char c; i= 0; while (!feof(archivo)) { fscanf(archivo, "%c", &c); buffer[i++] = c; if (c == '\n') break; } buffer[i] = '\0'; }

//ESTA FUNCIO LEE EL SIGUIENTE CHAR QUE ESTA ALMACENADO EN //ARREGLO BUFFER[] char siguientechar() { ji++; if (buffer[ji] == '\0') { if (!feof(archivo)) { genbuffer(); ji = 0; lexema = 0; } else

return((char)EOF); } return(buffer[ji]); } //ESTA FUNCION COMPARA SI ES UNA PALABRA RESERBADA //O UN IDENTIFICADOR CUALQUIERA. tipotoken reserv() { int i=0,s; if(!strcmp(tokenaux,"If")) return(If); else if(!strcmp(tokenaux,"Then")) return(Then); else if(!strcmp(tokenaux,"Inicio_programa")) return(Inicio_programa); else if(!strcmp(tokenaux,"Fin_programa")) return(Fin_programa); else if(!strcmp(tokenaux,"Entrada")) return(Entrada); else if(!strcmp(tokenaux,"Salida")) return(Salida); else if(!strcmp(tokenaux,"Fin_if")) return(Fin_if); else if(!strcmp(tokenaux,"Else")) return(Else); else if(!strcmp(tokenaux,"Hacer_mientras")) return(Hacer_mientras); else if(!strcmp(tokenaux,"Fin_hacer")) return(Fin_hacer); else { while ((tokenaux[i])!='\0') { if(isupper(tokenaux[i])) s=1; i++; } } if (s==1) return(XD); else return(ID); } //IMPRIMERO LOS PARES (TOKEN,ATRIBUTOS),GUARDADOS EN EL ARCHIVO2(C:\PARES.TXT) void imprimepares() {

char par; int xx=30,yy=4; archivo2= fopen("d://pares.txt", "r"); if (archivo2 == NULL) { printf("NO ES POSIBLE ABRIR L ARCHIVO" ); exit(1); } while (!feof(archivo2)) {

par=getc(archivo2); printf("%c",par); } fclose(archivo2); }

Y este es el analizador sintactico ifndef SINTACTICO_H #define SINTACTICO_H #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h>

class Sintactico { public: Sintactico(FILE *, FILE *); int analizar(); void print(); private: void OperRelacionales(); void instruccion(); void error(); void oper(); void condicional(); void operp(); void instruccion_if(); void instruccion_ifp(); void instruccion_asign(); void instruccion_hacer(); void instruccion_inicio_fin(); void instruccion_entrada(); void instruccion_salida(); void siguiente(); void instruccionp(); void desicion();

int numParentesis; char lexema[50]; FILE *arch; FILE *arch2; int opcion ; }; #endif

#include "sintactico.h" /*contructor*/ Sintactico::Sintactico(FILE *myArch1, FILE *myArch2) { arch =myArch1; arch2 = myArch2; numParentesis=0; opcion = -1; }

/*Funcion que manda mensaje de erroror*/ void Sintactico::error(){ printf ("erroror de sintaxis"); fclose(arch); fclose(arch2); abort(); } /*Funcion que me proporciona el siguiente lexema */ void Sintactico::siguiente(){ if (!feof(arch)) fscanf (arch,"\n%s",lexema); if(opcion==0) opcion=5; }

/*Funciones que trabajan con Operasiones aritmericas*/ void Sintactico::oper(){ if (!strcmp(lexema,"ID")) { fprintf(arch2,"Oper -> ID Operp\n"); uu: siguiente(); if(!strcmp(lexema,")")) { numParentesis--; goto uu; } operp(); } if (!strcmp(lexema,"CONST")) {

fprintf(arch2,"Oper -> CONST Operp\n"); uur: siguiente(); if(!strcmp(lexema,")")) { numParentesis--; goto uur; } operp(); } }

void Sintactico::operp() { bool sw = 0; if (!strcmp(lexema,"+")){ sw = 1; fprintf(arch2,"Operp -> + Oper Operp\n"); siguiente(); oper(); operp(); } else if (!strcmp(lexema,"-")){ sw = 1; fprintf(arch2,"Operp -> - Oper Operp\n"); siguiente(); oper(); operp(); } else if (!strcmp(lexema,"*")){ sw = 1; fprintf(arch2,"Operp -> * Oper Operp\n"); siguiente(); oper(); operp(); } else if (!strcmp(lexema,"/")){ sw = 1; fprintf(arch2,"Operp -> / Oper Operp\n"); siguiente(); oper(); operp(); } if (sw == 0) fprintf(arch2,"Operp -> epsilon\n"); }

/*Funciones que trabajan con operadores relacionales*/ void Sintactico::OperRelacionales(){ oper();

if (!strcmp(lexema,"=")) { fprintf(arch2,"OperRelacionales -> Oper = Oper\n"); uy: siguiente(); if(!strcmp(lexema,"(")) {numParentesis++; goto uy;} oper(); } else if (!strcmp(lexema,">")) { fprintf(arch2,"OperRelacionales -> Oper > Oper\n"); gg:siguiente(); if(!strcmp(lexema,"(")) {numParentesis++; goto gg; } oper(); } else if (!strcmp(lexema,"<")) { fprintf(arch2,"OperRelacionales -> Oper < Oper\n"); uyy: siguiente(); if(!strcmp(lexema,"(")) {numParentesis++; goto uyy;} oper(); } else if (!strcmp(lexema,">=")) { fprintf(arch2,"OperRelacionales -> Oper >= Oper\n"); uyyy: siguiente(); if(!strcmp(lexema,"(")) {numParentesis++; goto uyyy;} oper(); } else if (!strcmp(lexema,"<=")) { fprintf(arch2,"OperRelacionales -> Oper <= Oper\n"); uf: siguiente(); if(!strcmp(lexema,"(")) {numParentesis++; goto uf;} oper(); } else if (!strcmp(lexema,"<>")) { fprintf(arch2,"OperRelacionales -> Oper <> Oper\n"); ue: siguiente(); if(!strcmp(lexema,"(")) {numParentesis++; goto ue;} oper();

} } void Sintactico::condicional(){ fprintf(arch2,"condicional -> OperRelacionales\n"); OperRelacionales(); } /*Funciones para la instruccionruccion if*/ void Sintactico::instruccion_if(){ if (!strcmp(lexema,"If")) { fprintf(arch2,"instruccion-if -> If condicional Then instruccion instruccion_ifp\n"); j:siguiente(); if(!strcmp(lexema,"(")) { numParentesis++; goto j; } condicional(); if (!strcmp(lexema,"Then")) { siguiente(); desicion(); instruccion(); instruccion_ifp(); desicion(); } else {

printf("error sintactico , falta Then"); abort(); } } } void Sintactico::instruccion_ifp() { if (!strcmp(lexema,"Fin_if")) { fprintf(arch2,"instruccion-ifp -> Fin_if\n"); siguiente(); } else if (!strcmp(lexema,"Else")) { fprintf(arch2,"instruccion-ifp -> Else instruccion Fin_if\n"); siguiente(); desicion(); instruccion(); if (!strcmp(lexema,"Fin_if")) siguiente(); else {

printf("error sintactico, falta Fin_if"); abort(); } } } /*Funcion para la signacion*/ void Sintactico::instruccion_asign(){ if (!strcmp(lexema,"ID")){ fprintf(arch2,"instruccion-asign -> ID := Oper\n"); siguiente(); if (!strcmp(lexema,":=")) { siguiente(); oper();} else {

printf("error sintactico, en la asignacion"); abort(); } } }; /*Funcion para el ciclo mientras*/ void Sintactico::instruccion_hacer(){ if (!strcmp(lexema,"Hacer_mientras")){ fprintf(arch2,"instruccion-hacer -> Hacer Mientras condicional instruccion Fin_hacer\n"); siguiente(); condicional(); desicion(); instruccion(); if (!strcmp(lexema,"Fin_hacer")) siguiente(); else { printf("error sintactico, falta Fin_hacer"); abort(); }

} } /*Funcion para la,instruccionruccion inicio y fin del programa*/

void Sintactico::instruccion_inicio_fin(){ if (!strcmp(lexema,"Inicio_programa")){ fprintf(arch2,"instruccion-inicio-fin -> Inicio_programa instruccion Fin_programa\n"); siguiente(); desicion(); instruccion(); if (!strcmp(lexema,"Fin_programa")) siguiente(); else { printf("error sintactico, falta Fin_programa"); abort();} } else { printf("error sintactico, falta Inicio_programa"); abort(); } } /*Funcion para la intruccion entrada*/ void Sintactico::instruccion_entrada(){ if (!strcmp(lexema,"Entrada")){ fprintf(arch2,"instruccion-Entrada -> Entrada (ID)\n"); siguiente(); if (!strcmp(lexema,"(")){ siguiente(); if (!strcmp(lexema,"ID")){ siguiente(); if (!strcmp(lexema,")")){opcion=5; siguiente();} else { printf("error sintactico, falta )"); abort();} } else { printf("error sintactico, falta identificador"); abort(); }

} else {

printf("error sintactico, falta("); abort();} } }

/*Funcion para la instruccionruccion de salida*/ void Sintactico::instruccion_salida(){ if (!strcmp(lexema,"Salida")){ fprintf(arch2,"instruccion-Salida -> Salida (?)\n"); siguiente(); if (!strcmp(lexema,"(")){ siguiente(); if (!strcmp(lexema,"ID")){ siguiente(); if (!strcmp(lexema,")")){ siguiente(); opcion=5;} else { printf("error sintactico, falta )"); abort();} } else { printf("error sintactico, falta identificador"); abort();}

} else { printf("error sintactico, falta ("); abort();} } }

/*Funciones que trabajan con las instruccionrucciones del lenguaje*/ void Sintactico::instruccion(){ switch (opcion){ case 0: fprintf(arch2,"instruccion -> instruccion-Asign instruccionp\n"); instruccion_asign(); instruccionp(); break; case 1: fprintf(arch2,"instruccion -> instruccion-Entrada instruccionp\n"); instruccion_entrada(); instruccionp(); break;

case 2: fprintf(arch2,"instruccion -> instruccion-Salida instruccionp\n"); instruccion_salida(); instruccionp(); break; case 3: fprintf(arch2,"instruccion -> instruccion-If instruccionp\n"); instruccion_if(); instruccionp(); break; case 4: fprintf(arch2,"instruccion -> instruccion-Hacer instruccionp\n"); instruccion_hacer(); instruccionp(); break; case 5: break; default: error(); }; };

void Sintactico::instruccionp(){ desicion(); if (opcion == 5) fprintf(arch2,"instruccionp -> epsilon \n"); instruccion(); } /* Funcion que decide segun la entrada que produccion OperRelacionalesandir*/ void Sintactico::desicion(){ if (!strcmp(lexema,"ID")) opcion=0; if (!strcmp(lexema,"Entrada")) opcion=1; if (!strcmp(lexema,"Salida")) opcion=2; if (!strcmp(lexema,"If")) opcion=3; if (!strcmp(lexema,"Hacer_mientras")) opcion=4; } void Sintactico::print() { FILE *arch3; char par; arch3=fopen("d://sintact.txt", "r"); while (!feof(arch3)) { par=getc(arch3); printf("%c",par); } fclose(arch3); } /*Funcion que realiza el analisis*/ int Sintactico::analizar(){ fscanf (arch,"%s",lexema); instruccion_inicio_fin(); if(numParentesis!=0){ printf("erroror : parentesis desbalanceados"); fclose(arch); fclose(arch2); return 0;

} printf("Codigo sintacticamente correcto!"); fclose(arch); fclose(arch2); return 0; }

Вам также может понравиться