Você está na página 1de 14

ANALIZADOR LEXICO

LEXICO.CPP

Libreras:
# include<stdio.h>
# include<iostream.h>
# include<io.h>
# include<string.h>
# include<ctype.h>
# include<conio.h>

Declaracin de elementos y variables:


void aceptacion(int e);
void error(int e);
int busca_columna(char c);
void lexico();
void menu();
void acep();
void error();
int comp(char *c);
int comp2(char *c);
int buf_doble(int a);
int edo,col;
char cad,bufer[1002];

Para declarar una variable de tipo apuntador a archivo:


FILE *fp,*fe,*fa;

Para declarar una matriz:


int mat
[21][28]={{1,20,6,8,4,201,10,17,13,201,14,15,16,112,113,114,18,201,19,201,119,121,124,12
5,0,0,0,200},{1,2,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
100,100,100,100,100,100,100,100,100},{3,202,202,202,202,202,202,202,202,202,202,202,
202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202},{3,101,101,101,101,
101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
101,101},{4,102,102,102,4,5,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
102,102,102,102,102,102,102,102},{4,203,203,203,4,203,203,203,203,203,203,203,203,203,
203,203,203,203,203,203,203,203,203,203,203,203,203,203},{6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,204},{103,6,103,103,103,103,103,103,103,103,103,103,103,103,103,
103,103,103,103,103,103,103,103,103,103,103},{8,8,8,9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,204},{103,103,103,8,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
103,103,103,103,103,103,103,103,103,103},{104,104,104,104,104,104,104,11,104,104,104,
104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104},{11,11,11,11,11,
11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,205},{11,11,11,11,11,
11,105,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,205},{13,13,13,13,13,
13,13,13,13,105,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,205},{122,122,122,122
,122,122,122,122,122,122,122,122,122,106,122,122,122,122,122,122,122,122,122,122,122,

122,122,122},{109,109,109,109,109,109,109,109,109,109,109,109,107,108,109,109,109,109
,109,109,109,109,109,109,109,109,109},{110,110,110,110,110,110,110,110,110,110,110,11
0,110,111,110,110,110,110,110,110,110,110,110,110,110,110,110},{115,115,115,115,115,
115,115,116,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
115,115},{18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,206,117,18,18,18,18,18,18,18,
18,18,207},{19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,206,118,19,19,19,19,19,
19,19},{120,123,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120}};
char res[39][10]= {"ARRAY", "ELSE", "FOR", "EXIT", "REPEAT", "TO", "TRUE", "CHAR",
"BEGIN", "WRITELN", "IF", "NOT", "RETURN" ,"UNTIL", "FALSE", "STRING", "CASE",
"READLN", "LOOP", "OF", "PROCEDURE", "VAR", "DIV", "BYTE", "CONST", "ELSEIF",
"MODULE", "MOD", "BY", "WHILE", "INTEGER", "BOOLEAN", "DO", "END", "FUNCTION",
"RECORD", "THEN", "WITH", "REAL"};
char log[3][4] = {"AND","OR","NOT"};

CLASE PRINCIPAL:

void main()
{
char *archivo;
clrscr();
edo=0;
Pide la direccin del archivo que se desea analizar y lo almacena en el puntero archivo
cout<<"Indique la ruta y el nombres del archivo ";
cin>>archivo;

Pregunta si el archivo no se puede abrir. La funcin fopen() devuelve un puntero a


archivo. El tipo FILE est definido enstdio.h. Si fopen(), por la razn que sea, no puede
abrir el archivo, devolver un puntero a NULL.
El Modo r: Abre el archivo existente para lectura en modo secuencial. El archivo debe
existir previamente si se le aade la letra t es de texto.
if((fp=fopen(archivo,"rt"))==NULL){
Para cerrar un archivo se usa la funcin fclose()

fclose(fp);
cout<<"Nombre de archivo no valido" ;
getch();
}
En caso de que el archivo sea abierto, se llama al mtodo lxico y luego al mtodo men
else{
lxico
();
menu();
}
}

METODO LEXICO
void especifica mtodo que no retorna valor
void lexico(){
char *buf;
int l=0,i=0,c=1,p=1,a=0;

Copia no ms de n=301 caracteres de la cadena apuntada por s2= a la cadena


apuntada por s1=bufer
strncpy(bufer," ",301);
a=buf_doble(a);

El modo w de fopen: Crea un archivo para lectura/escritura en modo directo. Si el archivo


ya existe, se elimina y se crea de nuevo. Se puede leer y escribir en cualquier posicin del
archivo.

fa=fopen("c:\\acepta.txt","w");
fe=fopen("c:\\error.txt","w");
Realiza el proceso mientras no lea el smbolo peso ($)en el archivo
do{
edo=0;
i=0;
c=1;
p=1;
while((bufer[l]==' ') || (bufer[l]=='\n') || (bufer[l]=='\t'))
{

l++;
}
while((bufer[l]==';') || (bufer[l]=='+') || (bufer[l]=='-') || (bufer[l]=='=') || (bufer[l]==',')
|| (bufer[l]=='#') || (bufer[l]=='&'))
{
edo=0;
cad=bufer[l];
col=busca_columna(cad);
edo=mat[edo][col];
cout<<cad;
aceptacion(edo);
fputc(cad,fa);
fputc('\n',fa);
l++;
}
if(bufer[l]!='$'){
do{
cad=bufer[l];
if(cad!='@'){
col=busca_columna(cad);
edo=mat[edo][col];
if((edo>=0) && (edo<=20)){
buf[i]=cad;
i++;
}
l++;
}
else
{
cout<<bufer[l];
a=buf_doble(a);
if (a==0) l=0;
else l++;
}
}while((edo>=0) && (edo<=20));
if ((edo==105) || (edo==106) || (edo==117) || (edo==118) || (edo==116)
|| (edo==201) || (edo==203) || (edo==111) || (edo==107) || (edo==123)
|| (edo==108)){
buf[i]=cad;
i++;
}
for(int t=0; t<i; t++){
cout<<buf[t];
}
if(edo==102)
c=comp(buf);

if ((edo==102) && (c!=0))


p=comp1(buf);
if((edo==105) || (edo==201) || (edo==106) || (edo==203) || (edo==117) ||
(edo==118) || (edo==111) || (edo==108) || (edo==107) || (edo==116) ||
(edo==123)){
l++;
}
if((edo >= 100) && (edo <=125)){
if(c==0) cout<<" Palabra reservada \n";
if(p==0) cout<<" Operador logico \n";
if((c!=0) && (p!=0)) aceptacion(edo);
fwrite(buf,i,1,fa);
fputc('\n',fa);
}
else {
error(edo);
fwrite(buf,i,1,fe);
fputc('\n',fe);
}
getch();
strncpy(&buf[0]," ",i);
l--;
if ((cad=='\n') || (cad=='\t') || (cad==' ')){
l++;
}
if((bufer[l]==';') || (bufer[l]=='+') || (bufer[l]=='-') || (bufer[l]=='=') || (bufer[l]==',')
|| (bufer[l]=='#') || (bufer[l]=='&')){
edo=0;
cad=bufer[l];
col=busca_columna(cad);
edo=mat[edo][col];
cout<<cad;
aceptacion(edo);
fputc(cad,fa);
fputc('\n',fa);
l++;
}
getch();
}
else
cad=bufer[l];
if((l==0) && (cad=='$'))
{
cad=bufer[l];
col=busca_columna(cad);
edo=mat[edo][col];

error(edo);
}
}while(cad!='$');
cout<<"archivo analizado\n";
strncpy(&buf[0]," ",200);
strncpy(&bufer[0]," ",250);
fclose(fp);
fclose(fa);
fclose(fe);
getch();
}

METODO ACEPTACIN
void especifica mtodo que no retorna valor.
Recibe una variable de tipo entero y pregunta que asignacin tiene para imprimir especificacin de
token:
void aceptacion(int e)
{
switch(e)
{
case 100:printf(" CONSTANTE ENTERA\n");
break;
case 101:printf(" CONSTANTE REAL\n");
break;
case 102:printf(" IDENTIFICADOR \n");
break;
case 103:printf(" LETRERO ( ' O '' )\n");
break;
case 104:printf(" OPERADOR ARITMETICO DE DIVISION ( / )\n");
break;
case 105:printf(" COMENTARIOS\n");
break;
case 106:printf(" OPERADOR RELACIONAL DE ASIGNACION ( := )\n");
break;
case 107:printf(" OPERADOR RELACIONAL DIFERENTE ( <> )\n");
break;
case 108:printf(" OPERADOR RELACIONAL MENOR O IGUAL ( <= )\n");
break;
case 109:printf(" OPERADOR RELACIONAL MENOR ( < )\n");
break;
case 110:printf(" OPERADOR RELACIONAL MAYOR ( > )\n");
break;
case 111:printf(" OPERADOR RELACIONAL MAYOR O IGUAL ( >= )\n");
break;
case 112:printf(" OPERADOR RELACIONAL IGUAL ( = )\n");
break;

case 113:printf(" OPERADOR ARITMETICO DE SUMA ( + )\n");


break;
case 114:printf(" OPERADOR ARITMETICO DE RESTA ( - )\n");
break;
case 115:printf(" OPERADOR ARITMETICO DE MULTIPLICACION ( * )\n");
break;
case 116:printf(" OPERADOR ARITMETICO ** \n");
break;
case 117:printf(" DELIMITADOR PARENTESIS ( ) \n");
break;
case 118:printf(" DELIMITADOR CORCHETES [ ] \n");
break;
case 119:printf(" DELIMITADOR COMA ( , )\n");
break;
case 120:printf(" DELIMITADOR PUNTO ( . )\n");
break;
case 121:printf(" DELIMITADOR PUNTO Y COMA ( ; )\n");
break;
case 122:printf(" DELIMITADOR DOS PUNTOS ( : )\n");
break;
case 123:printf(" DELIMITADOR PUNTO-PUNTO ( .. )\n");
break;
case 124:printf(" DELIMITADOR GATO ( # )\n");
break;
case 125:printf(" DELIMITADOR AMPERSON ( & )\n");
break;
}
}
METODO ERROR
void especifica mtodo que no retorna valor.
Recibe una variable de tipo entero y pregunta que asignacin tiene para imprimir especificacin de
error:
void error(int e)
{
switch(e)
{
case 200:printf(" **ERROR** ARCHIVO VACIO\n");
break;
case 201:printf(" **ERROR** SIMBOLO DESCONOCIDO\n");
break;
case 202:printf(" **ERROR** CONSTANTE REAL MAL FORMADA; SE ESPERABA UN
DIGITO\n");
break;
case 203:printf(" **ERROR** IDENTIFICADOR, PALABRA RESERVADA O OPERADOR
RELACIONAL MAL FORMADO; SE ESPERABA LETRA O DIGITO\n");
break;

case 204:printf(" **ERROR** NO SE HA CERRADO EL LETRERO SE ESPERABA UNA '


O '' \n");
break;
case 205:printf(" **ERROR** NO SE HA CERRADO EL COMENTARIO;SE ESPERABA /
O } \n");
break;
case 206:printf(" **ERROR** YA FUE ABIERTO EL DELIMITADOR YA SEA
PARENTESIS O CORCHETE \n");
break;
case 207:printf(" **ERROR** NO SE HA CERRADO EL DELIMITADOR YA SEA ) O ]
)\n");
break;
}
}
METODO BUSCA_COLUMNA
int especifica mtodo que retornar valores enteros
Recibe una variable de tipo carcter, comprueba sin un carcter es alfabtico, isalpha es una
macro que verifica el caracter c pertenece al rango de letras (A a Z o a a z) de ser una letra
devuelve el entero 4 caso contrario pregunta que entero tiene para retornar de acuerdo al
carcter que ingresa, si no es un operador por defecto preguntar si es un digito, de ser as
retornara el entero 0:
int busca_columna(char c)
{
if(isalpha(c)) return(4);
switch(c)
{
case '.':return(1);
case '39':return(2);
case '"':return(3);
case '_':return(5);
case '/':return(6);
case '*':return(7);
case '{':return(8);
case '}':return(9);
case ':':return(10);
case '<':return(11);
case '>':return(12);
case '=':return(13);
case '+':return(14);
case '-':return(15);
case '(':return(16);
case ')':return(17);
case '[':return(18);
case ']':return(19);
case ',':return(20);
case ';':return(21);

case '#':return(22);
case '&':return(23);
case ' ':return(24);
case '\t':return(25);
case '\n':return(26);
case '$':return(27);
default:if(isdigit(c));
return(0);
}
}
METODO COMP
int especifica mtodo que retornar valores enteros
Recibe una variable de tipo puntero y pregunta que carcter tiene para retornar de acuerdo al
carcter valores enteros correspondientes:
La funcin strncmp compara dos cadenas pero solo hasta cierto nmero que es el tercer campo
que usa la funcin, si no son iguales devuelve un valor negativo, en caso de ser iguales devuelve el
valor cero, r se incrementar y como la matriz res solo tiene 39 valores el do while se terminar en
caso de ser estas dos cadenas iguales y no mayores al tamao de res
La funcin strupr convierte los caracteres a maysculas. Finalmente el mtodo devuelve la variable
a.
int comp(char *b)
{
int a,r=0;
do{
a=strncmp(strupr(b),res[r],10);
r++;
}while((r<=38) && (a!=0));
return(a);
}
METODO COMP1
int especifica mtodo que retornar valores enteros.
Recibe una variable de tipo puntero y pregunta que carcter tiene para retornar de acuerdo al
carcter valores enteros correspondientes:
La funcin strncmp compara dos cadenas pero solo hasta cierto nmero que es el tercer campo
que usa la funcin, si no son iguales devuelve un valor negativo, en caso de ser iguales devuelve el
valor cero, r se incrementar y como la matriz log solo tiene 3 valores el do while se terminar en
caso de ser estas dos cadenas iguales y no mayores al tamao de log
La funcin strupr convierte los caracteres a maysculas. Finalmente el mtodo devuelve la variable
a.
int comp1(char *b)
{
int a,r=0;
do{
a=strncmp(strupr(b),log[r],4);

r++;
}while((r<=2) && (a!=0));
return(a);
}
METODO BUF_DOBLE
int especifica mtodo que retornar valores enteros
int buf_doble(int a){
if(a==0){
bufer[0];
fread(bufer,250,1,fp);
bufer[250]='@';
a=1;
}
else
{
fread(bufer,250,1,fp);
bufer[501]='@';
a=0;
}
return(a);
}
METODO MENU
Despliega en pantalla un men de tres opciones, condicionando con un swicth el acceso a una sola
opcin a la vez
void menu()
{
int op;
do{
clrscr();
gotoxy(25,2); cout<<"MENU";
gotoxy(23,4); cout<<"1.- Token's validos";
gotoxy(23,5); cout<<"2.- Errores";
gotoxy(23,6); cout<<"3.- Salir";
gotoxy(22,8); cout<<"Seleccione una opcion ";
cin>>op;
switch(op){
case 1: acep(); break;
case 2: error(); break;
}
}while(op!=3);
}
METODO ACEP
void especifica mtodo que no retorna valor

void acep()
{
char car;
Abre para lectura el archivo de texto de una direccin especifica
fa=fopen("c:\\acepta.txt","rt");
clrscr();
do{

La funcin fgetc obtiene el carcter siguiente (si est presente), si se llega al final del
fichero la funcin devuelve EOF
car=fgetc(fa);
Imprime en pantalla el carcter ledo
cout<<car;
}while(!feof(fa));
Cierra el archivo fa
fclose(fa);
getch();
}
METODO ERROR
void especifica mtodo que no retorna valor
void error()
{
char car;
Abre para lectura el archivo de texto de una direccin especifica
fe=fopen("c:\\error.txt","rt");
clrscr();
do{

La funcin fgetc obtiene el carcter siguiente (si est presente), si se llega al final del
fichero la funcin devuelve EOF
car=fgetc(fe);
Imprime en pantalla el carcter ledo
cout<<car;
}while(!feof(fe));
Cierra el archivo fe
fclose(fe);
getch();
}
COMPILACIN

Primero se debe crear en el disco C un archivo de texto que contenga los tokens que se desean
analizar

Segundo
Hacer compilar el programa: se debe especificar la direccin y nombre del archivo, entonces el
programa comenzar a identificar cada lnea del archivo de texto.

Tercero
Al terminar de analizar el archivo, el programa mostrar un men con tres opcciones

Cuarto
La primera opcin nos muestra el contenido aceptado:

Quinto
La segunda opcin nos muestra los errores de contenido identificados:

Sexto
Para verificar, ingresamos al disco C y notaremos que se crearon dos archivos de texto que
previamente no existan uno con el nombre de error y otro con el nombre de acepta, ambos
archivos contendrn los token aceptados y los token identificados como errores respectivamente: