Está en la página 1de 24

Compiladores

Configuración de un Reconocedor del Lenguaje Utilizando Flex y Bison


10 de mayo de 2017

Índice

I Consideraciones Iniciales 3
1. Compilador 3

2. Gramáticas Libres de Contexto 3

II Herramientas 4
1. Integración de Flex y Bison 4

2. Flex 4

3. Bison 5
3.1. Declaraciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.2. Reglas de Producción . . . . . . . . . . . . . . . . . . . . . . . . 6
3.3. Código Adicional . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

III Instalación de las Herramientas 7


1. Instalación de Flex 7

2. Instalación de Bison 11

IV Ejercicio de Ejemplo 17
1. Planteo 17

1
2. Solución 18
2.1. Especificación para Flex . . . . . . . . . . . . . . . . . . . . . . . 18
2.2. Especificación para Bison . . . . . . . . . . . . . . . . . . . . . . 18
2.3. Compiación de la especificación Flex . . . . . . . . . . . . . . . . 19
2.4. Compiación de la especificación Bison . . . . . . . . . . . . . . . 19
2.5. Opcion 1: Generación del Programa Reconocedor Utilizando gcc 20
2.6. Opcion 2: Generación del Programa Reconocedor Utilizando Zinjai 20

V Anexo. Comandos del DOS (Línea de comandos) 23


1. Ingreso a Línea de Comandos 23

2. Comandos Principales 23
2.1. Comando cd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

2
PARTE I

CONSIDERACIONES INICIALES

1. Compilador
Un compilador es un grupo de componentes (en los cuales se pueden observar
subcomponentes) donde los datos a compilar transitan de uno a otro. Utilizare-
mos una herramienta diferente para representar cada uno de estos componentes.
Para realizar el análisis léxico, utilizaremos una herramienta llamada Flex, y
para el análisis sintáctico/semántico una herramienta llamada Bison. Final-
mente, para generar el código de máquina (programa recoonocedor), se puede
utilizar LLVM, herramienta que genera código intermedio.
Este apunte tiene por objeto puntualizar el uso de estas herramientas en
la construcción de un analizador sintáctico, con el objeto de entender como
funcionan los compiladores, y tener una idea de la máquina subyacente. Esto
permite luego experimentar con diferentes técnicas de compilación.

2. Gramáticas Libres de Contexto


Las gramáticas libres de contexto permiten describir la mayoría de los len-
guajes programación.
Por otro lado, estas gramáticas son suficientemente simples como para permi-
tir el diseño eficientes de algoritmos de análisis sintáctico que, para una cadena
de caracteres dada determinen cómo puede ser generada desde la gramática.

3
PARTE II

HERRAMIENTAS

1. Integración de Flex y Bison


Flex y Bison se complementan en la construcción de un analizador sintáctico.
La secciones siguientes describen el proceso de construcción del analizador del
lenguaje (en la figura: a.exe)

Flex y Bison generan a partir de especificaciones previas, programas en


lenguaje C, que al ser ensamblados conjuntamente generan finalmente el ana-
lizador.

2. Flex
Flex (Fast Lexical Analyzer) es una herramienta para construir analizadores
léxicos o lexers. Un lexer lee un flujo de entrada y lo divide en unidades léxicas
(tokens).
Un programa en flex tiene 3 secciones, separadas por la etiqueta % %

4
Declaraciones y opciones de configuración
%%
Lista de patrones y acciones
%%
código C adicional copiado al escanner

En la sección de declaraciones, el código que se encuentre entre %{ y %} se


copiará literalmente al comienzo del fichero generado en C.
En la segunda sección se especifica cada patrón a reconocer comenzando la
línea, seguido por código C que se ejecutará cuando sea reconocido el patrón.
Cada patrón debe dar comienzo a la línea, ya que flex considera cada lí-
nea que comience con un espacio como código a ser compilado en el código C
generado.

3. Bison
Bison es una herramienta que, a partir de la descripción formal de una gra-
mática libre de contexto que define un lenguaje, genera un analizador sintáctico
(parser) para esa gramática. Este analizador se materializa a través de un pro-
grama en C. A partir del uso de Bison, se obtiene como producto un árbol de
sintaxis abstracta.
Un programa en Bison se divide en 3 partes:

Declaraciones
%%
Reglas de producción
%%
Código adicional

3.1. Declaraciones
La primera parte puede contener:

Especificaciones escritas en el lenguaje destino, definidas entre %{ y %}.


Declaraciones de tokens, con la palabra clave %token.

El tipo del terminal, con la palabra reservada %union.


Información sobre las prioridades de los operadores y su asociatividad.
El axioma de la gramática, o símbolo inicial, usando la palabra reservada %start
(si no se especifica, el axioma es la primera regla de la segunda parte del
archivo).

5
3.2. Reglas de Producción
Esta es la única parte necesaria, esto es, la que siempre debe aparecer en un
programa Bison. Puede contener:

Declaraciones y/o definiciones encerradas entre % y %.

Reglas de producción de la gramática. Las reglas de producción son defi-


nidas así:
expresion_no_terminal: cuerpo_1 { sentencias acciones 1 }
| cuerpo_2 { sentencias acciones 2 }
| ...
| cuerpo_n { sentencias acciones n };

donde cuerpo_i pueden ser expresiones terminales o no terminales del


lenguaje

3.3. Código Adicional


Esta parte contiene código adicional. En nuestro caso debe contener la fun-
ción main() que debe llamar a la función yyparse(), y una función yyerror(char
*mensaje), que será llamada cuando ocurra un error de sintaxis en el reconoci-
miento.

6
PARTE III

INSTALACIÓN DE LAS HERRAMIENTAS

1. Instalación de Flex
A continuación se muestran las pantallas de la instalación paso a paso de
Flex.

Paso 1.

Paso 2.

7
Paso 3.

Paso 4.

8
Paso 5.

Paso 6.

9
Paso 7.

Paso 8.

10
2. Instalación de Bison
A continuación se muestran las pantallas de la instalación paso a paso de
Bison.

Paso 1.

Paso 2.

11
Paso 3.

Paso 4.

12
Paso 5.

Paso 6.

13
Paso 7.

Paso 8.

14
Cuando ya se encuentran instaladas ambas herramientas se puede visualizar
el siguiente árbol de directorios

En particular el directorio bin de la instalación contiene los siguientes ar-


chivos

15
Importante: En Windows será necesario incluir en la variable de ambiente
path, el directorio bin (el camino completo), para que los programas flex.exe
y bison.exe puedan ser invocados desde cualquier otro directorio.

16
PARTE IV

EJERCICIO DE EJEMPLO

1. Planteo
Haciendo uso de las herramientas Flex/Bison, desarrollar un analizador léxi-
co (scanner) y un analizador sintáctico (parser) para la gramática que se mues-
tra. Obtener el programa ejecutable que tome como ‘input’ un archivo de texto
con un ejemplo de código fuente que corresponda al lenguaje y lo someta a las
dos primeras fases del proceso de traducción. Como resultado el analizador debe
mostrar la tabla de lexemas-tokens obtenida por el scanner y el árbol de deri-
vación generado por el parser, o el error en caso de producirse alguno de orden
léxico o sintáctico durante el proceso de análisis.

1 rutina ::= i d e n t i f i e r parameter_list
2 parameter_list ::= " ( " defparameter { " , "
d e f p a r a m e t e r }∗ |
3 ( "&" i d e n t i f i e r { " , " "&" i d e n t i f i e r }∗
4 d e f p a r a m e t e r : : = parameter [ "=" e x p r e s s i o n ]
5 identifier ::= l e t t e r { l e t t e r | d i g i t | "_" }∗
6 parameter ::= i d e n t i f i e r | " ( " s u b l i s t " ) "
7 expression : : = c o n d i t i o n a l _ e x p r e s s i o n | lambda_form
8 letter ::= lowercase | uppercase
9 digit ::= " 0 " | " 1 " | . . . | " 9 "
10 identifier : : = ( l e t t e r ) { l e t t e r | d i g i t | "_" }∗
11 sublist : : = parameter ( " , " parameter ) ∗
12 c o n d i t i o n a l _ e x p r e s s i o n : : = " o r _ t e s t " | " and_test "
13 lambda_form : : = " lambda "
14 lowercase ::= " a " | "b" | . . . | " z "
15 uppercase : : = "A" | "B" | . . . | " Z "

EJEMPLOS:

1 algo_1 ( a l f a = o r _ t e s t , Beta = lambda ) // vá l i d o
2 algo_1 ( a l f a = o r _ t e s t , &Beta ) // i n v á l i d o
3 algo_1 ( a l f a = o r _ t e s t , _Beta = lambda ) // i n v á l i d o

17
2. Solución
La resolución del problema viene dada por la configuración de dos ficheros:
1) La especificación léxica para ser reconocida por Flex, y 2) la especificación
sintáctica a ser reconocida por Bison.

2.1. Especificación para Flex


 
1 %{
2 #i n c l u d e " y . t a b . h "
3 %}
4
5 /∗ IDENTIFIER [ A−Za−z ] + [A−Za−z0 −9]∗ ∗/
6 LETTER [ A−Za−z ]
7 DIGIT [0 −9]
8 IDENTIFIER {LETTER} ( {LETTER} | { DIGIT } ) ∗
9 %%
10
11 ")" { r e t u r n CPAR; }
12 "(" { r e t u r n APAR; }
13 "=" { r e t u r n IGUAL ; }
14 " ," { r e t u r n COMA; }
15 "&" { r e t u r n AMPERSAND; }
16 " or_test " { r e t u r n ORTEST; }
17 " a n d _ t e s t " { r e t u r n ANDTEST; }
18 " lambda " { r e t u r n LAMBDA; }
19 {IDENTIFIER} {printf ( " Identificador :
%s \n " , y y t e x t ) ; r e t u r n ( IDENTIFIER ) ; }
20 ( \ n )+ { r e t u r n (NL) ; }
21 . { return yytext [ 0 ] ; }
22 %%
 

2.2. Especificación para Bison


 
1 %{
2 #i n c l u d e <s t d i o . h>
3
4
5 extern char ∗ yytext ;
6
7 %}
8
9
10
11
12
13 %t o k e n NL IGUAL IDENTIFIER APAR CPAR COMA ORTEST ANDTEST LAMBDA
AMPERSAND
14 %%
15
16 r u t i n a : IDENTIFIER APAR PARAMETER_LIST CPAR NL { p r i n t f ( " cadena
valida " ) ; return ; }
17 |
18 ;
19 PARAMETER_LIST : DEFPARAMETER
20 | PARAMETER_LIST COMA DEFPARAMETER
21 | AMPERSAND IDENTIFIER
22 ;

18
23
24
25 DEFPARAMETER: PARAMETER IGUAL EXPRESION COMA DEFPARAMETER
26 | PARAMETER IGUAL EXPRESION
27 | AMPERSAND IDENTIFIER
28 ;
29
30
31 PARAMETER: IDENTIFIER
32 | APAR SUBLIST CPAR
33 ;
34
35 SUBLIST :
36 | PARAMETER
37 | SUBLIST COMA PARAMETER
38 ;
39
40 CONDITIONAL_EXPRESSION : ORTEST
41 | ANDTEST
42 ;
43
44 EXPRESION : CONDITIONAL_EXPRESSION { p r i n t f ( " Se e n c o n t r o e x p r e s i o n −−−>
%s " , y y t e x t ) ; }
45 | LAMBDA_FORM { p r i n t f ( " Se e n c o n t r o e x p r e s i o n −−−>
%s " , y y t e x t ) ; }
46
47 LAMBDA_FORM: LAMBDA
48
49 %%
50 i n t y y e r r o r ( c h a r ∗msg ) {
51 p r i n t f ( " cadena i n v a l i d a %s \n " , msg ) ;
52 return ;
53 }
54 i n t main ( ) {
55 p r i n t f ( " I n g r e s e cadena \n " ) ;
56 yyparse () ;
57 }
 

2.3. Compiación de la especificación Flex


Desde línea de comandos, y situados en el directorio donse encuentra la es-
pecificación flex (por ejemplo flex.l), ejecutar el siguiente comando

c:/mitrabajo/flex flex.l

Esta acción genera en el directorio de trabajo el fichero en C correspondiente


al scanner.

2.4. Compiación de la especificación Bison


Desde línea de comandos, y situados en el directorio donse encuentra la es-
pecificación bison (por ejemplo bison.y), ejecutar el siguiente comando

c:/mitrabajo/bison -t -d -v bison.y -ly

Esta acción genera en el directorio de trabajo el fichero en C correspondiente


al parser.

19
2.5. Opcion 1: Generación del Programa Reconocedor Uti-
lizando gcc
Si se cuenta con el compilador gcc (GNU) instalado en la computadora, desde
línea de comandos ejecutar el siguiente:

c : /mitrabajo/gcc y.tab.c lex.yy.c − lf l − Lc : /f lex_bison/lib

donde la directiva -lfl especifica la inclusión de las librerías de flex, y -L


la ruta donde se encuentran librerias de flex y bison para ser enlazadas con el
código ya generado (para el ejemplo: c:/flex_bison/lib).

Nota IMPORTANTE: En el caso de utilizar un IDE (como por ejemplo


Zinjai), estas rutas deben ser especificadas también.

2.6. Opcion 2: Generación del Programa Reconocedor Uti-


lizando Zinjai
A partir de los ficheros obtenidos en la compilación de los ficheros para Flex
y Bison, se utiliza Zinjai para crear un proyecto que contenga los dos ficheros
en lenguaje C. Para ello se deben seguir los siguientes pasos:

Abrir el IDE Zinjai

Crear un nuevo proyecto.


• Archivo → Nuevo Proyecto
• Configurar nombre de proyecto y directorio donde se almacenará.
• Seleccionar a continuación Proyecto en Blanco, y presionar el botón
crear. Esto genera una estructura del proyecto vacía, a la cual habrá
que añadirle los ficheros en C ya generados.

Seleccionar desde el menú principal la opcion Archivo → Abrir/Agregar al


Proyecto...

Seleccionar los ficheros lex.yy.c, y.tab.c y y.tab.h. A partir de esto se vi-


sualizarán los archivos seleccionados, ahora como parte del proyecto, y en
el editor de código fuente el código C generado.

20
En las opciones de compilación y enlazado se debe especificar la ruta
donde se encuentran las librerias necesarias. Hasta que no se realice dicha
configuración es posible que se obtiene el siguiente error

Para configurar las librerias necesarias, se deben seguir los siguientes pasos:
• Desde el menú principal Ejecución seleccionar Opciones.

• Seleccionar la solapa Enlazado.


• En la opción Parámetros extra para el enlazado colocar -lfl -L más
el directorio donde se encuentran las librerias de Flex y Bison.

21
Ejecución del Programa.

• Modalidad 1. Ejecución desde Zinjai Una vez compilado, se debe


debe seleccionar la opción del menú Ejecución → Ejecutar (F9), o
presionar el correspondiente botón de la barra. Tras la ejecución, el
sistema presentará una consola donde se solicita al usuario el ingreso
de la cadena a reconocer.
• Modalidad 2. Ejecución desde Línea de Comandos Se sugiere espe-
cialmente este tipo de ejecución, ya que es más versátil y permite
probar mayor cantidad de casos en menos tiempo. Para ejecutar el
analizador desde linea de comandos seguir los siguientes pasos:
◦ Abrir una ventana de línea de comandos.
◦ Cambiarse al directorio donde se encuentran el programa ya com-
pilado por Zinjai (el reconocedor).
◦ Ejecutar el reconocedor con el siguiente comando (tener en cuen-
ta que el nombre del reconocedor puede cambiar de acuerdo a
como ustede lo haya identificado en el Zinjai)

c:/reconocedor.exe <ejemplo.txt

Se debe utilizar la redireccion < para indicar que la entrada


de datos no será por teclado, sino desde el fichero de texto que
se encuentra como parámetro. El fichero parámetro ejemplo.txt
(o como usted le haya llamado) contiene el código que debe ser
reconocido, de acuerdo a la gramática presentada anteriormente.

22
PARTE V

ANEXO. COMANDOS DEL DOS (LÍNEA DE


COMANDOS)

1. Ingreso a Línea de Comandos


Ejecutar desde Windows el comando cmd. Esto abrirá una ventana de color
negro donde se comenzarán a ejecutar los comandos.

2. Comandos Principales
2.1. Comando cd
Este comando sirve para cambiar de directorio. Por ejemplo:

c:/mitrabajo>cd ..

Deja al usuario situado en el directorio en el directorio c:/.


A continuación:

c:/mitrabajo>cd mitrabajo2

Deja al usuario situado en el directorio en el directorio c:/mitrabajo2.

2.2. Comando dir


Muestra los ficheros que se encuentran en el directorio actual.

2.3. Comandos delete o erase


Seguido del nombre de archivo, borra el mismo.

2.4. Comando type


Seguido por el nombre de un archivo, muestra por pantalla el contenido de
este.

23
2.5. Ejecución de un Programa
La ejecución se realiza simplemente colocando el nombre del programa, y
presionando enter.

24

También podría gustarte