11

Click here to load reader

Flex bison

Embed Size (px)

Citation preview

Page 1: Flex bison

PONTIFICIA UNIVERSIDAD CATÓLICA DEL ECUADOR SEDE IBARRA

Nombre: Carlos Brusil

Escuela: Ingeniería

Materia: Compiladores

Tema: Flex y Bison

1.- Herramientas para la construcción de procesadores de lenguaje.

A continuación se muestran algunas de las herramientas disponibles que pueden utilizarse

para la realización de la Práctica de Procesadores de Lenguajes. Estas herramientas

funcionan bajo Windows, aunque se puede utilizar, si se desea, cualquier otra

herramienta. No obstante, se recuerda que los ficheros que debe generar la práctica no

son generados automáticamente por estas herramientas (y en especial, el árbol sintáctico

generado por la herramienta Gold Parser no es correcto ni válido para aprobar la práctica).

Herramienta Lenguaje Descripción

Bison C Generador de Analizadores Sintácticos Ascendentes

tipo YACC

COCO/R C/C++ Generador de Analizadores Léxicos y Sintácticos

Descendentes Recursivos

Flex C Generador de Analizadores Léxicos tipo Lex

Lex C Generador de Analizadores Léxicos

SDGLL1 exe Sistema Detector de Gramáticas LL(1) y generador de la

tabla

TS 2006 C/C++ Tipo abstracto de datos Tabla de Símbolos de uso sencillo

TS C Tipo abstracto de datos Tabla de Símbolos

TS-OO C++ Tipo abstracto de datos orientado a objetos Tabla de

Símbolos

VASt exe

Visualizador de árboles sintácticos partiendo de los

ficheros con la gramática y el parse pedidos en

la Práctica [versión 2.0, Windows]

VASt C++

Visualizador de árboles sintácticos partiendo de los

ficheros con la gramática y el parse pedidos en

la Práctica [versión 1.0, Linux]

YACC C Generador de Analizadores Sintácticos Ascendentes LR(1)

2.- Aplicación de los lenguajes

Page 2: Flex bison

Los lenguajes de programación hoy en día tienen una infinidad de aplicaciones,

básicamente cualquier objeto electrónico tiene cierto grado de programación. Algunos de

los más comunes son C++ y JAVA, también existe HTML, HTTP, XML, XAML y C#,

este último actualmente es el más utilizado en todos los dispositivos y redes basados en

MICROSOFT (Xbox 350, Windows Mobile, Windows Phone, Windows Cloud, Zune,

etc.). Ya que los lenguajes de programación son informáticamente un puente entre el

Hardware y el Software estos permiten que las computadoras puedan establecer conexión

con un celular, una cámara o una consola portátil de videojuego. Otra de las aplicaciones

de los lenguajes de programación son las matemáticas como las calculadoras, cajas

registradoras, cajeros automáticos, por solo mencionar algunos ejemplos sencillos.

Existen también niveles de programación mucho más complejos como los videojuegos o

los pilotos automáticos de los aviones comerciales o las máquinas de juego de los casinos

que siguen un patrón de probabilidad a partir de un arreglo de números al azar establecido

por una programación numérica.

3.- Reseña Histórica

Las primeras aplicaciones del procesamiento del lenguaje natural surgieron entre 1940 y

1960, teniendo como interés fundamental la traducción automática de textos entre

diferentes idiomas. Los experimentos en este ámbito se basaban fundamentalmente en la

sustitución automática palabra por palabra, por lo que se obtenían traducciones muy

rudimentarias, que no proporcionaban unos resultados claros. Surgió por tanto la

necesidad de resolver ambigüedades sintácticas y semánticas, así como la importancia de

considerar la información contextual. Los problemas más relevantes en este tiempo

fueron la carencia de un orden de la estructura oracional en algunas lenguas, y la dificultad

para obtener una representación tanto sintáctica como semántica, pero una vez que se

empezaron a tener en cuenta se dio paso a una concepción más realista del lenguaje en la

que era necesario contemplar las transformaciones que se producen en la estructura de la

frase durante el proceso de traducción. Los últimos años se caracterizan por la

incorporación de técnicas estadísticas y el desarrollo de formalismos adecuados para el

tratamiento de la información léxica. Se ha introducido nuevas técnicas de representación

del conocimiento muy cercanas a la inteligencia artificial, y las técnicas de procesamiento

utilizadas por investigadores procedentes del área de la lingüística e informática son cada

vez más próximas.

4.- Diseño y construcción de un compilador.

La construcción de un compilador involucra la división del proceso en una serie de fases

que variará con su complejidad. Generalmente estas fases se agrupan en dos tareas: el

análisis del programa fuente y la síntesis del programa objeto. Análisis: Se trata de la

comprobación de la corrección del programa fuente, e incluye las fases correspondientes

al Análisis léxico (que consiste en la descomposición del programa fuente en

componentes léxicos), Análisis sintáctico (agrupación de los componentes léxicos en

frases gramaticales) y Análisis semántico (comprobación de la validez semántica de las

sentencias aceptadas en la fase de Análisis Sintáctico). Síntesis: Su objetivo es la

generación de la salida expresada en el lenguaje objeto y suele estar formado por una o

varias combinaciones de fases de Generación de Código (normalmente se trata de código

intermedio o de código objeto) y de Optimización de Código (en las que se busca obtener

un código lo más eficiente posible). QUE ES FLEX Y BISON Son dos herramientas útiles

para crear programas que reaccionen a una entrada de datos con una estructura y un

Page 3: Flex bison

lenguaje predeterminado, como por ejemplo, podemos crear compiladores, intérpretes y

analizadores de línea de comando. Flex: El Flex define las reglas de reconocimiento de

símbolos (Tokens) a partir de expresiones regulares. Cuando un Token es reconocido por

uno de estos patrones de agrupamiento se le define una acción, por lo general esta acción

es devolver el Tipo y el valor (lexema). El Flex cuando se utiliza combinado con el Bison,

utiliza las definiciones de los Tokens realizadas en el Bison para la comunicación entre

ellos, Bison: GNU bison es un programa generador de analizadores sintácticos de

propósito general perteneciente al proyecto GNU disponible para prácticamente todos los

sistemas operativos, se usa normalmente acompañado de flex aunque los analizadores

léxicos se pueden también obtener de otras formas. Bison convierte la descripción formal

de un lenguaje, escrita como una gramática libre de contexto LALR, en un programa en

C, C++, o Java que realiza análisis sintáctico. Es utilizado para crear analizadores para

muchos lenguajes, desde simples calculadoras hasta lenguajes complejos. Para utilizar

Bison, es necesaria experiencia con la sintaxis usada para describir gramáticas.

5.- Las herramientas Flex y Bison.

Esta herramienta se usa en consonancia con la herramienta flex y sirve para especificaran

analizadores sintácticos. De la misma forma que flex tiene como base las expresiones

regulares, la herramienta bison también se basa en otro formalismo para describir

lenguajes ,en este caso serán las gramáticas independientes del contexto las que

constituirán el núcleo de las especificaciones que procesará bison.

6.- Que es flex y Bison

Son dos herramientas útiles para crear programas que reaccionen a una entrada de datos

con una estructura y un lenguaje predeterminado, como por ejemplo, podemos crear

compiladores, intérpretes y analizadores de línea de comando.

Flex: El Flex define las reglas de reconocimiento de símbolos (Tokens) a partir de

expresiones regulares. Cuando un Token es reconocido por uno de estos patrones de

agrupamiento se le define una acción, por lo general esta acción es devolver el Tipo y el

valor (lexema). El Flex cuando se utiliza combinado con el Bison, utiliza las definiciones

de los Tokens realizadas en el Bison para la comunicación entre ellos.

Bison: GNU bison es un programa generador de analizadores sintácticos de propósito

general perteneciente al proyecto GNU disponible para prácticamente todos los sistemas

operativos, se usa normalmente acompañado de flex aunque los analizadores léxicos se

pueden también obtener de otras formas. Bison convierte la descripción formal de un

lenguaje, escrita como una gramática libre de contexto LALR, en un programa en C, C++,

o Java que realiza análisis sintáctico. Es utilizado para crear analizadores para muchos

lenguajes, desde simples calculadoras hasta lenguajes complejos. Para utilizar Bison, es

necesaria experiencia con la sintaxis usada para describir gramáticas.

7.- Como se instala Flex y Bison

7.1.-Descarga el software disponible en el sitio de la cátedra.

7.2. Instalar el software en la unidad C: (para explicar a partir del punto 4 se tendrá

como hipótesis de que flex y bison han sido instalados en la ruta: C:GnuWin32 donde

contiene una subcarpeta llamada bin donde se encuentran los programas respectivos)

Page 4: Flex bison

7.3.- Flex y bison son aplicaciones de consola, por lo que se deberá entrar al Símbolo

del sistema y tipear líneas de comando para ejecutar Flex. Una alternativa es crear un

archivo de proceso por lotes (*.bat) que contenga las líneas de comando para la

ejecución de Flex y Bison y/o la compilación del archivo generado.

7.4.- Si deseas que flex y bison se integren al conjunto de variables del entorno (esto te

va a permitir llamar a flex/bison desde cualquier ubicación en la línea de comandos)

debes hacer lo siguiente:

• Clic derecho en “Mi PC”.

• Selecciona “Propiedades”

• Clic en la pestaña “Opciones Avanzadas”

• Presiona el botón “Variables de entorno”

• En la ventana de variables de entorno, ubicarse en la sección “Variables del sistema”

luego haz clic en PATH y luego en el botón “Modificar” (si no está hacer clic en

“Nueva” y agregar PATH)

• En la nueva ventana, escribir la ruta completa al directorio “bin” de la aplicación

flex/bison. Si existe otro valor, separarlos con comas.

• Aceptar los cambios y luego reiniciar el sistema operativo.

7.5.- Si deseas instalar un compilador de C como MinGwin, deberás integrar la ruta de

acceso al compilador a las variables de entorno para facilitar la llamada al programa.

Por ejemplo si se instaló MingWin en “C:Mingw” y dentro de la carpeta “bin” se

encuentra “gcc.exe” que es el ejecutable, entonces de deberá agregar (análogo a los

pasos anteriores) lo siguiente:

7.6.- Cuando tengas listo podrás llamar a flex/bison desde el símbolo del sistema sin

necesidad de ubicarte en la carpeta donde ha sido instalado flex/bison.

8.- Como se compila con Flex y Bison

$ bison -d calculadora.y

$ flex calculadora.l

$ gcc -o calculador calculadora.tab.c lex.yy.c diccionario.c

Ejemplos

a)

Ejemplo Flex y Bison

Vamos a realizar un ejemplo de una calculadora sencilla que reconocerá las principales

operaciones aritmética (+,-,* y /).

Abrimos un editor de texto y pegamos el siguiente código que será nuestro scanner

/*****************

Definiciones

Se colocan las cabeceras, variables y expresiones regulares

********************/

%{

#include <stdio.h>

#include <stdlib.h>

Page 5: Flex bison

#include "sintactico.tab.h"

int linea=0;

%}

/*

Creamos todas las expresiones regulares

Creamos la definición llamada DIGITO, podemos acceder esta definición

usando {DIGITO}*/

DIGITO [0-9]

NUMERO {DIGITO}+("."{DIGITO}+)?

%%

/***************

Reglas

*****************/

/* Creamos las reglas que reconocerán las cadenas que acepte

Nuestro scanner y retornaremos el token a bison con la

funcion return. */

{NUMERO} {yylval.real=atof(yytext); return(NUMERO);}

"=" {return(IGUAL);}

"+" {return(MAS);}

"-" {return(MENOS);}

";" {return(PTOCOMA);}

"*" {return(POR);}

"/" {return(DIV);}

"(" {return(PAA);}

")" {return(PAC);}

"\n" {linea++;}

[\t\r\f] {}

" " {}

/* Si en nuestra entrada tiene algún caracter que no pertenece a

las reglas anteriores, se genera un error léxico */

. {printf("Error lexico en linea %d",linea);}

%%

/*

Código de Usuario

Aquí podemos realizar otras funciones, como por ejemplo ingresar

símbolos a nuestra tabal de símbolos o cualquier otra accione

del usuario.

Todo lo que el usuario coloque en esta sección se copiara al

archvi lex.yy.c tal y como esta.

*/

Page 6: Flex bison

Guardamos el archivo como lexico.l. Luego creamos un nuevo archivo y colocamos el

siguiente código.

%{

/********************

Declaraciones en C

**********************/

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

extern int yylex(void);

extern char *yytext;

extern int linea;

extern FILE *yyin;

void yyerror(char *s);

%}

/************************

Declaraciones de Bison

*************************/

/* Especifica la coleccion completa de tipos de datos para poder usar

varios tipos de datos en los terminales y no terminales*/

%union

{

float real;

}

/* Indica la produccion con la que inicia nuestra gramatica*/

%start Exp_l

/* Especificacion de termines, podemos especificar tambien su tipo */

%token <real> NUMERO

%token MAS

%token MENOS

%token IGUAL

%token PTOCOMA

%token POR

%token DIV

%token PAA

%token PAC

/* No Terminales, que tambien podemos especificar su tipo */

%type <real> Exp

%type <real> Calc

%type <real> Exp_l

/* Definimos las precedencias de menor a mayor */

%left MAS MENOS

Page 7: Flex bison

%left POR DIV

%%

/**********************

Reglas Gramaticales

***********************/

Exp_l: Exp_l Calc

|Calc

;

Calc : Exp PTOCOMA {printf ("%4.1f\n",$1)}

;

/* con el símbolo de $$ asignamos el valor semántico de toda

la acción de la derecha y se la asignamos al no terminal de

la izquierda, en la siguiente regla, se la asigna a Exp.

Para poder acceder al valor de los terminales y no terminales del lado

derecho usamos el símbolo $ y le concatenamos un numero que representa

la posición en la que se encuentra es decir si tenemos

A --> B NUMERO C

Si queremos usar le valor que tiene el no terminal B usamos $1, si queremos

usar el valor que tiene NUMERO usamos $2 y así sucesivamente.

*/

Exp : NUMERO {$$=$1;}

|Exp MAS Exp {$$=$1+$3;}

|Exp MENOS Exp {$$=$1-$3;}

|Exp POR Exp {$$=$1*$3;}

|Exp DIV Exp {$$=$1/$3;}

|PAA Exp PAC {$$=$2;}

;

%%

/********************

Codigo C Adicional

**********************/

void yyerror(char *s)

{

printf("Error sintactico %s",s);

}

int main(int argc,char **argv)

{

if (argc>1)

yyin=fopen(argv[1],"rt");

else

yyin=stdin;

Page 8: Flex bison

yyparse();

return 0;

}

Guardamos este archivo con el nombre sintáctico.y y con eso ya tenemos nuestro

scanner y nuestro parser terminado. Para compilar estos archivos usamos los comandos

Compilando sintactico.y

~> bison -d sintactico.y

El parámetro –d, crea el fichero t.tab.h, que contiene los identificadores de los tokens de

bison usados por flex

Compilando lexico.l

~> flex lexico.l

Compilando arhivos generados y crear ejecutable

~> cc lex.yy.c sintactico.tab.c -o analizador -lfl -lm

Esto nos genera un ejecutable llamado analizador.

Muchas veces necesitamos modificar nuestro archivo sintáctico.y o lexico.l y tenemos

que compilar todo cada vez que hacemos un cambio, para no estar escribiendo los

comandos cada vez que realizamos un cambio, crearemos un script, que al ejecutarlo

realizara todos los comandos de compilación. Para eso creamos un nuevo archivo en

blanco y escribimos

#!/bin/bash

bison -d sintactico.y

flex lexico.l

cc lex.yy.c sintactico.tab.c -o analizador -lfl –lm

Guardamos este archivo con cualquier nombre, por ejemplo compilar.sh. Ahora

cambiaremos las propiedades de este archivo para poder ejecutar. Le damos clic

derecho sobre este archivo y en la pestaña permisos elegimos la opción de “Permitir

ejecutar el archivo como un programa”, cerramos esa ventana.

Page 9: Flex bison

Para poder compilar, desde consola nos ubicamos donde se encuentra este archivo .sh y

escribimos

./compilar.sh

Esto nos genera nuestro ejecutable que podemos correr para poder probar nuestra

calculadora. Para ejecutar este ejemplo usamos el comando

./analizador

Ingresamos algunas expresiones y el resultado que obtenemos es:

b) Minianalizador sintáctico para frases en español.

%token ARTICULO NOMBRE ADJETIVO PREPOSICION VERBO

Page 10: Flex bison

%%

dialogo : frase

| dialogo frase

;

frase : '\n'

| sujeto predicado '\n' {printf("\n>> Frase correcta\n");}

;

sujeto : frase_nominal

;

frase_nominal : NOMBRE

| ARTICULO NOMBRE

| ARTICULO NOMBRE ADJETIVO

| ARTICULO NOMBRE frase_preposicional

;

frase_preposicional : PREPOSICION frase_nominal

;

predicado : frase_verbal

;

frase_verbal : VERBO

| VERBO frase_nominal

| VERBO frase_preposicional

;

%%

int main()

{

yyparse();

}

void yyerror (char *s)

{

printf ("%s\n", s);

}

int yywrap()

{

return 1;

}

COMPILACIÓN

Page 11: Flex bison

$ bison -d ejemplo1.y

$ flex ejemplo1.l

$ gcc -o ejemplo1 ejemplo1.tab.c lex.yy.c

Tambien es posible utilizar el comando make (se incluye fichero Makefile).

EJECUCIÓN

$ ./ejemplo1

el gato rojo vive en la casa azul

$ gcc -o ejemplo1 ejemplo1.tab.c lex.yy.c