• Viernes 8 de Noviembre de 2024, 16:35

Autor Tema:  Analizador Lexico Simplificado  (Leído 9385 veces)

Tom Cyberspirit

  • Nuevo Miembro
  • *
  • Mensajes: 3
    • Ver Perfil
Analizador Lexico Simplificado
« en: Martes 24 de Mayo de 2011, 17:46 »
0
¿Alguien me puede facilitar el código en c++  o Java de un Analizador Léxico simplificado?
Hola a todos. Si alguien me puede facilitar su código, le agradeceré infinitamente.

Les dejo los requisitos que debe llevar el programa:

Para nuestro proyecto utilizaremos un lenguaje hipotético que se conformará de lo siguiente:

Palabras reservadas: { Inicio, Fin, Var }
Operadores aritméticos: { +, *, /, -, = }
Números : { reales, enteros}
Identificadores: ver Gramáticas regulares
Palabra NO valida: Error, cadena que no sea de alguno de los tipos anteriores

Hasta aquí debemos concluir que nuestro programa clasificará cada cadena de nuestra entrada como uno de los cinco elementos anteriores.
Ejemplo
Si tenemos como entrada las siguientes cadenas

var  a, casa, 1fin
inicio
  algo = 50 + 20.5
fin

La salida esperada en pantalla sería

Palabra            Clasificación
var               Palabra reservada
a               Identificador
casa               Identificador
1fin               Error, Palabra NO valida
inicio               Palabra reservada
algo               Identificador
=               Operador
50               Número entero
+               Operador
20.5               Número real
fin               Palabra reservada

Como programar
Un objetivo importante de este proyecto es recalcar la aplicación practica de la materia por lo que nuestro programa lo realizaremos tomando como base el comportamiento de las gramáticas regulares ya que con ellas podemos diseñar lenguajes que producen cualquiera de los cuatro tipos de cadenas que reconocerá nuestro programa. Con este antecedente mostraremos el pseudocódigo de la función que reconoce un identificador.
func Identificador (Cadena cad) regresa boolean
   if cad[1] != LETRA or cad[1] !=’_’ regresa  falso;
      for( x =2 ; x <= longitud(cad);  x++)  
            {
     if cad
  • !=LETRA or cad
  • != NUMERO or cad
  • !=’_’

                regresa  falso;
             }
   regresa  verdadero;
fin func

De la misma forma como vemos la función identificador debemos codificar las funciones Numero,  PalabraReservada, Operador, etc. de manera que un ciclo en la función principal se vería:

func principal ()
   FILE fa  = fopen(“archivo”,”r”)     
   while ( !feof(fa)) {
      if LeeArchivo(fa, cad)>0 {
          if PalabraReservada (cad)
         print( cad + “tt Palabra Reservada”);
          elseif Identificador (cad)
         print( cad + “tt Identificador”);
          elseif Numero(cad)  
         print( cad + “tt Numero”);
          elseif Operador(cad)  
         print( cad + “tt Operador Aritmético”);
          else
         print(cad + “tt  Error: Palabra NO valida”);
          }
   }
fin func
Aclaraciones

a)   El programa deberá ser escrito en C o Java.
b)   No es obligatorio que la entrada se lea de un archivo, puede ser tecleando las cadenas pero NO una por una sino renglones que simulan expresiones completas, ej:  var1 = 67 + var2
c)   Por razones ajenas existe un programa con mucha disponibilidad entre la comunidad que realiza un tarea similar pero es basando en Autómatas Finitos. Este programa se basa en grandes arreglos donde cada estado es un arreglo y el contenido de estos son cada una de las letras, los números y otros símbolos.  ESTE PROGRAMA NO SERA ACEPTADO.
d)    En un analizador léxico real cuando al evaluar una expresión se encuentra un símbolos que no sea parte de un identificador (LETRA, NUMERO, ‘_’) se  da por terminada la cadena y se procesa. Este comportamiento se considerará un agregado. Se da por valido el hecho de que cada cadena de un reglón vaya separada por un espacio en blanco.

ssaammuu

  • Miembro activo
  • **
  • Mensajes: 41
  • Nacionalidad: es
    • Ver Perfil
    • http://desarrollodejuegos.net
Re: Analizador Lexico Simplificado
« Respuesta #1 en: Martes 24 de Mayo de 2011, 17:54 »
0
No se hacen tareas, intentalo tú y las dudas que tengas las preguntas...

Tom Cyberspirit

  • Nuevo Miembro
  • *
  • Mensajes: 3
    • Ver Perfil
Re: Analizador Lexico Simplificado
« Respuesta #2 en: Martes 24 de Mayo de 2011, 18:02 »
0
De acuerdo. En tal caso podrian decirme si el siguiente codigo me sirve??

include <string.h>
#include <conio.h>
#include <stdio.h>
#include <io.h>
typedef char cadena[30];

typedef enum{FALSE, TRUE} booleano;

typedef enum{letra, guionBajo, digito, amperson, bype, aritmetico,
igual, relacional, menos, mas, negacion, letraHexa, e, punto,
h, FDC, otros, circunflejo} entradas;

typedef enum{x=-2, bien, q0, q1, q2, q3, q4, q5, q6, q7, q8, q9,
q10, q11, q12, q13, q14, q15, q16, q17, q18, q19,
q20, q21, q22, q23, q24} estados;

typedef enum{identificador, entero, aritmeticoFinal, real, relacionalFinal,
logico, hexadecimal, exponencial} resultados;

//////// AUTOMATA EN FORMA DE TABLA //////////
estados tabla[25][18]={
{q1, q1, q15, q12, q13, q6, q7, q9, q3, q11, q19, q1, q1, q4, q1, x, x, q6},
{q1, q1, q1, x, x, x, x, x, x, x, x, q1, q1, x, q1, bien, x, x},
{x, x, q2, x, x, x, x, x, x, x, x, x, q20, q4, x, bien, x, x},
{x, x, q2, x, x, x, q8, x, q8, x, x, x, x, q4, x, bien, x, x},
{x, x, q5, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x},
{x, x, q5, x, x, x, x, x, x, x, x, x, q20, x, x, bien, x, x},
{x, x, x, x, x, x, q8, x, x, x, x, x, x, x, x, bien, x, x},
{x, x, x, x, x, x, q10, x, x, x, x, x, x, x, x, bien, x, x},
{x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, bien, x},
{x, x, x, x, x, x, q10, x, x, x, x, x, x, x, x, bien, x, x},
{x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, bien, x, x},
{x, x, q2, x, x, x, q8, x, x, q8, x, x, x, q4, x, bien, x, x},
{x, x, x, q14, x, x, x, x, x, x, x, x, x, x, x, x, x, x},
{x, x, x, x, q14, x, x, x, x, x, x, x, x, x, x, x, x, x},
{x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, bien, x, x},
{x, x, q15, x, x, x, x, x, x, x, x, q17, q16, q4, q18, bien, x, x},
{x, x, q22, x, x, x, x, x, q23, q23, x, q17, q17, x, q18, x, x, x},
{x, x, q17, x, x, x, x, x, x, x, x, q17, q17, x, q18, x, x, x},
{x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, bien, x, x},
{x, x, x, x, x, x, q10, x, x, x, x, x, x, x, x, bien, x, x},
{x, x, q21, x, x, x, x, x, q23, q23, x, x, x, x, x, x, x, x},
{x, x, q21, x, x, x, x, x, x, x, x, x, x, x, x, bien, x, x},
{x, x, q22, x, x, x, x, x, x, x, x, q17, q17, x, q18, bien, x, x},
{x, x, q24, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x},
{x, x, q24, x, x, x, x, x, x, x, x, x, x, x, x, bien, x, x}};
/**********MARGEN********/
void margen(void)
{
int i, j;
textbackground(BLUE);
textcolor(WHITE);
for (i=1; i<=80; i++)
{
gotoxy(i,1);cprintf("%c", 176);
gotoxy(i,24);cprintf("%c", 176);
}
for (i=1; i<=24; i++)
{
gotoxy(1,i);cprintf("%c", 176);
gotoxy(80,i);cprintf("%c", 176);
}
}
/*********PALABRAS RESERVADAS*******/
booleano palabraReservada(cadena cad)
{
int i;
cadena lista[]={"int", "float", "char", "enum", "unsigned", "short",
"long", "double", "class", "public", "static", "void", "main",
"protected", "for", "if", "while", "do", "switch", "case", "default",
"{", "}", "printf", "goto", "scanf", "gotoxy", "typedef", "struct",
"union", "auto", "return", "include", "define", "malloc", "new",
"delete", "continue", "free", "else"};
for (i=0; i<40; i++)
if (strcmp(lista, cad)==0)
return TRUE;
return FALSE;
}
/****************DICCIONARIO DE ENTRADAS*************/
entradas diccionario(char caracter)
{
switch (caracter)
{
case 'g':case 'i':case 'j':case 'k':case 'l':case 'm':
case 'n':case 'o':case 'p':case 'q':case 'r':case 's':
case 't':case 'u':case 'v':case 'w':case 'x':case 'y':
case 'z':case 'G':case 'I':case 'J':case 'K':case 'L':
case 'M':case 'N':case 'O':case 'P':case 'Q':case 'R':
case 'S':case 'T':case 'U':case 'V':case 'W':case 'X':
case 'Y':case 'Z':
return letra;
case '_':
return guionBajo;
case '0':case '1':case '2':case '3':case '4':case '5':
case '6':case '7':case '8':case '9':
return digito;
case '&':
return amperson;
case '|':
return bype;
case '%':case '/':case '*':
return aritmetico;
case '=':
return igual;
case '<':case '>':
return relacional;
case '-':
return menos;
case '+':
return mas;
case '!':
return negacion;
case 'a':case 'b':case 'c':case 'd':case 'f':
case 'A':case 'B':case 'C':case 'D':case 'F':
return letraHexa;
case 'e':case 'E':
return e;
case '.':
return punto;
case 'h':case 'H':
return h;
case '^':
return circunflejo;
case '':
return FDC;
default:
return otros;
}
}
/*******DICCIONARIO DE ESTADOS*********/
resultados diccionario_edos(estados edo)
{
switch (edo)
{
case q1:
return identificador;
case q2:case q15:
return entero;
case q3:case q6:case q7:case q8:case q11:
return aritmeticoFinal;
case q5:
return real;
case q9:case q10:
return relacionalFinal;
case q14:case q19:
return logico;
case q18:
return hexadecimal;
case q21:case q22:case q24:
return exponencial;
}
return entero;
}
/***********AUTOMATA DEL ANALISADOR**********/
booleano automata(cadena cad, estados &edo)
{
int i=0;
estados edoAnterior;
edo=q0;
entradas in;
do
{
in=diccionario(cad);
edoAnterior=edo;
edo=tabla[edo][in];
if (edo==x)
return FALSE;
i++;
}while(edo!=bien);
edo=edoAnterior;
return TRUE;
}
/**********MAIN***********/
void main(void)
{
cadena cad;
estados edo;
resultados res;
char rep;

do{
clrscr();
margen();
gotoxy(29, 3);
textcolor(YELLOW);cprintf("== ANALIZADOR LEXICO ==");
gotoxy(3, 6);
textcolor(WHITE);cprintf("Cadena: ");
gotoxy(3, 7);gets(cad);
if (palabraReservada(cad))
{
textcolor(YELLOW);
gotoxy(10, 12);cprintf("SI ES UN TOKEN VALIDO DE C.");
gotoxy(10, 13);cprintf("ES UNA ");
textcolor(WHITE);cprintf("PALABRA RESERVADA.");
}
else
{

if (automata(cad, edo))
{
res=diccionario_edos(edo);
textcolor(YELLOW);
gotoxy(10, 12);cprintf("SI ES UN TOKEN VALIDO DE C.");
gotoxy(10, 13);cprintf("ES UN ");
textcolor(WHITE);
switch (res)
{
case identificador:
cprintf("IDENTIFICADOR.");
break;
case entero:
cprintf("NUMERO ENTERO.");
break;
case aritmeticoFinal:
cprintf("OPERADOR ARITMETICO.");
break;
case real:
cprintf("NUMERO REAL.");
break;
case relacionalFinal:
cprintf("OPERADOR RELACIONAL.");
break;
case logico:
cprintf("OPERADOR LOGICO.");
break;
case hexadecimal:
cprintf("NUMERO HEXADECIMAL PARA INTEL.");
break;
case exponencial:
cprintf("NUMERO EXPONENCIAL.");
break;
}

}
else
{
textcolor(YELLOW);
gotoxy(10, 9);cprintf("NO ES UN TOKEN VALIDO DE C.");
}
}
gotoxy(20, 20);
textcolor(GREEN);cprintf(">> [ENTER] PARA REPETIR.");
gotoxy(20, 21);cprintf(">> [ESC] PARA SALIR.");
rep=getch();
}while(rep==13);

}

Se que es parecido a lo que yo quiero hacer pero no es exactamente lo que pido. En caso de que no sea asi me pueden decir los puntod que debo cambiar??

Gracias

Tom Cyberspirit

  • Nuevo Miembro
  • *
  • Mensajes: 3
    • Ver Perfil
Re: Analizador Lexico Simplificado
« Respuesta #3 en: Domingo 29 de Mayo de 2011, 03:58 »
0
De acuerdo. Dado que no hay respuesta ya empece a hacerlo por mi cuenta.

Mi primera duda es la siguiente:

Como hago para que saber el tipo de dato que el usuario escribira??

Se que debo guardar lo que el usuario teclee en una variable pero tambien se que debo saber el tipo de dato de la variable.

Ejemplo:

El programa dice:

Escribe el token que deseas analizar:

el usario escribe lo siguiente:

Inicio

Inicio es una palabra reservada de C y es un tipo de dato caracter. pero como hacer que el programa reconozca por si solo que tipo de dato es??

Existe una forma de guardar diferentes tipos de datos en una sola variable??

O que es lo mas aconsejable para esto??

ssaammuu

  • Miembro activo
  • **
  • Mensajes: 41
  • Nacionalidad: es
    • Ver Perfil
    • http://desarrollodejuegos.net
Re: Analizador Lexico Simplificado
« Respuesta #4 en: Domingo 29 de Mayo de 2011, 14:54 »
0
Usando C++ (que creo que estás usando) yo personalmente guardaría todo lo que el usuario escribe en strings, irrespectivamente de lo que sea. Después la mayoría del programa consistiría en analizar esos strings para determinar lo que el usuario ha introducido. Si te parece bien usar esta estrategia te recomiendo que le te familiarizes con string y sstream para manipular/cambiar el tipo de variable.