analizador lexico y sintactico
Post on 09-Mar-2015
239 Views
Preview:
TRANSCRIPT
Analizador Lexico y SintacticoEste 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
INCORRECTOStypedef 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 VALIDOStypedef 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 TIPOERROR2tipoerror2 strerrorr[100];tipoerror cerror[100];
//ESTRUCTURA (lista) PARA ALMASENAR LOS DATOS DE LA TABLA DE SIMBOLOtypedef 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 LEXEMAvoid Push2(TSimbolo *l, int v,char pt1[50],char pt2[50]);void imprime2(TSimbolo *l);// IMPRIME TODA LA lista(TABLA DE SIMBOLOint buscaTS2(TSimbolo *l,char *lex); //BUSCA SI SE ENCUENTRA EL LEXEMA A
INSERTAR EN LA lista
// FUNCIONES QUE SE UTLIZAN EN EL LA FUNCION LEXICOStipotoken reserv();tipotoken siguientetoken();void retrocede();char siguientechar();int cambestado();//DELVUELVE EL SIGUIENTE ESTADOvoid 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 ERRORint uu=0;//PARA QUE LOS ERRORESint 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 ERRORESuuu=0;int swww=0;int ind=0;//VARIABLE ENTERA PARA SABER NUMERO DEL INDICE DE LA TABLA DE
SIMBOLOcerror[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(); //RETROCEDErelac = 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 CONSTANTEcase 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; break;
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 ESTADOint cambestado() {
ji = lexema - 1;switch(auxestado) {
case 0:auxestado = 9; //SI ES IDENTIFICADORbreak;
case 9:auxestado = 12; //SI ES CONSTANTEbreak;
case 12: auxestado=0; ji=lexema++;
//DEVUELVE ESTADO 0 Y ADEMAS CONTROLAR ERRORESbreak;
}return(auxestado);
}
// FUNCION QUE RETROCEDE UNCARACTER ATRAS EN EL ARRGLE BUFFERvoid retrocede() {
ji =ji-1;return;
}
//FUNCION QUE LEE HASTA EL FINAL DEL ARCHIVO PARA ALMACENAR//CADA CADENA EN EL ARREGLO BUFFER[],LINEA A LINEAvoid 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); elseif(!strcmp(tokenaux,"Fin_if")) return(Fin_if); elseif(!strcmp(tokenaux,"Else")) return(Else); else if(!strcmp(tokenaux,"Hacer_mientras")) return(Hacer_mientras); elseif(!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 sintacticoifndef 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(); }
elseif (!strcmp(lexema,"-")){
sw = 1;fprintf(arch2,"Operp -> - Oper Operp\n");siguiente();oper();operp(); }
elseif (!strcmp(lexema,"*")){
sw = 1;fprintf(arch2,"Operp -> * Oper Operp\n");siguiente();oper();operp();}
elseif (!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; }
top related