analizador léxico y sintáctico para compilador que invierte cadenas utilizando jflex y cup

19
CIS-IXB-005 UNIVERSIDAD NACIONAL DE LOJA ´ Area de la Energ´ ıa las Industrias y los Recursos Naturales No Renovables Carrera de Ingenier ´ ıa en Sistemas “Analizador L´ exico y Sint´ actico para Compilador que Invierte Cadenas utilizando JFLEX y CUP” Informe de Trabajo Final Noveno B Autor: Diego Paul Cuenca Quezada Docente: Ing. Henry Paz Materia: Compiladores Loja-Ecuador 2015 1

Upload: diego-cuenca

Post on 24-Jul-2015

399 views

Category:

Software


3 download

TRANSCRIPT

Page 1: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

CIS-IXB-005

UNIVERSIDADNACIONALDE LOJA

Area de la Energıa las Industrias y los Recursos Naturales No Renovables

Carrera de Ingenierıa en Sistemas

“Analizador Lexico y Sintactico paraCompilador que Invierte Cadenas

utilizando JFLEX y CUP”

Informe de Trabajo FinalNoveno B

Autor:

• Diego Paul Cuenca Quezada

Docente: Ing. Henry Paz

Materia: Compiladores

Loja-Ecuador2015

1

Page 2: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

IndiceA. PROBLEMA 3

1 . ¿Como surgio el problema? . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 . ¿Que resuelve? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 . Automata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

B. ANALIZADOR LEXICO 51 . Cogido del archivo Jflex . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

C. ANALIZADOR SINTACTICO 81 . Cogido del archivo CUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

D. MANEJO DE ERRORES 12

E. FUNCIONAMIENTO 151 . MENU PRINCIPAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 . MENU OPCIONES AVANZADAS . . . . . . . . . . . . . . . . . . . . . . 163 . EJECUCION Y RESULTADOS . . . . . . . . . . . . . . . . . . . . . . . . 16

F. BIBLIOGRAFIA 18

G. LICENCIA 19

Page 3: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

A. PROBLEMAEl desarrollo de un compilador que invierta cadenas utilizando Jflex y Cup tiene como

objetivo principal, poner en practica todos los conocimientos adquiridos en la asignaturade Compiladores, ademas de incentivar la investigacion en los estudiantes, mediante locual puedan resolver las diferentes dificultades que se presentan en el campo laboral. Paraello, en los siguientes apartados se explicara de manera mas profunda el porque de laelaboracion de este compilador y que problema resuelve.

1 . ¿Como surgio el problema?El problema a resolver con este compilador surgio principalmente por la idea del

docente responsable de impartir la materia de compiladores Ing. Henry Paz, quien nosmanifesto que al final de su catedra tendrıamos que elaborar un compilador que resuelva unproblema diferente a los que usualmente se encuentran en la internet, con el fin de mostrarcomo un compilador puede ser efectivo en algunos casos y para entender funcionalidadesadicionales a las expuestas frecuentemente en la web, es decir proponer una solucion propiaa un problema propio, valga la redundancia.

2 . ¿Que resuelve?El presente compilador denominado Inversor de Cadenas, como su nombre lo ex-

presa, va a permitir a una cadena (String), ingresada previamente, encontrarle su inversa,es decir si el valor dado es “Hola soy Diego Paul y estudio en la UNL”, la inversa encon-trada por el compilador sera “UNL la en estudio y Paul Diego soy Hola”. Para ello sedebe conocer primeramente la sintaxis de ingreso de datos del compilador, la cual sera lasiguiente:

INVERTIR(Cadena a invertir);

En donde:

INVERTIR, es la palabra reservada del presente compilador, la cual permite quese realice la inversa de una cadena (String).

(), cumplen la misma funcionalidad que las comillas “” en la mayorıa de los lenguajesde programacion, es decir, representan el inicio y el final de una cadena (String).

Cadena a invertir, simboliza la cadena (String) que va ser ingresada al compiladorpara ser invertida, esta debe ir entre los parentesis ya mencionados anteriormente.

;, indica el final de la sentencia, al igual que algunos lenguajes de programacion.

El formato con el que el compilador nos arrojara el resultado de la inversion de una cadena(String), sera de la siguiente manera:

− > Esta es la cadena invertida

3

Page 4: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

3 . AutomataA continuacion se muestra el automata propuesto para el compilador inversor de ca-

denas:

Figura 1: Automata del compilador.

4

Page 5: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

B. ANALIZADOR LEXICOAquı podemos evidenciar el codigo utilizado para el analisis lexico de este compilador,

es claro darse cuenta en los comentarios expuestos en cada lınea para que pueda entendersede mejor manera y con esto compartir el conocimiento adquirido durante su desarrollo. Esimportante recordar la estructura de un archivo Jflex, que para una mejor comprensionse divide 3 partes:

1. Opciones y declaraciones

2. Codigo de usuario

3. Reglas lexicograficas

1 . Cogido del archivo Jflex/* --------------------------Codigo de Usuario----------------------- */package compilador; //Paquete en donde se creara el analizador

/*Importamos la librerıa de CUP y todas las clases del paquete runtime*/import java_cup.runtime.*;

%% //INICIO DE OPCIONES

/* ------ Seccion de opciones y declaraciones de JFlex -------------- */

/*Cambiamos el nombre de la clase del analizador a Lexer

*/%class AnalizadorLexico

%line //Activar el contador de lineas, variable yyline%column //Activar el contador de columna, variable yycolumn%cup //Activamos la compatibilidad con Java CUP para analizadores sintacticos

/*Declaraciones

El codigo entre %{ y %} sera copiado ıntegramente en elanalizador generado.

*/%{

/*Necesaria para poder controlar el error del ;*/boolean estadoFinLinea = false;

/* Generamos un java_cup.Symbol para guardar el tipo de tokenencontrado */

5

Page 6: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

private Symbol symbol(int type) {return new Symbol(type, yyline, yycolumn);

}

/* Generamos un Symbol para el tipo de token encontradojunto con su valor */

private Symbol symbol(int type, Object value) {return new Symbol(type, yyline, yycolumn, value);

}%}

/*Macro declaraciones

Declaramos expresiones regulares que despues usaremos en lasreglas lexicas.

*/

/*Todos los caracteres excepto los que se muestran en el alfabeto*/Letras_Numeros = [ˆ\;\-\>\(\)]*

%% //FIN DE OPCIONES

/* -------------------- Seccion de reglas lexicas ------------------ */

/*Esta seccion contiene expresiones regulares y acciones.Las acciones son codigo en Java que se ejecutaran cuando seencuentre una entrada valida para la expresion regular correspondiente */

/* YYINITIAL es el estado inicial del analizador lexico al escanear.Las expresiones regulares solo seran comparadas si se encuentraen ese estado inicial. Es decir, cada vez que se encuentra unacoincidencia el scanner vuelve al estado inicial. Por lo cual se

ignoran estados intermedios.*/

<YYINITIAL> {/* Retorna que el token FIN_LINEA declarado en la clase sym,

fue encontrado. */";" { estadoFinLinea = true;

return symbol(sym.FIN_LINEA); }/* Retorna que el token INVERTIDA_ES declarado en la clase sym,fue encontrado. */"->" { System.out.print("->");

return symbol(sym.INVERTIDA_ES); }

6

Page 7: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

/* Retorna que el token PARENTESIS_INICIO declarado en la clase sym,fue encontrado. */"(" { System.out.print("(");

return symbol(sym.PARENTESIS_INICIO); }/* Retorna que el token PARENTESIS_FINAL declarado en la clase sym,

fue encontrado. */")" { System.out.println(")");

return symbol(sym.PARENTESIS_FINAL); }/* Retorna que el token PALABRA_RESERVADA declarado en la clase sym,fue encontrado. */"INVERTIR" {

System.out.println("#-#-#-#-#-#-#-#-#-# SENTENCIA #-#-#-#-#-#-#-#-#-#");System.out.print(yytext());return symbol(sym.PALABRA_RESERVADA); }

/* Cuando encuentra un String se imprime, se retorna el token CADENAque representa la cadena a invertir con el valor que se obtuvo deyytext(). yytext() es el token encontrado. */

{Letras_Numeros} {/*Metodo para controlar cuando no existe el fin de lınea,es decir cuando no se pone el ; al fin de la sentencia.*/

if (!estadoFinLinea && yytext().isEmpty()) {/*En caso de que no se encuentre el ; me devuelvenull para imprimir el error, esto en el analizadorsintactico*/return null;} else {/*Es caso de que no haya problema con el ;*/System.out.print(yytext());

return symbol(sym.CADENA, yytext());}

}}

/* Si el token contenido en la entrada no coincide con ninguna reglaentonces se marca un token ilegal */

[ˆ] { throw new Error("El caracter <"+yytext()+"> es ilegal"); }

7

Page 8: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

C. ANALIZADOR SINTACTICOComo es de nuestro conocimiento, un fichero de entrada para CUP consta de una

estructura bien definida, la misma que se encuentra descrita en nuestro archivo CUP,teniendo en cuenta lo que va a realizar nuestro compilador. La estructura es la siguiente:

1. Definicion de paquetes y sentencias import.

2. Seccion de codigo de usuario.

3. Declaracion de sımbolos terminales y no terminales.

4. Declaraciones de precedencia.

5. Definicion del sımbolo inicial de la gramatica y las reglas de produccion.

1 . Cogido del archivo CUP/* ---------------Seccion de declaraciones preliminares--------------------*/package compilador; //Paquete en donde se creara el analizador

/*Importamos la clase FileReader del paquete java.io para poder leer elarchivo test.txt en cual se almacenan las sentecias ingresadas*/import java.io.FileReader;

/* Codigo del parser, se copia ıntegramente a la clase final.Agregamos el manejo de errores. */

parser code {:/* Reporte de los errores encontrados. */

public void report_error(String message, Object info) {StringBuilder m = new StringBuilder("Error");int linea = 0;int columna = 0;/*Control para el error de "lectura de la ultima lınea de la sentencia"*/if ("".equals((((java_cup.runtime.Symbol) info).value))&& (((java_cup.runtime.Symbol) info).sym) == 7) {System.out.print("");} else {if (info instanceof java_cup.runtime.Symbol) {java_cup.runtime.Symbol s = ((java_cup.runtime.Symbol) info);//Determinamos la lınea y columna del errorif (s.left >= 0) {linea = s.left + 1;if (s.right >= 0) {columna = s.right + 1;}

8

Page 9: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

}}//Linea y Columna ya tiene un valor asignado para perzonalizar los erroresm.append(" en la lınea ").append(linea);

m.append(", columna ").append(columna);//Error en caso de no ingresar el ;

if (columna == 0) {m.append(" : ").append(message).append(" : No se ha terminado la sentencia con ;\n"+ "\tSugerencia: La sentencia debe terminar "+ "--> INVERTIR(cadena a invertir);");

}//Error en caso de ingresar mal la palabra reservada INVERTIR

if (columna == 1) {m.append(" : ").append(message).append(" : No se reconoce la palabra reservada\n"+ "\tSugerencia: La sentencia debe empezar con la palabra resevada "+ "--> INVERTIR");

}//Error en caso de ingresar sentencia correcta y cadena vacıa

if (columna == 10) {m.append(" : ").append(message).append(" : INVETIR(’’) Cadena vacıa\n"+ "\tSugerencia: Debe ingresar algun valor en la sentencia "+ "--> INVERTIR(cadena a invertir)");}//Error en caso de no ingresar el ultimo parentesis

if (columna > 10) {m.append(" : ").append(message).append(" : No se reconoce la cadena ingresada\n"+ "\tSugerencia: La cadena debe ir entre parentesis "+ "--> (cadena a invertir)");

}System.err.println(m);//Imprimimos el error y la sugerencia

}}

/* Cuando se encuentra un error de donde el sistema no puederecuperarse, se lanza un error fatal. Se despliega el mensaje

de error y la sugerencia determinada en el metodo. */public void report_fatal_error(String message, Object info) {report_error(message, info);}

/* Metodo main para garantizar la ejecucion del analizador

9

Page 10: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

lexico y sintactico, ademas que se pase como parametro la tablade simbolos correspondiente. */public static void main(String[] args){try {AnalizadorSintactico asin = new AnalizadorSintactico(new AnalizadorLexico(new FileReader(args[0])));Object result = asin.parse().value;//Ejecucion del Analizador} catch (Exception ex) {System.out.print("");}}/*Metodo necesario para realizar el objetivo principal del

compilador, que en este caso es de invertir una cadena*/public String invertirCadena(String cadena) {String cadenaInversa = "";

int posicionInicial = 0;for (int i = 0; i < cadena.length(); i++) {//En caso de los espacios

if (String.valueOf(cadena.charAt(i)).equals(" ")) {cadenaInversa = " ".concat(cadena.substring(posicionInicial, i)).concat(cadenaInversa);posicionInicial = i + 1;//Guarda la posicion inicial del substring}

if (i == cadena.length() - 1) {//En caso de la ultima subcadenacadenaInversa = cadena.substring(posicionInicial, i + 1)

.concat(cadenaInversa);}}

return cadenaInversa;//Retornamos la cadena ya invertida}:};

/* --------Declaracion de simbolos terminales y no terminales------ */

/* Terminales (tokens obtenidos por el analizador lexico).Las variables terminales seran todos los sımbolos terminales

de la gramatica*/terminal PALABRA_RESERVADA, PARENTESIS_INICIO, PARENTESIS_FINAL;terminal FIN_LINEA, INVERTIDA_ES;terminal String CADENA;

/* Las variables no terminales seran todas las variables que representaranproducciones*/

non terminal Object expr, linea;non terminal String cadena;

10

Page 11: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

/* ---------Seccion de predencia y asociacion de los terminales------- *//* Esta seccion es opcional. En nuestro compilador no vamos a utilizaresta seccion, se lo puede hacer, de ser necesario.*/

/* ------------------- Seccion de la gramatica ------------------------ */// En este seccion se escriben las producciones de la misma

/*Este compilador inciara la produccion desde el no-terminal expr*/start with expr;

/*Para que la sentencia una vez realzadas las anteriores producciones,termine en ; INVERTIR(cadena que vamos a invertir);*/expr ::= linea:l{://Obtenemos la produccion de linea e imprimimos nuestra cadena invertidaSystem.out.println("#-#-#-#-#-#-#-#-#-# INVERTIDA ES "+ "#-#-#-#-#-#-#-#-#-#\n -> " + l);:}

FIN_LINEA;

/*Ya con la cadena entre parentesis, nos aseguramos que antes de esta simprevaya la palabra reservadaINVERTIR(cadena que vamos a invertir)*/linea ::= PALABRA_RESERVADA cadena:c{:/*Aquı llamamos al metodo que invierte las cadenas y almacenamos su

resultado en RESULT*/RESULT = new AnalizadorSintactico().invertirCadena(c);

:};

/*Nos aseguramos que nuesta cadena siempre vaya entre parentesis(cadena que vamos a invertir) */cadena ::= PARENTESIS_INICIO CADENA:a PARENTESIS_FINAL{:RESULT = a;

:};

11

Page 12: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

D. MANEJO DE ERRORESEsta seccion es muy importante, ya que se trata de darle sentido a los errores del

compilador, es decir, identificar cada uno, que mensaje arrojarıa el mismo en determinadocaso y controlarlo para que devuelva lo que nosotros creamos conveniente. El exito deesta actividad no esta solo en entender el funcionamiento de nuestro compilador, si node analizar la logica del mismo para ası identificar cada uno de los errores en distintassituaciones a las que puede ser sometido.

En las siguientes figuras se muestra el codigo del metodo report error, en el cual secontrola y personaliza los errores del compilador, para lo que se va indicar en dos partes:En la primera parte podemos observar que se declaran dos variables: lınea y columna detipo entero, las cuales tomaran su respectivo valor para ser utilizadas en la segunda partedel mismo. Ademas en la lınea 20 se encuentra una condicion la cual en caso de que seaverdad imprime una cadena vacıa, que controlamos un error que se generaba siempre alfinal de la sentencia.

Figura 2: Codigo que controla y personaliza errores 1.

Ya con los valores asignados a las variables lınea y columna, la segunda parte presentalos diferentes casos en los cuales se va a generar un error de sintaxis y presenta el error,su ubicacion y la sugerencia dependiendo del caso.

12

Page 13: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

Figura 3: Codigo que controla y personaliza errores 2.

Por ejemplo, a continuacion se describen los cuatro errores que se controlan en este com-pilador:

1. Si la palabras reservada no esta bien escrita:

Figura 4: Codigo: Lınea 42 de la Figura 3.

2. Si no se ingresa una cadena al inversor:

Figura 5: Codigo: Lınea 47 de la Figura 3.

13

Page 14: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

3. Si no se encuentra el parentesis al final de la cadena:

Figura 6: Codigo: Lınea 52 de la Figura 3.

4. Si el fin de lınea no se encuentra:

Figura 7: Codigo: Lınea 37 de la Figura 3.

14

Page 15: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

E. FUNCIONAMIENTOEl compilador inversor de cadenas, ademas de su rapido funcionamiento, tiene la ca-

racterıstica de ser intuitivo para el usuario, ya que cuenta con un menu principal en dondese puede seleccionar la actividad que desee, de la siguiente manera:

1 . MENU PRINCIPAL

Figura 8: Menu Principal de nuestro compilador.

1. Ejecutar compilador. El programa pedira que se ingrese la sentencia, en la cualel usuario debe hacerlo, pudiendo ası obtener el resultado de la inversion. En otraspalabras aquı el compilador realiza la tarea para la que fue desarrollado.

Figura 9: Opcion 1 del MP para ejecutar el compilador.

2. Ir a Opciones avanzadas. Nos lleva a otro menu en donde encontraremos unaopcion adicional “Generar archivos Jflex y Cup”, que no esta en el menu principalporque no es necesario que se ejecute frecuentemente, solo en caso de hacer cambiosen los archivos Jflex y Cup.

15

Page 16: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

Figura 10: Opcion 2 del MP para llevarnos al otro menu.

3. Salir del compilador. Salimos del compilador.

2 . MENU OPCIONES AVANZADAS1. Generar archivos Jflex y Cup. Como ya se explico en el apartado anterior, esta

solo se usara en caso de ser necesario, es decir se realice algun cambio a cualquierade los archivos Jflex o Cup.

Figura 11: Menu de Opciones Avanzadas.

2. Volver al Menu Principal. Regresamos al menu principal para realizar cualquieropcion de ese menu.

3. Salir del compilador. Salimos del compilador.

3 . EJECUCION Y RESULTADOSComo ya lo sabemos para ejecutar nuestro compilador debemos seleccionar la opcion

1 del Menu Principal, para que posteriormente ingresarla sentencia a validar. Para estaprueba vamos a probarlo con la siguiente cadena:

Hola soy Diego.!!, mi fecha de nacimiento es el 14/02/93. Y tu Como te llamas?

Entonces la ejecucion del compilador serıa como se puede ver en la figura 12.

16

Page 17: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

Figura 12: Ejecucion del Compilador.

17

Page 18: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

F. BIBLIOGRAFIA

Referencias[1] CUENCA Diego; Codigo del Compilador Inversor de Cadenas; Universidad Na-

cional de Loja - Carrera de Ingenierıa en Sistemas; Disponible en: https://gist.github.com/diego14c/b1f547a9f1ef9428eaa2

[2] Jflex; Descargar librerıa Jflex; Disponible en: http://jflex.de/download.html

[3] CUP; Descargar librerıa CUP; Disponible en: http://www.cs.princeton.edu/˜appel/modern/java/CUP/

18

Page 19: Analizador Léxico y Sintáctico para Compilador que Invierte Cadenas utilizando JFLEX y CUP

G. LICENCIA

19