Está en la página 1de 17

CIS-IXB-001

UNIVERSIDAD
NACIONAL
DE LOJA

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

Carrera de Ingeniera en Sistemas

Desarrollo de un compilador que


permita la conversi
on de may
usculas
a min
usculas y viceversa

Trabajo Final de Compiladores


Noveno B

Autores:
Priscilla Lourdes Pacheco Ordo
nez

Docente: Ing. Henry-Paz,

Loja-Ecuador
2015

Indice
A. Problema

B. Introducci
on

C. Aut
omata

D. Requerimientos

E. Descripci
on del c
odigo
1 . Codificacion del Analizador Lexico o archivo .flex . . . . . . . . . . . . . .
2 . Analizador sintactico o archivo .cup . . . . . . . . . . . . . . . . . . . . . .

4
4
7

F. Funcionamiento del Compilador

14

G. Repositorio del c
odigo

17

A.

Problema

El presente informe se realizo con el objetivo de dar a conocer una idea mas de desarrollar un compilador, ya que en internet la informacion es muy limitada y no muy bien
comprensible para cup, y en cuanto a ejemplos solamente muestra uno o dos ejemplos, el
cual nos permite estar muy estaticos en cuanto a estructura se refiere. Es por ello que se
cree conveniente el desarrollo de un COMPILADOR CON ESTRUCTURA FLEX
DE LETRAS MAYUSCULAS

Y CUP QUE PERMITA LA CONVERSION

A MINUSCULAS Y VICEVERSA, este ejemplo se realiza de una manera sencilla


con el fin de mostrar una buena manera de crear un compilador.
Un ejemplo del compilador sera el siguiente:
Permitir el ingreso de letras may
usculas o min
usculas
En caso de un espacio debe estar entre las letras o palabras, este es tomado como
un String mas y es aceptable.
Al final de la oracion, letra o palabra se debe obligatoriamente ingresar un (;), que
nos indica el fin de la conversion.
En caso de ingresar cualquier caracter o smbolo que no sea el alfabeto debe presentar
el tipo de error y donde esta localizado.

B.

Introducci
on

El presente informe describira paso a paso la estructura de los archivos flex o analizador
lexico y cup o analizador sintactico, ademas una ilustracion del automata y finalmente su
ejecucion del los archivos, este informe pretende generar conocimientos academicos y la
manera mas sencilla de construir un compilador definiendo nuestro propio lenguajes.

C.

Aut
omata

Figura 1: Automata

D.

Requerimientos

Los requerimientos necesarios para el desarrollo del compilador de conversion de letras,


necesitamos:
Tener las libreras jflex-1.5.0.jar y java-cup-11a.jar
Conocer La estructura basica del archivo flex y cup
Un IDE como Netbeans
El dise
no de automata del convertir letras.

E.

Descripci
on del c
odigo

1.

Codificaci
on del Analizador L
exico o archivo .flex

Importaciones
Esta es la seccion inicial el cual se agregar los paquetes e importaciones, en la parte
de los paquetes se ingresa el nombre de donde se va a generar el archivo .java, el cual se
crea automaticamente de acuerdo a la ejecucion del archivo lexico1.flex, es el nombre
que le daremos en el archivo flex.
Las importaciones se agregan de las clases propias con las que permite integrar la
librera para flex (jflex1.5.0.jar) en su u
ltima version. La primera importacion es de
la cup para integrar con el flex, al siguiente es para leer un archivo que se ingresa
para evaluar las sentencias que se tenga dentro del archivo. Para comprender mejor las
importaciones tenemos la siguiente figura 2.

Figura 2: Importaciones

Declaraci
on de opciones
A traves de esta seccion se puede agregar opcionalmente, esto sirve de mucho en caso
de querer corregir los errores, como es el caso de %line y %column, donde me muestra la
posicion del error, para entender mejor sera las siguientes lneas de codigo.

%class nos permite asignar el nombre de la clase que vamos a generar, %cup, vamos
a mostrar la compatibilidad entre el archivo lexico y sintactico. Su comprension se dara
en la siguiente figura 3.

Figura 3: Declaracion de opciones

M
etodos para generar Smbolos con c
odigo java
Tanto flex y cup, permiten generar codigo en java para trabajar, tal es el caso que
dentro de la misma seccion del archivo flex se puede agregar codigo java, por ejemplo la
creacion de metodos Symbol que son propias de la librera cup (java cup.Symbol).
Para la agregacion del codigo java, el archivo flex accede si se encuentra dentro de
unos smbolos de porcentaje y llaves.

%{ Aqu c
odigo java %}
Este metodo nos permite enviar el n
umero de token que sera el identificativo de las
variables (FINLINEA, MAYUSCULAS, MINUSCULAS) que se declaren como prioridad
y que seran utilizadas en el cup a traves de la generacion automatica de la clase Sym
que proviene de la clase Symbol de la librera cup.
Se sobre carga el metodo symbol, en el primer metodo se ingresa un parametro con valor entero que es igual al n
umero que se asigno en la clase Sym y es representado por type,
el segundo parametro es el n
umero de lnea representado por yyline, finalmente que el
tercer parametro se asigna el n
umero de columna representado por yycolumn. Mientras
que en el segundo metodo se agrega un parametro llamaso Object value que se utiliza
en caso de tener el tipo de variable pero su valor y adicionalmente para mostrar el error
con una posicion de lnea y columna. De la manera que se muestra en la siguiente figura 4.

Figura 4: Codigo java, metodos para reconocer smbolos

Declaraci
on
Seguimos con las expresiones regulares que tambien se encuentran dentro de la segunda
seccion, en mi caso de conversion de letras yo creo variables llamadas Salto, Espacio,
EspacioAcept, Lminuscula, Lmayuscula, es aqu donde declaramos las variables a
utilizarse en el archivo flex para darle la parte lexica al compilador como se muestra en
la figura 5.

Figura 5: Declaracion de variables

Area
de reglas l
exica
Tercera seccion las reglas Lexicas, en este bloque se debe describir la parte lexica que
conforma mi compilador es decir como reconocera a cada caracter o llamados token, y
en caso de no estar comprendido por las expresiones regulares declaradas anteriormente,
debera generar un tipo de error con su respectiva posicion, adicionalmente tomamos un
operador ; que nos servira en el caso de terminar el ingreso de los caracteres, es decir

sera el fin de lnea.


Todo esto se encuentra comprendido en un YYINITIAL {. . . } con este comando
propio de flex decimos que damos inicio al analisis del archivo entrante, para mejor compresion se tiene el siguiente figura 6.
Entonces como hemos declarado anteriormente si identificamos el ; representamos
con el token FINLINEA que es aceptable como el final de sentencia para la conversion.
La segunda opcion es Lminusculas que nos indica que un smbolo min
usculo es aceptable
con el token MINUSCULA, igualmente Lmayusculas para letras may
usculas que se
representa con el token MAYUSCULA, espacios representados con la variable EspacioAcept y el token es ESPACIO ,y en caso de tabuladores, nueva pagina, etc estos son
ignorados. Si es el caso que ninguno de los smbolos descritos anteriormente son reconocidos entonces nos indicara que es un caracter invalido. Asi como se muestra en la siguiente
figura 6.

Figura 6: Reglas Lexicas, es el sentido lexico

2.

Analizador sint
actico o archivo .cup

Para mostrar el archivo cup o analizador sintactico, iniciamos conociendo las secciones
con las que cuenta el mismo. Las secciones del cup son 1. Declaracion de los paquetes,
2. Seccion de codigo de usuario, 3. Declaracion de smbolos terminales y no terminales,
4. Declaracion de precedencias este es opcional y 5. Definicion del smbolo inicial de la
gramatica y reglas de produccion.

Importaciones
Iniciamos con las importaciones las cuales en el paquete decimos que el paquete en
donde se va a encontrar el nuevo archivo ejecutado en .java del AnalizadorSintactico.java, y las otras importaciones son las mismas que se describieron en el archivo lexico,
java cp.runtime.* nos dice que vamos a trabajar en tiempo real, mientras que la siguiente importacion nos deja leer archivos. Para comprender mejor entonces veamos la
figura 7.

Figura 7: Declaracion de importaciones

C
odigo del Usuario para el Parser
En la segunda seccion nos encontramos con el codigo de usuario, el cual se escribe en
codigo java, metodos para reportar los errores, en el caso de mi ejemplo cuento con el
primer metodo llamado report error, el cual recibe dos parametros el mensaje que es
tipo String para decir si existe alg
un tipo de error, el segundo parametro en cambio es
info y de tipo object, el cual nos sirve para conocer cual es el objeto o n
umero de token, es
decir; en la clase Sym que se generaba anteriormente por la clases Symbol, este se genera
automaticamente un numero u
nico para cada variables, de la manera que se mostrara a
continuacion en la figura 8.

Figura 8: Codigo de la clase Sym


Estos cuentan con un numero u
nico, que sera representado con el parametro info,
entonces iniciamos creando un objeto m, de tipo StringBuffer que representa una
cadena cuyo tama
no puede variar, otra variable info1 de tipo String y un info2 que es
8

un arreglo tipo String que contiene un Split indicando que si tiene un # ya que la variable
info bien el id del token con un #, entonces hay que separar y solo dejar un valor entero
y lo almacenamos en la variable info2, para poder comparar con los id de los tokens de
la clase sym, entonces primero preguntamos si el valor EOF que se mostros en la figura
anterior es igual al valor de la variable almacenada en el array simplemente le mostramos
un mensaje indicando que falta un ; para el fin de lnea.
Pero si es lo contrario preguntamos si FINLINEA es igual al valor que mantiene el
array info2, para decirle que existe un error de ;, esto en caso de tener una duplicacion
de fin de lnea. Ejemplo:
hola COMO Estas;;
Entonces si esto ha pasado, lo que procede es a preguntar si la variable info es una
instancia de la clase java cup.rintime.Symbol, es decir: que tiene el mismo tipo, nos
permite conocer la ubicacion del error y as finalmente mostrar cual fue el error y en
que posicion la podemos corregir. Una vez culminado con el recorrido este es agregado en
la variable m, para mostrar el mensaje final. Para comprender mejor el codigo tenemos
la siguiente figura 9.

Figura 9: Codigo java para presentar errores


El segundo metodo lo conoceremos como report fatal error, entonces en este metodo
llamamos al metodo creado de error que se encuentra en la figura 9, finalmente el ultimo
9

metodo que tenemos es el main el cual contiene un objeto que vamos a crear en el archivo
cup llamado AnalizadorSintactico.java, este archivo sera ledo y evaluado a traves de
un metodo interno de cup, conocido tambien como parse(). Si esto se genera bien de
acuerdo a las reglas sintacticas simplemente me muestra un mensaje de haber finalizado
con la ejecucion de conversion de letras del archivo entrante o test1.txt. Para comprender
mejor mostraremos en la figura 10.

Figura 10: Segunda parte de los metodos de error

Ahora el codigo completo comprendido para el reconocimiento de errores seria: para


ingresar el codigo java se debe ingresar en el metodo general.

10

Figura 11: Codigo completo del metodo parser code

Declaraci
on de los Terminales y no Terminales
La tercera parte en la declaracion de terminales y no terminales, el cual en la parte de
los terminales iran aquellas variables que fueron creadas en la parte lexica (MINUSCULAS, MAYUSCULAS, etc) la declaracion se detalla en la figura 12.

Figura 12: Declaracion de los smbolos terminales


Ahora veremos como se declara los smbolos no terminales, existen dos tipos de smbolos no terminales: los que tienen un tipo valor por ejemplo String expr y los que no tiene
11

valor como expr list tipo Object, en el caso de la utilizacion del segundo se utiliza
cuando no conocemos el valor de la expresion, esto lo explicaremos mas adelante por
ahora la definicion de los no terminales en la figura 13.

Figura 13: Declaracion de los smbolos no terminales

Dependencias
En esta seccion, tenemos la asignacion de las dependencias que son opcionales, estas
nos sirven para dar prioridad a las variables y son ledas de abajo hacia arriba para la
prioridad. En el caso de mi ejemplo no lo utilizo ya que se utiliza mas para trabajar con
operaciones matematicas, en cambio yo realizo la conversion de letras.
Gram
atica
En la u
ltima seccion es darle un sentido sintactico o de escritura a las palabras de
entrada, para ello los smbolos que se describieron en los terminales y no terminales son
utilizados, es as que tambien le damos prioridad desde abajo hacia arriba en mi ejemplo
se desea hacer la conversion de letras como lo siguiente:

hola COMO Estas; === HOLA como eSTAS


Para el ejemplo en caso que inicie con un espacio no le da problemas, ya que tambien
es aceptable para la conversion, en caso de ingresarse con n
umeros me dice que numero
es el error y su posicion, o si despues del espacio encuentra una letra la toma y realiza
la conversion, finalmente la que la sentencia sea aceptada debe terminar con un punto y
coma En la parte final del informe se describira mejor con un ejemplo ya convertido.
Para la explicar la gramatica se debe comprender que su lectura es de abajo hacia
arriba, para ello utilizamos expr que va hacer la variable que almacenaremos el smbolo
que reconozca como aceptables.
Cuando comenzamos a analizar un archivo, primero va al final debido a que en la
variable expr no se encuentra ning
un valor, entonces verifica que tipo de tokens es y en
el caso de ser min
uscula o may
uscula lo convertimos a lo contrario y lo almacenamos en
expr(RESULT) pero cuando es un espacio solo lo almacenamos en la variable expr,
una vez que la variable expr tenga ya un valor entonces se crea una variable de expr(e)
12

para poder obtener el valor anterior y lo concatenamos con el nuevo valor que depende del
token que sea si es min
uscula lo convertimos a may
uscula y lo contrario con la may
uscula,
pero si es espacio solo lo concatenamos y a esa concatenacion nuevamente la almacenamos
en expr, para su mejor comprension se muestra en la figura 14.

Figura 14: Codigo de la variable expr

Una vez que tenemos claro como funciona la lectura y que se almacena en la variable
expr, entonces decimos que esta expresion para ser aceptada debe finalizar con un FINLINEA o conocido en el lexico por un smbolo de ;.Creamos una variable de expr(e)
y la imprimimos siempre y cuando este con un FINLINEA. Para mejor comprension
tenemos la figura 15.

Figura 15: Codigo de la variable expr part

Finalmente la u
ltima parte de la gramatica que tenemos es la de variable expr list, en
esta parte lo que hacemos es que en caso de tener varias lneas de entrada con terminacion
de ; me va a permitir convertir sus letras de entrada y ser presentadas en la consola.
Se debe recordar que la lectura de la gramatica inicia de abajo hacia arriba, por lo tanto
13

expr va estar contenida en expr part y este a su vez de expr list. Como se muestra en
la figura 16.

Figura 16: Codigo de gramatica

F.

Funcionamiento del Compilador

Generar clase L
exica
Una vez estructurado bien el archivo lexico1.flex ya lo podemos generar la clase lexica
esto se muestra en la figura 17.

14

Figura 17: Ejecucion del archivo lexico

Para ejecutar el archivo lexico lo primero que tenemos que hacer es saber cuan es el
nombre del archivo lexico en nuestro caso se llama lexico1.flex entonces llamamos a la
librera Jflex al main que recibe como parametro un archivo entonces le enviamos el
nombre de archivo lexico(lexico1.flex)
Generar clase sint
actica
Al igual que el analizador lexico en el analizador sintactico tenemos que tener bien
estructurado para generar la clase sintactica, como se muestra en la figura 18.

Figura 18: Ejecucion del archivo cup


Primero se crea una variable de tipo string y se almacena el nombre del archivo
cup(sintactico1.cup). Luego se crea un arreglo de tipo Sting que se le enva tres datos
el objeto de la clase sintactica, en nombre de como se va a llamar la clase y el archivo donde
sintactico con extension cup(archSintactico), luego se llama a la librera cup y se le enva
el arreglo asintactico para que se genera la clase sintactica(AnalizadorSintactico.java).

Ejecuci
on
Para la ejecucion necesitamos el archivo con las sentencias que se va a evaluar como
se muestra en la figura 19.

Figura 19: Ejecucion del compilador


Se crea un arreglo de tipo string(archivoPrueba) y se almacena el nombre del archivo
que se va a compilar vale recalcar que este archivo ya fue creado anteriormente y se ingreso
las sentencias a evaluar, luego se llama al metodo main de la clase AnalizadorSintactico
y se ejecuta.
15

Errores
Evaluar las cadenas se dan un sinn
umero de errores.
Error de caracteres no declarados
Su entrada seria como se muestra en la figura 20:

Figura 20: Cadena de entrada

Mientras que la salida sera la siguiente, porque existe un error al no encontrar ese
caracter (12) declarado dentro del lenguaje del automata y me presenta un mensaje describiendo cual fue el error. Esto se puede visualizar en la figura 21.

Figura 21: error de caracter ilegal

Errores de fin de linea


Como describimos en la figura 14 que para que una cadena sea aceptada tiene que
tener un fin de lnea y si no la tienen la cadena no sera aceptada, me presenta un mensaje
informando que falta el FINLINEA, esto se puede ver en la figura 22.

Figura 22: Errores de fin de lnea

16

Ejecuci
on sin errores:
Para el ejemplo en caso que inicie con un espacio no le da problemas, ya que tambien
es aceptable para la conversion, en caso de ingresarse con n
umeros me dice que numero
es el error y su posicion, o si despues del espacio encuentra una letra la toma y realiza
la conversion, finalmente la que la sentencia sea aceptada debe terminar con un punto y
coma En la parte final del informe se describira mejor con un ejemplo ya convertido.
La sentencia de entrada del archivo test1.txt, incluye espacio como se ve en la figura
23:

Figura 23: Dato de Entrada

Y la salida por consola sera, un mensaje con la cadena transformada que es el resultado
de el compilador como se muestra figura 24:

Figura 24: Ejecucion sin errores

G.

Repositorio del c
odigo
visualizacion del codigo: https://github.com/plpachecoo/Convertir-Letras/tree/
FlexCup1

codigo comprimido: https://mega.co.nz/#!Kh03WRSB!Srm5zMHkDfC3sLOj8OCjHnP0Pr4uQoPF

17

También podría gustarte