Documentos de Académico
Documentos de Profesional
Documentos de Cultura
UNIVERSIDAD
NACIONAL
DE LOJA
Area
de la Energa las Industrias y los Recursos Naturales No Renovables
Trabajo Final
Noveno B
Autores:
Juan Pablo Guaman Rodrguez
Loja - Ecuador
2015
1
Indice
A. Introducci
on
B. Palabras reservadas
C. Operadores
D. Aut
omata
4
5
5
6
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
8
8
9
9
10
G. Ejecuci
on compilador
12
H. Captura de errores
13
I. C
odigo fuente
14
J. BIBLIOGRAFIA
15
A.
Introducci
on
La idea del presente compilador nace por la curiosidad de permitirle al usuario sumar
no solo n
umeros enteros como tales si no que, el mismo juegue con el compilador ingresando palabras.
Como funciona el compilador, pues bien en el mismo puede entender una suma, resta
y/o multiplicacion teniendo como terminos n
umeros enteros y/o palabras las mismas que
pueden ser compuestas por varios caracteres o ser uno solo.
El compilador al encontrar una palabra lo que hace es consultar el codigo ASCII de
cada caracter que forma esta palabra y sumar cada uno de ellos entre si para ese valor
devolverlo como entero, el cual matematicamente si es posible sumarlo con otras enteros.
Para entender mejor eso vamos a ingresar en nuestra entrada del compilador la siguiente
expresion:
1 + 19 - hola;
Nuestro compilador primero se dara cuenta que el primer token es un entero 1el cual
se le esta pidiendo que se le sume otro entero en este caso el 19 seguidamente se le sumara
la palabra holapara por ultimo restarle la palabra mundo, generando la siguiente salida:
ENTERO <1> SUMA ENTERO <19> RESTA CADENA <hola(104:111:108:97) > = -400
Como se puede observar en la salida se muestra lo que estamos pretendiendo operar as,
al encontrar una cadena, la misma se descompone y muestra el ASCII de cada caracter.
B.
Palabras reservadas
Nuestro compilador cuenta con una sola palabra reservada la cual se utiliza para
finalizar una expresion matematica, designado con el smbolo punto y coma ;.
C.
Operadores
D.
Aut
omata
Una vez que sabemos que vamos hacer debemos plantearnos la idea en un automata,
as con este poder seguir la secuencia de pasaos para la validacion de nuestras expresiones.
El automata en nuestro compilador quedo diagramado de la siguiente manera:
E.
Uno de los dos archivos mas importantes para la creacion de nuestro compilador, es
el archivo punto flex, ya que es aqu donde creamos nuestro analizador lexico, el mismo
que nos servira para agregar las reglas lexicas que nuestro compilador poseera.
Pues para este punto nosotros ya deberamos saber que un archivo punto flex posee tres
grandes partes; Codigo de usuario, Directivas y las reglas para las expresiones regulares;
todas las partes separadas por doble porcentaje.
Describamos cada una de estas partes usando el codigo necesario para la creacion de
nuestro compilador.
E.1.
C
odigo de Usuario
package lexico.sintactico;
import java_cup.runtime.*;
import java.io.Reader;
import java.util.HashMap;
Se puede observar que este codigo es, codigo integro que se copiara al archivo punto java
que generaremos, por hende es obvio pensar y estar en lo correcto al decir que la primera
linea es el nombre del paquete que nuestro punto java tendra, ademas las siguientes lineas
son importaciones dos de ellas indispensables para la cremacion y ejecucion de nuestro
flex, la ultima que es una importacion de HashMap se usa en nuestro caso para el control
de errores que mas adelante detallaremos.
E.2.
Directivas
%%
%class AnalizadorLexico
%line
%column
%cup
%{
private Symbol symbol(int type) {
return new Symbol(type, yyline, yycolumn);
}
private Symbol symbol(int type, Object value) {
return new Symbol(type, yyline, yycolumn, value);
}
public static HashMap<String, String> errores = new HashMap<>();
%}
Salto = \r|\n|\r\n
Espacio = {Salto} | [ \t\f]
Entero = 0 | [1-9][0-9]*
Cadena = [a-z][a-z]* | [A-Z][A-Z]* | [a-z][A-Z]* | [A-Z][a-z]*
Para empezar esta segunda seccion escribiremos un doble porcentaje, realizado esto
observamos el nombre de la clase que nuestro punto java tendra, seguidamente nos encontramos con dos lineas mas una %line. y la otra %column las mismas que sirven para
activar el contador de lineas y de columnas en flex, %cup sirve para activar la compatibilidad con CUP que sera usado para nuestro analizador sintactico.
Despues nos encontraremos con un %{ finalizando con %} todo lo que esta dentro de
estas llaves es codigo que se copiara ntegramente a nuestro punto java, pero no fuera de
la clase si no dentro. Los dos primeros metodos son para asignar un entero a los smbolos
5
que nosotros declaremos en nuestro CUP, si este smbolo posee un valor se llamara el
segundo metodo y ese valor pasado como parametro se asignara, el atributo errores es un
HashMap en cual usaremos para almacenar cada error que se encuentre.
E.3.
Expresiones Regulares
%%
<YYINITIAL> {
";"
{
return symbol(sym.SEMI);
}
"+"
{
System.out.print(" SUMA ");
return symbol(sym.OP_SUMA);
}
"-"
{
System.out.print(" RESTA ");
return symbol(sym.OP_RESTA);
}
"*"
{
System.out.print(" MULTIPLICACION ");
return symbol(sym.OP_MULT);
}
"("
{
System.out.print(" PARENTESIS ( ");
return symbol(sym.PARENTESIS_IZQUIERDO);
}
")"
{
System.out.print(" PARENTESIS ) ");
return symbol(sym.PARENTESIS_DERECHO);
}
{Entero}
{
System.out.print("ENTERO <"+yytext()+">");
return symbol(sym.ENTERO, new Integer(yytext()));
}
{Cadena}
{
System.out.print("CADENA <"+yytext());
6
System.out.print("(");
for (int i = 0; i < yytext().length()-1; i++) {
System.out.print(yytext().codePointAt(i)+":");
}
System.out.print(yytext().codePointAt(yytext().length()-1));
System.out.print(") >");
return symbol(sym.CADENA, new StringBuffer(yytext()));
}
{Espacio}
{
}
}
[]
{
String mensaje = "";
mensaje += ("\n************************************");
mensaje += ("\n****Caracter invalido ==> "+yytext()+" <== ****");
mensaje += ("\nencontrado en la linea ");
mensaje += ((yyline + 1) + " y columna " + (yycolumn + 1));
mensaje += ("\n************************************\n");
String keyString = (yyline + 1) + (yycolumn + 1) + "";
errores.put(keyString, yytext());
System.err.println(mensaje);
}
YYINITIAL es un estado inicial el cual va a ir almacenando nuestros tokens que seran
declarados.
En nuestro compilador el caracter ; sera el smbolo que exprese el final de una excrecion matematica, para esto el compilador retornara un token con el smbolo SEMI de
ingles semi column que significa fin de linea. De esta misma manera se consideran los
caracteres:
+, , , (, y ). retornando el simbolo con el token: OP SU M A, OP REST A, OP M U LT ,
P AREN T ESIS IZQU IERDO y OP P AREN T ESIS DERECHO respectivamente.
Luego de ver esto se aprecia el token entero el mismo que esta dise
nado para retornar un
smbolo EN T ERO el mismo que sera cualesquier numero.
Cuando hablamos de una cadena el compilador fue dise
nado para aceptar cualquier de
estas en tanto las mismas no posean ning
un caracter especial y no empiecen con un entero,
por ultimo los espacios que son ignorados por el compilador.
Al final del analizador lexico se encuentra el smbolo [] en el cual se presentara un mensaje de error, cuando apreciaremos este error pues bien, el mismo se lanzara si y solo si el
7
F.
F.1.
Importaciones de java
package lexico.sintactico;
import java_cup.runtime.*;
import java.io.FileReader;
De igual forma que en el archivo punto flex, este codigo es codigo integro a copiar el
el punto java a generar, siendo la primera linea el paquete en donde se encontrara nuestro
punto java, las dos siguientes importaciones son necesarias la una para la ejecucion del
runtime de cup, y la otra para la leda y creacion de archivos con java.
F.2.
C
odigo del usuario para el parser
parser code {:
public void report_error(String message, Object info) {
System.err.println(message);
}
public void syntax_error(Symbol s) {
String key = (s.left + 1) + s.right + "";
String mensaje = ("\nError de sintaxis en linea "
+ (s.left + 1) +" columna " + s.right);
if(AnalizadorLexico.errores.get(key) == null) {
mensaje += ("\nAl simbolo " + s.value.toString()
+ " le antecede un entero falta el operador");
report_error(mensaje, null);
}else {
mensaje += ("\nERROR: entero o cadena <CARACTER INVALIDO> entero o cadena");
mensaje += ("\nCORRECTO: entero o cadena <OPERADOR> entero o cadena");
mensaje += ("\nAl simbolo " + s.value.toString()
+ " le antecede un token invalido");
mensaje += (" ==> "+ AnalizadorLexico.errores.get(key)+" <==");
report_error(mensaje, null);
}
}
8
F.3.
C
odigo del usuario, acciones de la gram
atica
F.4.
Declaraci
on de variables para la gram
atica
terminal
terminal Integer
terminal StringBuffer
CADENA;
F.5.
Gram
atica
/*
sentencia se compone de una exprecion seguida de SEMI.
asignacion:aestablece que a representa al objeto asociado a
asignacion, entre {: :} se coloca el c
odigo en java para las
acciones a tomar al cumplirse una producci
on.
*/
sentencia ::= exprecion:e
{:
System.out.println(" = " + e);
:}
SEMI
;
/*
exprecion puede ser una excreci
on matem
atica que empieza con numero
entero o palabra OP_SUMA exprecion, de esa forma se realizara una suma.
Tambi
en puede ser un numero entero, con esto se devuelve el valor del
entero. En RESULT se almacena el valor de las acciones, y se pasa al
siguiente nivel de la gram
atica. Si se encuentra una palaba se observa
que se recorre la misma obteniendo el ASCCI de cada caracter se suman
10
/*
Al encontrarnos una palabra la debolvemos creando un StringBuffer java
para manipularlo posteriormente
*/
palabra
::= palabra:p OP_MULT termino:e
{:
RESULT = new StringBuffer(e+""+p+"");
:}
;
/*
operacion sera el termino y un OP_MULT y termino, o solo un
termino si se realiza una multiplicaci
on y una suma esto le dar
a
prioridad a la multiplicaci
on
11
*/
operacion ::= operacion:f OP_MULT termino:e
{:
RESULT = new Integer(f.intValue() * e.intValue());
:}
|
termino:t
{:
RESULT = t;
:}
;
/*
termino fue pensado para que el compilador realice las operaciones con
prioridad en las expresiones que se encuentran dentro de los parentesis.
*/
termino
::= PARENTESIS_IZQUIERDO exprecion:e PARENTESIS_DERECHO
{:
RESULT = e;
:}
|
ENTERO:e
{:
RESULT = e;
:}
|
CADENA:c
{:
int sumLetras = 0;
StringBuffer letras = new StringBuffer(c);
for(int i=0; i< letras.length();i++)
{
sumLetras = sumLetras + letras.codePointAt(i);
}
RESULT = sumLetras;
:}
;
G.
Ejecuci
on compilador
Para la ejecucion de nuestro compilador tendremos una archivo punto txt el cual nos
servira para los datos de entrada del mismo, el cual posee la siguiente informacion:
1 + 19 - hola;
1 + dos * 2;
12
Una vez corrido nuestro main, el programa nos mostrara el siguiente men
u, en el
cual tendremos dos opciones digitar uno para generar los archivos y moverlos al paquete
correspondiente, o digitar dos para leer el archivo de entrada y probar nuestro compilador,
en este caso hemos digitado dos y se puede apreciar que no ocurrio ning
un error y el
compilador nos dio la respuesta que esperabamos.
ENTERO <1> SUMA ENTERO <19> RESTA CADENA <hola(104:111:108:97) > = -400
ENTERO <1> SUMA CADENA <dos(100:111:115) > MULTIPLICACION ENTERO <2> = 653
*********************************************
H.
Captura de errores
Para dar una mejor impresion en nuestro compilador hemos credo conveniente el
control de errores, no solo en el aspecto linea columna, si no que dar una idea d ello que
el usuario esta haciendo mal as: Si el usuario ingresa los siguientes datos como entrada:
1 + h19 - hola;
1 + dos 2;
El compilador nos muestra lo siguiente:
ENTERO <1> SUMA CADENA <h(104) >ENTERO <19>
Error de sintaxis en linea 1 columna 5
Al simbolo 19 le antecede un entero falta el operador
*********************************************
*************************************
*********ERROR IRECUPERABLE**********
*************************************
Expresando la linea columna del error sintactico y sugiriendo la posible solucion. Probemos ahora con un erro lexico:
1 + 19. - hola;
1 + dos 12 - 2;
El compilador mostrara lo siguiente:
ENTERO <1> SUMA ENTERO <19> RESTA CADENA <hola(104:111:108:97) >
************************************
****Caracter invalido ==> . <== ****
encontrado en la linea 1 y columna 7
************************************
= -400
ENTERO <1> SUMA CADENA <dos(100:111:115) >ENTERO <12>
*********************************************
13
I.
C
odigo fuente
14
J.
BIBLIOGRAFIA
Referencias
[1] Analizador
lexico.
Disponible
en:
http://es.slideshare.net/maryr_
/actividad-2-analizador-lxico-sintctico-y-semntico
[2] Archivo
Jlex.
Disponible
en:
http://www.cc.uah.es/ie/docencia/
ProcesadoresDeLenguaje/2.3.JLex.pdf
[3] Estructura del archivo Jlex. Disponible en: http://openfecks.wordpress.com/
jlex-y-cup/plantilla-archivo-jlex/
[4] Estructura de Archivo Cup: https://openfecks.wordpress.com/jlex-y-cup/
estructura-de-archivo-cup/
[5] Cup y el analisis semantico: http://www.escet.urjc.es/procesal/pracs/Cup_
tr_clase.pdf
15