1. CIS-IXB-001
UNIVERSIDAD
NACIONAL
DE LOJA
´Area de la Energ´ıa las Industrias y los Recursos Naturales No Renovables
Carrera de Ingenier´ıa en Sistemas
” COMPILADOR: CONVERTIDOR
DE N ´UMEROS EN LETRAS A SU
VALOR ENTERO ”
Tarea- Extra Clase
Noveno B
Autor: Sheimy Liliana Pati˜no Rivera.
Docente: Ing. Henry Paz.
Fecha: 13-02-2015
Loja-Ecuador
2015
Tarea de Compiladores. By Sheimy Liliana Pati˜no Rivera is licensed Under a Creative
Commons Reconocimiento-NoComercial-CompartirIgual 3.0 Unported License.
1
3. A. INTRODUCCI´ON
Desde el punto de vista de un profesional inform´atico, practicamente todas las accio-
nes que se va a ver obligado a desarrollar estara relacionado con traductores, como es la
programaci´on, creaci´on de ficheros, utilizaci´on de interpretes, entre otros.
En este caso se va a tratar sobre los compiladores, mismos que son programas que leen
un programa escrito en determinado lenguaje, y lo traduce a un programa equivalente en
otro lenguaje. Por lo cual trabajar con compiladores incluye saber cuales seran los token,
lexemas y patrones.
Existen dos partes importantes dentro del compilador, el analizador l´exico que es el que
ayuda a leer los caracteres de entrada para formar componentes, identificarlos y pasarlos
al analizador sint´actico quien sera el encargado de determinar si el ingreso de los carcteres
tiene sentido sint´actico, y en caso que exista errores que indique el porque se dan.
1 . Analizador l´exico
Para crear un AL hay que [1]:
• Especificar todos los tokens del lenguaje.
• Puede haber varios tokens que correspondan a una misma expresi´on regular.
• En este caso el algoritmo asociado a la expresi´on regular deber´a diferenciar a
partir del lexema el token.
Funcionamiento:
• Hay una variable (texto) que contiene el lexema encontrado al reconocer un
determinado patr´on.
• Cada vez que se llama al AL, ´este va leyendo caracteres hasta encontrar un
lexema que pertenece a un lenguaje descrito por una expresi´on regular.
• En ese momento est´a el lexema completo y se ejecuta el algoritmo asociado.
• El valor asociado que devuelve el AL var´ıa de un token a otro.
2 . Analizador Sint´actico
Funcionamiento:
El analizador sintactico arranca.
Solicita un token.
El Scanner lo devulve de acuerdo a la codificaci´on Sym.
3
4. B. CASO DE ESTUDIO
Aplicando los conocimiento recibidos en clase referente a la materia de compiladores,
se pretende solucionar el siguiente problema:
El compilador que se a desarrollado nos permitira realizar la conversi´on de los n´umeros
del 1-9 y de 10 en 10 hasta el 100, ejemplo: uno=1; diez=10; cien=100.
1 . Estructura del archivo FLEX
Un archivo .flex esta dividido en tres partes [2]:
Opciones y declaraciones.
C´odigo de usuario.
Reglas lexicogr´aficas.
1 .1. Opciones y declaraciones
Se importan todos los paquetes que se van a utilizar en nuestro analizador, despues
se pone un par de % para decir que desde ahi inicia el bloque de configuraci´on, mismo
que define un conjunto de parametros que iniciaran con un %, estos indicaran al analizar
como se debe comportar.
Donde:
package <nombrePaquete>: debemos poner el nombre del paquete en el cual se va
a crear el codigo java de archivo flex.
import java cup.runtime.*: esto importamos para que el archivo flex tengo sincro-
nizaci´on con el archivo cup.
%class <nombreClase>: comunica a Jflex como se va a llamar la clase.
%cup: establece la compatibilidad de Jflex con CUP.
%line: permite que se puedan contar las l´ıneas.
%column: permite que se puedan contar las columnas.
4
5. 1 .2. C´odigo de usuario
En este bloque se puede incluir codigo Java, mismo que se lo usara en el analizador,
este c´odigo se encuentra entre % %, este codigo sera copiado nitidamente en la clase .java
Aqui por ejemplo tenemos la creaci´on de dos m´etodos:
1. Generamos un Symbol para guardar el tipo de token encontrado.
2. Generamos un Symbol para el tipo de token encontrado junto con su valor.
1 .3. Reglas lexicogr´aficas
Este bloque es una parte muy importante dentro del analizador, aqui se define el con-
junto de expresiones regulares que seran utilizadas en el an´alisis. El analizador va leyendo
la cadena de entrada y activa la expresi´on que tiene mayor longitud.
Donde:
Salto: es para tener en cuenta el salto de linea en el texto, r y n son por el sistema
operativo en el que este.
Espacio: es para tener en cuenta el espacio en el texto, aqui llamamos al Salto y
ademas tenemos en cuenta el tabulador y avance de p´agina.
Se pueden utilizar los ambientes l´exicos: funcionan como una condici´on, como es el YYI-
NITIAL con el cual se empieza a escanear, para inicar este estado se debe anterponer un
par de %.
M´etodos: los m´etodos que se utilizan para obtener los valores de los token son:
String yytext(): devuelve lo que se ha le´ıdo.
Int yyline(): devuelve la l´ınea de la entrada actual pero empezando en 0.
Int column(): devuelve la columna.
5
6. Donde:
” < valorToken > ”: valor que tendra el token, ejemplo ”;”.
{System.out.print(); : valor con el que se va a presentar al momento de necesitarlo.
return symbol(sym.FL,yyline,yycolumn);}: valor que retorna a la clase Sym que es
la que almacena los token, FL es el valor del token. Despu´es de establecer el valor
de todos los tokens se indica que pasa si el caracter ingresado no esta declarado,
para ello se hace:
.{System.err.println(”caracterinvalido : ”+ yytext()+ yyyline()+1+yycolumn()+1);}:
aqui se esta mostrando el texto mal, la linea y columna en la que se encuentra.
6
7. 1 .4. Ejecuci´on en java
Para la generaci´on del codigo en .java se debe importar la libreria .flex dentro de un
proyecto en cualquir ID, en este caso se usa Netbeans y especificamente con la libreria
jflex.Main.main(); y se lo hace de la siguiente manera:
1: Se crea una variable tipo cadena.
2: Hacer un sentencia if, donde primero evaluamos que la variable de tipo cadena
sea sea mayor a 0, si es as´ı entonces igualamos la variable al archivo de tipo flex.
3: Se crea una variable de tipo cadena pero en arreglo y la igualamos a la varible se
creo en el paso 1.
4: Se hace el uso de la libreria jflex y se le envia como parametro el archivo creado
en el paso 3.
2 . Estructura de un archivo CUP
Un fichero de entrada para CUP consta de las siguientes partes [3]:
Definici´on de paquete y sentencias import.
Secci´on de c´odigo de usuario.
Declaraci´on de s´ımbolos terminales y no terminales.
Declaraciones de precedencia.
Definici´on del s´ımbolo inicial de la gram´atica y las reglas de producci´on.
2 .1. Definici´on de paquete y sentencias import
En esta secci´on se incluyen las construcciones para indicar que las clases Java ge-
neradas a partir de este fichero pertenecen a un determinado package o importar las
clases Java necesarias. Esta parte contendr´a como m´ınimo la siguiente l´ınea: import
java cup.runtime.∗;
7
8. Donde:
package <nombrePaquete>: debemos poner el nombre del paquete en el cual se va
a crear el codigo java de archivo flex.
import java cup.runtime.*: esto importamos para que el archivo flex tengo sincro-
nizaci´on con el archivo cup.
import java.io.FileReader: esta nos servira para poder hacer la lectura del archivo
de entrada de datos a analizar.
2 .2. Secci´on de c´odigo de usuario
En esta secci´on se puede incluir c´odigo Java que el usuario desee incluir en el analizador
sint´actico que se va a obtener con CUP. La declaraci´on es: parser code {: ... :}; esta nos
permite personalizar m´etodos algunos dentro del analizador. Donde:
El m´etodo report error: nos devolvera el error encontrado, asi como la linea y co-
lumna que este se encuentra.
El m´etodo report fatal error: cuando se encuentra un error donde el sistema no
puede recuperarse, nos devolvera un mensaje de error y finaliza la ejecuci´on.
El metodo main: para garantizar la ejecucion del analizador l´exico y sintactico,
adem´as que se pase como parametro la tabla de simbolos correspondiente.
Y finalmente el m´etodo conversion: es aquel que nos permite realizar la conversi´on
del n´umero en letras a su valor entero.
8
9. 2 .3. Declaraci´on de s´ımbolos terminales y no terminales
En esta secci´on se declaran los s´ımbolos terminales y no terminales de la gram´atica que
define el analizador sint´actico. Tanto los s´ımbolos no terminales (subarboles de sintaxis)
como los s´ımbolos terminales (token) pueden, opcionalmente, tener asociado un objeto
Java de una cierta clase.
Para declarar s´ımbolos terminales y no terminales se utiliza la siguiente sintaxis:
terminal [<nombre clase >] nombre1, nombre2, ... ;
non terminal [< nombre clase >] nombreA, nombreB, ... ;
9
10. 2 .4. Declaraciones de precedencia
En CUP, es posible definir niveles de precedencia y la asociatividad de s´ımbolos ter-
minales (como se ver´a m´as adelante, tambi´en se pueden definir niveles de precedencia y
asociatividad lig´andolos a reglas de producci´on concretas).
2 .5. Definici´on del s´ımbolo inicial de la gram´atica y las reglas de producci´on
En esta secci´on del archivo es donde escribiremos nuestra gramatica. La gramatica
tiene la siguiente sintaxis : <non terminal > ::= < terminales o No terminales >;
Como un no terminal puede tener mas de un lado derecho en Cup se utiliza el simbolo
“|”
<non terminal > ::= < terminales o No terminales >
| < terminales o No terminales >;
En este apartado se indica como va a ser el funcionamiento del compilador, en
este caso llamamos a la epxresi´on lista expr list concatenado con una expresi´on de
cadena expr part o se da el caso de llamar unicamente a la exprexion de cadena,
esta ultima sera la que nos mostrara el resultado de la expresion regular expr reg
ingreasa.
Aqu´ı estamos utilizando el no terminal expr part, donde se almacena el error si es
que se da el caso o llamamos a la expresi´on regular exprReg que es la que viene con
el resultado final de la expresi´on evaluada.
Ahora se procede a evaluar la forma en que el usuario ingresara los datos a ser
analizados, para eso usamos el no terminal exprReg, en esta se almacenara los
posibles errores y la regla gramatical correcta. A continuaci´on se indica algunos de
los errores que seran identificados:
10
11. • 1: Con la regla gramatical CONVNUM numero:n1 NUMLETRAS FL, CONV-
NUM numero:n1 NUMLETRAS se le indica al usuario que la sint´axis no es la
correcta.
• 2: Con la regla gramatical NUMLETRAS numero:n1, se controla la sint´axis
inicando que esta incompleta.
• 3: Con la regla gramatical NUMLETRAS numero:n1 CONVNUM, se controla
el fin de l´ınea FL.
Hasta esta parte se controla algunos errores que se pueden dar, la explicaci´on de
esto se hace en el apartado de Errores del compilador.
Con esta regla gramatical finalizamos el conjunto de expresiones que se evalua den-
tro del no terminal exprReg, aqu´ı estamos determinando cual es la sint´axis de como
11
12. deberian ser ingresados los datos a evaluar, primero se ingresa la palabra reserva-
da NUMLETRAS <n´umero a evaluar> operador CONVNUM y fin de l´ınea FL.
Adem´as se hace el uso del m´etodo de conversion que se creo al inicio, y este m´etodo
sera llamado dentro de un par de corchetes {: m´etodo :}, a continuaci´on se muestra
como debe ir:
Con el apartado numero se realiza una expresion gramatical en la que establecemos
el conjunto de los n´umeros en letras, la variable RESULT nos indica que el valor que
contiene dentro de ”” sera el valor que retorne.
2 .6. Ejecuci´on en java
Para la generaci´on del codigo en .java se debe importar la libreria .cup dentro de un pro-
yecto en cualquir ID, en este caso se usa Netbeans especificamente con java cup.Main.main();
y se lo hace de la siguiente manera:
1: Se crea una variable tipo cadena.
2: Hacer un sentencia if, donde primero evaluamos que la variable de tipo cadena
sea sea mayor a 0, si es as´ı entonces igualamos la variable al archivo de tipo cup.
3: Se crea una variable de tipo cadena pero en arreglo y la igualamos a la varible se
creo en el paso 1.
4: Se hace el uso de la libreria cup y se le envia como parametro el archivo creado
en el paso 3.
12
13. 3 . Errores en el compilador
Como sabemos que si el usuario no ingresa bien la sintaxis se generara un conjunto de
errores, es por ello que en este ejemplo se tomara en cuenta 4 tipos de errores, para los
cuales proporcionara la linea y columna en la cual se genero el error y para resolverlos se
dara una ayuda en tipo de mensaje de como debe ser la sint´axis.
Por ejemplo si el usuario ingresa:
numLetras uno convNum
La salida que nos enviara sera:
Error en linea 1, y columna 15 : Falta el fin de linea ;
Para eso se hace uso del metodo report error y report fatal error que han sido creados
en c´odigo java, y son llamados en la siguiente manera dentro de las reglas gramaticales:
Por ejemplo si el usario ingresa NUMLETRAS numero CONVNUM, entonces en este caso
falta el fin de l´ınea: FL, para ello:
1: se usa c´odigo java con el cual se obtiene la l´ınea y columna en la que se produjo
el error.
2: se llama al m´etodo parser.report error: aqui le enviamos el respectivo mensaje y
variable de error misma que da la l´ınea y columna del error.
13
14. 4 . Ejecuci´on del compilador desde Netbeans
4 .1. M´etodos generados en c´odigo java
AL generar este codigo desde el archivo .flex, se generar un metodo next token, el cual
nos devolvera un objeto de la clase Symbol que representa el siguiente token de la cadena
de token que sera la entrada para el analizador s´ıntactico.
El uso del m´etodo parse() se lo necesita en el analizador sint´actico, este m´etodo nos
devolvera un objeto de la clase Symbol que representa al simbolo no terminal ra´ız del
´arbol de derivaci´on que genera la cadena de token de entrada.
4 .2. Compilaci´on del c´odigo con la entrada a evaluar
Para realizar la ejecuci´on desde netbeans se crea una clase que contenga:
Como generar los archivos tanto el .flex como el .cup para que proporcionen el c´odigo
en una clase .java
Como ejecutar la entrada de un archivo .txt, el cual contendra los datos a ser
evaluados por el compilador.
A continuaci´on se indica el c´odigo de la clase que contiene el m´etodo main.
1: Se crea tres variables estaticas de tipo entero, para obtener el valor que el usuario
ingresara.
2: Se crea un bucle de elecci´on, esto nos sirve para ejecutar el codigo de acuerdo al
dato entero que el usuario ingreso, se tiene 2 casos:
1. GENERAR: generamos el c´odigo java de los archivos flex y cup, para eso se llama
a los archivos; y el caso
2: EJECUTAR: aqui se analiza el archivo .txt que contiene los datos que se van a
evaluar.
14
15. 4 .3. Archivo .txt de entrada
El archivo de entrada debera llevar la siguiente sint´axis:
Y la salida que se genera sera de la siguiente manera:
uno = 1
veinte = 20
ocho = 8
15
16. Caso contrario si ingresa asi:
Nos enviara la siguiente salida:
5 . Aut´omata
La creaci´on del aut´omata nos ayudo a enterder como es el funcionamiento del com-
pilador que se esta desarrollando, en si es para entender como funcionaran las reglas
gramaticales, a continuaci´on se muestra el aut´omata realizado:
6 . C´ODIGO FUENTE
El c´odigo fuente, tanto de los archivos FLEX y CUP as´ı como el c´odigo generado en
java de estos 2 archivos, la entrada de datos a analizar que es un .txt, la clase principal
que contiene el ejecutor del programa y la clase sym la que contiene todos los tokens, esta
disponible para su descarga en el siguiente link:
C´odigo Fuente: https://conv-numletras-a-numentero.googlecode.com/svn/trunk/
Documentaci´on: http://es.slideshare.net/SheyliPatio/ejercicio-compiladores
16
17. C. BIBLIOGRAFIA
Referencias
[1] Definici´on de analizador lexico; 08/02/2015. Disponible en: http://www.escet.
urjc.es/˜ci/material/lexico.pdf
[2] Estructura de un archivo Jflex; 08/02/2015. Disponible en: http://www.
rafaelvega.com/wp-content/uploads/Articulo.pdf
[3] Estructura del archivo CUP; 09/02/2015; Disponible en: http://www.it.uc3m.es/
˜luis/fo1/p/CUP.html
17