Manual JFlex CUP PDF

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 10

Universidad de San Carlos de Guatemala

Facultad de Ingeniería
Escuela de ciencias y sistemas
Organización de Lenguajes y compiladores 1
Sección C
Erick Tejaxún Xicón

Manual de uso JFlex y CUP en Netbeans


Para este manual, se implementará un analizador que reconoce una entrada de listas de operaciones
aritméticas separadas por punto y coma [;] y reconoce enteros, id, dobles, booleanos y caracteres
[‘c’] y cadenas [“cadena”] y produce una salida de la manera:
Descargamos JFlex : http://jflex.de/download.html
Descargamos CUP : http://www2.cs.tum.edu/projects/cup/install.php
1. Creamos un nuevo proyecto de escritorio.

2. Agregamos la librería javacup_runtime.jar al proyecto. Esta es importante porque nuestro


parser necesitará de las funciones que se encuentran en esa librería.
3. Creamos un nuevo paquete para nuestros analizadores.

4. Creamos nuestros archivos para la especificación de Jflex [ scanner.lex ] y para CUP


[parser.cup] y en caso de Windows, un archivo .bat para generar automáticamente nuestros
analizadores [generador.bat]

Generador.bat
SET JFLEX_HOME= C:\libs\jflex-1.6.1
cd C:\Users\erick\Documents\NetBeansProjects\clase1\src\Analisis\
java -jar %JFLEX_HOME%\lib\jflex-1.6.1.jar scanner.l
pause

SET JFLEX_HOME= C:\libs\java-cup-11b


cd C:\Users\erick\Documents\NetBeansProjects\clase1\src\Analisis\
java -jar %JFLEX_HOME%\java-cup-11b.jar -parser parser parser.cup
pause
Explicación:

Scanner.l
package Analisis; // Paquete donde estará nuestro scanner

import java_cup.runtime.Symbol;
%%

%{
/*Area de declaración de codigo java.
*Funciones y variables necesarias
*
*/
String nombre;
public void imprimir(String cadena)
{
System.out.println(cadena);
}
%}

// Area de directivas
%cupsym sym
%class scanner
%cup
%public
%unicode
%line
%column
%char
%ignorecase

// Area de definición de expresiones regulares. Tokens.


Comentario = "//" [^\r\n]* [^\r\n]
ComentarioMulti = "/*" [^/] ~"*/" | "/*" "/"+ "*/"
entero =[0-9]+
decimal =[0-9]+ "." [0-9]*
cadena =[\"] [^\"\n]* [\"\n]
letra =[a-zA-ZÑñ]+
id ={letra}({letra}|{entero}|"_")*
caracter="'"[^]"'"
bool=("verdadero"|"falso")
espacio = \t|\f|" "|\r|\n

%%
// Acciones
/* Espacios en blanco */
{espacio} {/*Ignorar*/}
{entero} {return new Symbol(sym.entero,yycolumn,yyline,yytext());}
{decimal} {return new Symbol(sym.decimal,yycolumn,yyline,yytext());}
{cadena} {return new Symbol(sym.cadena,yycolumn,yyline,yytext());}
{id} {return new Symbol(sym.id,yycolumn,yyline,yytext());}
{caracter} {return new Symbol(sym.caracter,yycolumn,yyline,yytext());}
{bool} {return new Symbol(sym.booleano,yycolumn,yyline,yytext());}
";" {return new Symbol(sym.puntocoma,yycolumn,yyline,yytext());}
"(" {return new Symbol(sym.para,yycolumn,yyline,yytext());}
")" {return new Symbol(sym.parc,yycolumn,yyline,yytext());}
"+" {return new Symbol(sym.suma,yycolumn,yyline,yytext());}
"-" {return new Symbol(sym.resta,yycolumn,yyline,yytext());}
"*" {return new Symbol(sym.multi,yycolumn,yyline,yytext());}
"/" {return new Symbol(sym.div,yycolumn,yyline,yytext());}
"^" {return new Symbol(sym.potencia,yycolumn,yyline,yytext());}
{Comentario} { /*Se ignora.*/}
{ComentarioMulti} { /*Se ignora.*/}
/*Recolección de errores*/
.
{
System.err.println("Error lexico: "+yytext()+ " Linea:"+(yyline+1)+"
Columna:"+(yycolumn+1));
}

Parser.cup
package Analisis; // Paquete
import java_cup.runtime.*;

parser code
{:

public String salida = "" ; // Aquí guardaremos nuestra resultado.

public void syntax_error(Symbol s)


{
System.err.println("El analizador se recupero tras el error\nError en la Línea "
+ (s.right+1) +" Columna "+(s.left+1)+ ". Identificador "
+s.value + " no reconocido." );
}

/**Metodo al que se llama en el momento en que ya no es posible una recuperación de


errores.*/
public void unrecovered_syntax_error(Symbol s) throws java.lang.Exception{
System.err.println("El analizador No se recupero tras el error\nError en la Línea
" + (s.right+1)+ "Columna "+(s.left+1)+". Identificador " +
s.value + " no reconocido.");
}

public void setSalida(String cadena) // Metodo que guarda nuestro resultado.


{
salida = cadena;
}
:}
/*Terminales*/

terminal String entero,decimal,cadena,booleano,id,caracter, puntocoma;


terminal String suma, resta, multi, div, potencia, para, parc;

/*
* Aquí están los no terminales
*/
non terminal INICIO;
non terminal String LEXP, EXP; // No terminales de tipo String

/* Precedencia */
precedence left suma, resta;
precedence left multi, div;
precedence left potencia;

/* Definición de la gramatica */
start with INICIO; // indicamos con qué producción debe empezar la gramatica.

INICIO::= LEXP:cadena {:setSalida(cadena);:};

LEXP::= LEXP:cadena1 EXP:cadena2 puntocoma {: RESULT = cadena1+ "\n" +


cadena2;:}
|EXP:cadena puntocoma {: RESULT = cadena;:}
;

EXP::=
EXP:valor1 suma EXP:valor2 {:RESULT = "suma("+valor1+","+valor2+")";:}
|EXP:valor1 resta EXP:valor2 {:RESULT ="resta("+valor1+","+valor2+")";:}
|EXP:valor1 multi EXP:valor2 {:RESULT = "multiplicacion("+valor1+","+valor2+")";:}
|EXP:valor1 div EXP:valor2 {:RESULT = "division("+valor1+","+valor2+")";:}
|EXP:valor1 potencia EXP:valor2 {:RESULT = "potencia("+valor1+","+valor2+")";:}
|para EXP:valor parc {:RESULT = valor;:}
|entero:valor {:RESULT = valor;:}
|decimal:valor {:RESULT = valor;:}
|cadena:valor {:RESULT = valor;:}
|booleano:valor {:RESULT = valor;:}
|id:valor {:RESULT = valor;:}
|caracter:valor {:RESULT = valor;:}
;
5. Luego de tener nuestro archivos scanner.l y parser.cup generamos nuestros analizadores
con el archivo [generador.bat]

Se ejecutará nuestro script. Vemos que primero nos generará nuestro archivo [scanner.java] y nos
muestra detalles. Si hubiera errores, se nos indicarán con detalle.
Luego nos generará nuestro analizador sintactico.
Esto generará las clases [parser.java] y la clase [sym.java].

Ahora que ya tenemos nuestros analizadores, crearemos la interfaz gráfica desde dónde
vamos a utilizarlos.
Creamos una Ventana JFrame.
Agregamos 2 textArea.
 txtInput: Caja de texto donde se ingresará la entrada.
 txtOutput: Caja de texto donde se mostrará la salida.
Botón “analizar”: llamará a la función analizar() donde se analizará la entrada.

Importamos nuestros analizadores


 import Analisis.*;
Desde el botón Analizar invocaremos a la función analizar().
public void analizar() throws Exception
{
String input = txtinput.getText(); //Obtenemos la entrada
/*Ahora instanciamos nuestro scanner enviándole como parámetro nuestro input.*/
scanner lexico = new scanner(new BufferedReader(new StringReader(input)));
/*Ahora instanciamos nuestro parser enviándole como parámetro nuestro scanner.*/
parser sin = new parser(lexico);
sin.parse(); // Comenzamos el análisis.
mostrarSalida(sin.salida); //Obtenemos nuestra cadena de resultado y la imprimimos.
}

public void mostrarSalida(String output)


{
txtoutput.setText(output);
}

Tarea:
Se solicita una aplicación que reconozca la misma gramática que este ejemplo pero que
genere como salida:
 La misma cadena de entrada pero en notación postfija.
 En caso de que todos los operando sean de tipo entero o doble, se deberá generar
como cadena en postfija = resultado.
/* Input */
(a-b*c/1)*1;
1+1;
9+2-34*1;
5+(a*b);

/*output */
a b - c 1 / * 1 *
1 1 + = 2
9 2 + 34 1 * - = -23
5 a b * +

También podría gustarte