Sei sulla pagina 1di 18

CIS-IXB-001

UNIVERSIDAD
NACIONAL
DE LOJA

Area
de la Energa las Industrias y los Recursos Naturales No Renovables

Carrera de Ingeniera en Sistemas

Desarrollar un compilador que


realice sumas de 2 o m
as n
umeros
binarios

Trabajo Final de Compiladores


Noveno B

Autores:
Jonathan Bladimir Arrobo Ajila

Docente: Ing. Henry-Paz,

Loja-Ecuador
2015

Indice
A. Problema

B. Introducci
on

C. Aut
omata

D. Desarrollo del Compilador


1 . Analizador Lexico . . . . . . . . . .
1 .1. Librera . . . . . . . . . . .
1 .2. Estructura del archivo JFlex
2 . Analizador sintactico . . . . . . . .
2 .1. Librera: . . . . . . . . . . .
2 .2. Estructura de Archivo Cup .

.
.
.
.
.
.

4
4
4
4
8
8
8

.
.
.
.

13
14
14
14
15

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

E. Funcionamiento del Compilador


1 . Generar clase Lexica . . . . . . . . . . . . . .
2 . Generar clase sintactica . . . . . . . . . . . . .
3 . Mover las clases al paquete suman binario
4 . Ejecutar . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.

F. Repositorio del c
odigo Fuente

18

G. BIBLIOGRAFIA

18

A.

Problema

Este problema fue creado debido a que no hay un compilador que acepte n
umeros
binarios y mucho menos realizar suma entre ellos sin convertir primero a decimales.
Por eso hemos credo conveniente realizar un compilador para los n
umeros binarios el
cual me va a permitir realizar lo siguiente.
Suma 2 o mas n
umeros binarios

1. El analizador lexico ignora los espacios juntando cada termino hasta que encuentre
un operador(+)
2. Para terminar la operaciones se debe poner ;
3. Se realiza la suma de los n
umeros binarios q se hayan ingresados
4. Se puede ingresar mas de una operacion
5. El resultado me da como numero decimal y binario
Ejemplo: 10001 + 0111;
Resultado= Decimal 24 Binario 11000

B.

Introducci
on

El presente informe se lo realizo con la finalidad de dar a conocer la creacion de un


compilador que realice la suma de n
umeros binarios. Para la realizacion de este compilador se utilizo un id como netbeans, un editor de texto que soporte java como sublime tex,
la librera Jflex para lo que es el analisis lexico y la librera CUP para el analisis sintactico.
El informe se encuentra dividido en: Problematica que describe por que se realizo este
compilador, Introduccion de todo el informe, Automata que me permita realizar la validacion de la cadena ingresada, Desarrollo del Compilador aqu en esta seccion se describe dos
putos muy importantes que es la creacion del compilador con los archivo para el analizador lexico donde de describe todo el codigo que fue utilizado para realizar este analizador
y Luego se tiene el analizador sintactico al igual que el analizador lexico aqu tambien
se describe todo su codigo utilizado para obtener el resultado deseado, Funcionamiento
del compilador cuando se ingrese cadenas validas e invalidas y sus respectivos errores y,
finalmente tenemos la bibliografa la la documentacion que se ha obtenido informacion
para realizar el presente proyecto.

C.

Aut
omata

El automata que se muestra en la figura 1 me va a permitir ver si se acepta la cadena


ingresada o no, Este es fundamental al momento de realizar la Gramatica en el analizador
sintactico.

Figura 1: Automata

D.
1.

Desarrollo del Compilador


Analizador L
exico

En esta seccion se realizara la primera fase de un compilador, es decir su analisis lexicografico, tambien denominado abreviadamente analisis lexico.

1 .1.

Librera

JFlex es un generador de analizador lexico (tambien conocido como generador de


escaner) para Java (TM) , escrito en Java (TM). Como Vern Paxson afirma por su C / C
++ herramienta flex: Ellos no comparten ning
un codigo.
La funcion principal del archivo Flex es leer los caracteres de entrada y elaborar como
salida una secuencia de componentes lexicos que utiliza el analizador sintactico para hacer
el analisis.[1]
1 .2.

Estructura del archivo JFlex

El texto se encuentra dividido en tres secciones separadas por % %, al igual que en


JFLex. Sin embargo, el contenido de cada seccion o area difiere con respecto a aquel,
4

siendo la estructura general de la forma:

Area
de codigo, importaciones y paquete
%%

Area
de opciones y declaraciones
%%

Area
de reglas[2]

Area
de c
odigo, importaciones y paquete
En esta area se realiza todas las importaciones que sean necesarias para crear la clase
lexica y tambien el paquete de donde se va a encontrar la clase que se va a crear que se
muestra en la figura 2.

Figura 2: Area
de codigo, importaciones y paquete

La primera instruccion nos dice que vamos a generar la clase lexica en el paquete
suma binario, la primera importacion nos indica la Liberia cup para poder tener una
conexion con el analizador sintactico y por ultimo tenemos java.io.Reader que es importacion para que me lea archivos ya que el analizador sintactico recibe un archivo y lo
va evaluando.

Area
de opciones y declaraciones
Este area permite indicar a JFlex una serie de opciones para adaptar el fichero java
resultante y que sera el que implemente nuestro analizador lexicografico en Java.
Opciones
Todas ellas empiezan por el caracter % y no pueden estar precedidas por nada en la
lnea en que aparecen, las opciones que utilizamos en el archivo lexico son las que se
muestran en la figura 3.

Figura 3: Seccion de opciones del archivo lexico

En el area de opciones tenemos que utilizar el % antes de cada opcion, la primera


opcion que tenemos es %class Analizadorlexico esto me indica el nombre de la clase
que se genera cuando llamamos a la librera jflex y le enviemos el archivo lexico, %line
y %column contador de lneas y columna si me da alg
un error vamos a saber de que parte
del archivo se encuentra ese error y as poder solucionar el error y finalmente tenemos
los metodos Symbol que me permitiran enviar el tipo de token encontrado con la lnea
y columna de donde fue ese token, tambien el tipo de dato que voy a enviar hacia el
analizador sintactico ya que sobrecargamos el mismo metodo.
Declaraciones
Las declaraciones que va a utilizar en nuestro alfabeto para la suma de n
umero binarios se muestran en la figura 4.

Figura 4: Declaraciones

Declaramos nuestro lenguaje que se va a utilizar para poder realizar las reglas lexicas,
Salto en esta variable se declara un salto de lnea para cuando en analizador sintactico
encuentre un salto de lnea o retorno de carro no me detecte a ese caracter, Esto es para
6

que se realiza en diferentes sistemas operativos(Linux y windows), Espacio esto es para


espacios, tabulacion y sato de pagino o el salto anterior que fue declarado para que todo
esto lo tome como un espacio y sean ignorados, por ultimo tenemos la declaracion de una
parte de nuestro lenguaje que es 0 y 1 como son los n
umeros binarios para realizar la
suma, la expresion dice que va a salir (0) o (0 y 1), por 0 o mas veces (1 y 0).

Area
de reglas
Esta seccion contiene expresiones regulares y acciones, las acciones son codigo en Java
que se ejecutara cuando se encuentre una entrada valida para la expresion regular correspondiente el cual se muestra en la figura 5.

Figura 5: Area
de Reglas

El area de reglas es el area mas importante porque aqu voy a decir como va a llegar
los datos al archivo sintactico. YYINITIAL este es el estado inicial del analizador lexico,
Las expresiones regulares solo seran comparadas si se encuentra en ese estado inicial. Es
decir, cada vez que se encuentra una coincidencia el scanner vuelve al estado inicial, Por
lo cual se ignoran estados intermedios, cuando el analizador lexico encuentre ; va a
devolver el token FIN LINEA que sera la finalizacion de una instruccion, + este es
otro token para realizar la suma entre 2 n
umeros binarios o mas, Binario cuando en
analizador lexico encuentre valores binario no importa cuantos sean siempre y cuando
sean(1y 0) hasta encontrar un signo + o un fin de lnea(;) ignorando los todos los espacios
declarados en la variable Espacio entonces devuelve el token BINARIO con todos los
binarios encontrados, (.) si se analizo todo el archivo y no se encontro ninguna coincidencia
entonces se va al error esto es para datos que no los encuentre en las reglas lexicas entonces
se enva el error al analizador sintactico.

2.
2 .1.

Analizador sint
actico
Librera:

Cup es un generador de analizadores sintacticos LALR en Java el cual recibe de entrada un archivo con la estructura de la gramatica y su salida es un parser escrito en Java
listo para usarse.
Decid dividir el tutorial en varias secciones para hacer mas facil el aprendizaje de
estas herramientas.[2]
2 .2.

Estructura de Archivo Cup

A continuacion detallare como se estructura un archivo de entrada para Cup.

Imports
En esta seccion creo que no tengo que ampliar mucho desde que programamos Java
sabemos como son los imports de librerias. Al igual que en el archivo jflex aqu en el archivo
cup tambien se realiza como primer paso las importaciones se describe en la figura 6.

Figura 6: Imports.

Primero se pone el nombre del paquete donde se va a generar la clase que es suman binario, luego se encuentra importacion para trabajar en tiempo real y la importacion del FileReader para que lea archivos cuando se ingrese los datos a compilar.

C
odigo del Usuario para el Parser:
Como el codigo Java es generado por la herramienta es muy difcil modificar lo en el
archivo de salida. As que aqu podemos declarar metodos y variables que pensamos usar
en la clase resultante. Si se declaran variables o metodos p
ublicos en esta seccion estos
podran ser accedidos por otras clases. Los metodos para controlar errores se pueden ver
en la figura 7 que es codigo java.

Figura 7: Errores encontrados

Para este metodo de errores encontrados se revise 2 parametros el mensaje de error y un


objeto que me da el token que produjo ese error, mensaje declaramos una variable para almacenar los errores encontrados, el primer if (info instanceof java cup.runtime.Symbol)
va a ingresar si los el info es del mismo tipo de java cup.tuntime.Symbol. Declaramos una
variable de tipo java cup.runtime.Symbol y realizamos un casting a info, luego revisa
que la variables s sea mayor 0 igual a 0, esto sirve para ver en que lnea y que columna
se encuentra el error y, se almacena en la variable mensaje como se puede observar el la
figura 8,

Figura 8: Numero de lnea y Columna del token

Como recibimos un objeto info entonces a ese objeto lo convertimos a un String y


separamos con el Split debido a que ese token vienen los valore con un numeral(#2)
9

entonces nos toca separar solo dejar el valor 2, una vez separado lo comparamos con la
clase sym a ver de cuales de los tokens me esta dando un error, finalmente imprimimos el
error as para todo el lenguaje como se muestra en la figura 9.

Figura 9: : Errores de Tokens

En la siguiente figura 10 llamamos al metodo report fatal error Cuando se encuentra un error de donde el sistema no puede recuperarse, se lanza un error fatal y se verifica
que tipo de error es llamando al metodo creado en la figura 9.

Figura 10: Error Fatal

Modificamos el metodo main, este metodo me recibe como parametro el archivo con
los datos a compilar, creamos una variable de tipo Objeto, Luego creamos un objetos de
la clase sintactico (AnalizadorSintactico) y nos pide como parametro un archivo de tipo
File, luego ejecutamos llamando al metodo parse() y cuando se encuentra una excepcion
se imprime un mensaje Ocurrio un error esto se encuentra en la figura 11.

10

Figura 11: Metodo main

En la siguiente figura 12 del codigo de usuario tenemos la transformacion de binarios


a decimales.

Figura 12: Convertir binario a decimal

Recibimos como parametro un string y devuelve un valor entero, la siguiente lnea es


la conversion de binarios a decimales utilizando un metodo propio de java, por u
ltimo
retornamos el valor convertido.
Por Ultimo tenemos el metodo para transformar de decimal a binario este metodo va a
realizar la trasformacion de binario a decimal una vez ya obtenido el resultado en decimal
tambien lo vamos a presentar en binario descrito en la siguiente figura 13.

Figura 13: Conversion de Decimal a Binario

11

El metodo recibe como parametro un n


umero entero y devuelve un String, luego
declaramos 2 variables de tipo int y una de tipo double, la variable exp y binario la
igualamos a 0, utilizamos el while hasta q sea n
umero diferente de 0, luego realizamos la
conversion de decimal a binario y al final vamos almacenando el binario en la variable res
y finalmente devolvemos a la variable.
Declaraci
on de Variables para la Gram
atica:
En esta seccion toca declarar las variables que se utilizaran en la gramatica, estas
variables pueden ser de dos tipos:
Variables Terminales Variables No Terminales
Las variables declaradas que son terminales y no terminales como se puede ver en la
siguiente figura 14.

Figura 14: Terminales y no Terminales

Las variables terminales son las mismas que nosotros hablamos en el analizador lexico
de las expresiones regulares ya que los terminales seran los tokens que se encuentren en
la clase sym, cada terminal de debe declarar con su tipo de dato o en el caso de no saber
que tipo de dato es se deja un espacio y solo se pone el nombre de la variable en nuestro
caso los terminales son FIN LINEA, SUMA y el terminal de tipo entero es BINARIO.
Los no terminales son las variables que voy a utilizar en la gramatica igual que en las
terminales las no terminales tambien hay q indicar el tipo de dato que es o si no se pone
un Object en caso de no saber que tipo es, los no terminales que son de tipo Object es
expr list, expr part y final mente el no terminal de tipo entero expr.

Gram
atica
En esta seccion del archivo es donde escribiremos nuestra gramatica. En esta seccion
se declara la gramatica que vamos a utilizar, Se describe en la figura 15.

12

Figura 15: Gramatica

La gramatica va a empezar a leer de abajo para arriba. Entonces como u


ltima lnea
tenemos que cuando ingrese un binario me lo almacena en la variable expr que es de
tipo Integer llamando al metodo conversion que se encuentra en codigo de usuario en la
figura 13 o cuando tenga un valor la variable expr el token SUMA y un BINARIO
entonces obtengo al valor de expr mediante una variable e, luego realizo la suma con el
nuevo binario que va ingresando pero antes lo convierto llamando nuevamente al metodo
conversi
on, almacenado el valor con RESULT para asignarle ese valor a la variable expr.
La variable expr part va a ingresar si tengo un valor en la variable expr y seguido
del token FIN LINEA entonces almaceno el valor de expr en expr part e imprimo el
valor de la primera instruccion encontrada y tambien llamamos al metodo de convertir de
decimal a binario para imprimir el resultado en binario.
Por ultimo tenemos la variable expr list esta variable me permite poner en el archivo
varias lneas de codigo separadas por el fin de lnea cada instruccion y me vaya mostrando
cada resultado con lo explicado anteriormente.

E.

Funcionamiento del Compilador

Luego de a ver creado el archivo lexico y sintactico tenemos que generar las clase java
tanto del sintactico como lexico.

13

1.

Generar clase L
exica

Una vez terminadas todas las areas dela analizador lexico ya lo podemos generar la
clase lexica esto se muestra en la figura 16.

Figura 16: Ejecucion del archivo lexico

Para ejecutar el archivo lexico lo primero que tenemos que hacer es declarar una variable de tipo String lexico y asignarle el nombre del archivo que descrito anteriormente
que sera alexico.flex, File file se declara una variable de tipo File y se le enva como parametro la variable que fue creada anteriormente con el nombre del archivo lexico,
jflex.Main.generate(file) esta lnea de codigo llama a la librera Jflex para generar la
clase lexica con el nombre de AnalizadorLexico.java.

2.

Generar clase sint


actica

Las lneas descritas en la figura 17 son para ejecutar el archivo cup y se generen las
clases java para poder ya probar el compilador. La primera lnea es una palabra reservada
que indica que se va a trabajar con el archivo sintactico, La siguiente lnea es el nombre
de como se va a llamar la clase y por u
ltimo el archivo sintactico (archSintactico), luego
se llama a la librera cup y se le enva el arreglo asintactico para que se genera la clase
sintactica (AnalizadorSintactico.iava).

Figura 17: Ejecucion del archivo cup

3.

Mover las clases al paquete suman binario

Una vez ya creadas las 2 clase sintactica y lexica tenemos que mover estas clases al
paquete (suman binario) de nuestro proyecto ya que cuando se generar las clases estas
se generan en donde encuentra los archivos lexico y sintactico como se muestra en la figura
18.

14

Figura 18: Mover archivos

El metodo moverArch recibe como parametro un string con el nombre del archivo
que se va a mover y devuelve un valor booleano dependiendo si se pudo mover el archivo
o no, se crea una instancia de la clase File le enviamos como parametro el nombre del
archivo, luego verificamos si el archivo existe y lo movemos al package suman binario
pero en caso de no encontrar el archivo me presentara un mensaje, finalmente devolvemos
un valor booleano si se ha podido o no mover el archivo.

4.

Ejecutar

Para probar si el compilador que fue creado funciona correctamente realizamos lo


siguiente figura 19.

15

Figura 19: Ejecutar Compilador

Lo primero que debemos es tener el archivo que se va a enviar a compilar entonces


pedimos que ingrese las operacion por consola y la almacenamos una variable cadena,
Luego creamos el archivo con la variable fichero, Despues de tener el archivo escribimos en el archivo lo que fue ingresado desde consola, creamos un arreglo de tipo String
y le enviamos el nombre del archivo creado que tiene que estar con los datos a analizar (10101+1111;) luego se llama a la clase AnalizadorSintactico que se creo cuando
compilamos el archivo cup, se le enva el arreglo y finalmente serramos este la ejecucion.
Resultados
Cuando ejecutamos nos da 3 opciones para seleccionar la primera si queremos generar
las clases, la segunda ejecutar el compilador y la tercera salir esto se describo en la figura
20.

Figura 20: Opciones de ejecucion

Cuando se selecciona la opcion 2 me pide que ingrese una cadena para evaluarla
as como en la siguiente figura 21, Como la cadena esta bien me da el resultado deseado.
16

Figura 21: Cadena aceptada

Pero si la cadena que ingresamos se encuentra caracteres no conocidos entonces me


da un error como en la siguiente figura 22. La cadena no va hacer aceptada y dice que
caracter esta mal y en que lnea y columna del archivo se encuentra dicho caracter.

Figura 22: Caracter Desconocido

Si el error es cuando esta mal estructurado no cumple con el automata pero todos sus
caracteres estan en el lenguaje del automata da el error de la figura 23. La cadena no es
aceptada y muestra un mensaje con la lnea y columna que esta el caracter mal y que
caracter es el que no consta en el lenguaje.

Figura 23: Errores de la Estructura

El ultimo tipo de error que tenemos es cuando me falta un Fin de lnea(;) como se
muestra en la figura 24: La cadena no es aceptada y muestra un mensaje informando que
falta el fin de lnea(;)

Figura 24: Errores de la Estructura

17

F.

Repositorio del c
odigo Fuente

Para su mejor compresion se puede visualizar el codigo en la siguiente direccion https:


//gist.github.com/jbarroboa/33be994c7cfd956c7758, en este repositorio solo esta el
archivo lexico, sintactico y el de ejecucion, Con estos archivos se genera el compilador.
Si se quiere descargar el proyecto completo lo puede descargar de la siguiente direccion
https://mega.co.nz/#!6Nw0CQbR!9eGy72424QS648w6d2Pd4yXeQauYX-ivln3ew4uK3BU.

G.

BIBLIOGRAFIA

Referencias
[1] Gandhy. (s.f.). open (fecks());. Obtenido de https://openfecks.wordpress.com/
jlex-y-cup/plantilla-archivo-jlex/
[2] Microsystems, S. (21 de 06 de 2014). JFlex - El Scanner Generador rapido para Java.
Obtenido de http://www.jflex.de/

18

Potrebbero piacerti anche