Flex y Bison

17
Ponficia Universidad Católica Del Ecuador Sede Ibarra Nombres: Henry Córdova Fecha: 28-05-2013 Nivel: Sexto Bison Y Flex Utilizando la herramienta de búsqueda de la Web, Investigar los siguientes temas: Herramientas para la construcción de procesadores de lenguaje. Herramientas para la construcción de Procesadores de Lenguajes 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]

Transcript of Flex y Bison

Page 1: Flex y Bison

Pontificia Universidad Católica Del Ecuador Sede Ibarra

Nombres: Henry Córdova Fecha: 28-05-2013 Nivel: Sexto

Bison Y Flex

Utilizando la herramienta de búsqueda de la Web, Investigar los siguientes

temas:

Herramientas para la construcción de procesadores de lenguaje.

Herramientas para la construcción de Procesadores de Lenguajes

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]

Page 2: Flex y Bison

Aplicación de los lenguajes:

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. La robótica es la combinación de mecánica,

electrónica y programación, la cual en base a sensores y mecanismos sigue

una serie de instrucciones algorítmicas las cuales le permiten por ejemplo a

un brazo robótico montar una rueda, ajustar un tornillo o cortar un

rectángulo de 3 cm cuadrados en una placa de acero. Con el avance de la

tecnología los límites de la programación se vuelven cada vez más

distantes.

Reseña Histórica

Para facilitar el trabajo, los primeros operadores de computadoras

decidieron hacer un traductor para reemplazar los 0 y 1 por palabras o

abstracción de palabras y letras provenientes del inglés; éste se conoce

como lenguaje ensamblador. Por ejemplo, para sumar se usa la letra A de la

palabra inglesa add (sumar). El lenguaje ensamblador sigue la misma

estructura del lenguaje máquina, pero las letras y palabras son más fáciles

de recordar y entender que los números.

La necesidad de recordar secuencias de programación para las acciones

usuales llevó a denominarlas con nombres fáciles de memorizar y

asociar:ADD (sumar), SUB (restar), MUL (multiplicar), CALL (ejecutar

subrutina), etc. A esta secuencia de posiciones se le denominó

YACC C Generador de Analizadores Sintácticos

Ascendentes LR(1)

Page 3: Flex y Bison

"instrucciones", y a este conjunto de instrucciones se le llamó lenguaje

ensamblador. Posteriormente aparecieron diferentes lenguajes de

programación, los cuales reciben su denominación porque tienen una

estructura sintáctica similar a los lenguajes escritos por los humanos,

denominados también lenguajes de alto nivel.

La primera programadora de computadora conocida fue Ada Lovelace, hija

de Anabella Milbanke Byron y Lord Byron. Anabella introdujo en las

matemáticas a Ada quien, después de conocer aCharles Babbage, tradujo y

amplió una descripción de su máquina analítica. Incluso aunque Babbage

nunca completó la construcción de cualquiera de sus máquinas, el trabajo

que Ada realizó con éstas le hizo ganarse el título de primera programadora

de computadoras del mundo. El nombre del lenguaje de programación

Ada fue escogido como homenaje a esta programadora.

Diseño y construcción de un compilador.

Page 4: Flex y Bison

Flex y Bison

Flex es un una herramienta que permite generar analizadores léxicos. A

partir de un conjunto de expresiones regulares, Flex busca concordancias

en un fichero de entrada y ejecuta acciones asociadas a estas expresiones.

Es compatible casi al 100% con Lex, una herramienta clásica de Unix para

la generación de analizadores léxicos, pero es un desarrollo diferente

realizado por GNU bajo licencia GPL.

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.

Instalación de Flex y Bison

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

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)

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.

Page 5: Flex y Bison

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)

Page 6: Flex y Bison

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.

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:

Page 7: Flex y Bison

Como se compila con Flex y Bison

Para compilar en Flex y Bison seguimos los siguientes pasos.

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.

Luego de escribir las especificaciones de flex y bison realizar lo siguiente.

Si se desea invocar a flex:

Page 8: Flex y Bison

Ejemplos

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

Definiciones

Se colocan las cabeceras, variables y expresiones regulares

********************

%{

#include <stdio.h>

#include <stdlib.h>

#include "sintactico.tab.h"

int linea=0;

Page 9: Flex y Bison

%}

/*

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

Page 10: Flex y Bison

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.

*/

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 */

Page 11: Flex y Bison

%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

%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

Page 12: Flex y Bison

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;

yyparse();

return 0;

}

Segundo ejemplo

Fichero léxico_solo.l

%{

/* Ejemplo para una pequeña calculadora que permite

trabajar con numeros enteros y reales con las operaciones

Page 13: Flex y Bison

básicas de suma, resta, producto, division y trigonometricas como el seno y el coseno */

#include <stdio.h>

#include <stdlib.h>

int nlines=0;

%}

DIGITO [0-9]

ID [a-zA-Z][a-zA-Z0-9_]*

%%

{DIGITO}+ {printf("Encontrado TKN_NUM_ENTERO: %d",atoi(yytext));}

{DIGITO}+"."{DIGITO}+ {printf("Encontrado TKN_NUM_REAL: %f",atof(yytext));}

"=" {printf("Encontrado TKN_ASIGN: %s",yytext);}

";" {printf("Encontrado TKN_PTOCOMA: %s",yytext);}

"*" {printf("Encontrado TKN_MULT: %s",yytext);}

"/" {printf("Encontrado TKN_DIV: %s",yytext);}

"+" {printf("Encontrado TKN_MAS: %s",yytext);}

"-" {printf("Encontrado TKN_MENOS: %s",yytext);}

"(" {printf("Encontrado TKN_PAA: %s",yytext);}

")" {printf("Encontrado TKN_PAC: %s",yytext);}

"cos" {printf("Encontrado TKN_COS: %s",yytext);}

"sen" {printf("Encontrado TKN_SEN: %s",yytext);}

{ID} {printf("Encontrado TKN_ID: %s",yytext);}

"\n" {nlines++;}

%%

void main(int argc,char **argv)

{

if (argc>1)

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

else

yyin=stdin;

yylex();

printf("\nNumero lineas analizadas: %d\n", nlines);

}

/* para compilar

Page 14: Flex y Bison

flex lexico.l

cc lex.yy.c -o milex -lfl -lm

*/

Fichero léxico.l (versión a enlazar con Bison)

%{

/* Ejemplo para una pequeña calculadora que permite trabajar

con las operaciones básicas de suma, resta, producto, division y

trigonometricas como el seno y el coseno */

#include <stdio.h>

#include <stdlib.h>

#include "sintactico.tab.h"

int nlines=0;

%}

DIGITO [0-9]

ID [a-zA-Z][a-zA-Z0-9_]*

%%

{DIGITO}+("."{DIGITO}+)? {//printf("Encontrado TKN_NUM: %f\n",atof(yytext));

yylval.real=atof(yytext);

return(TKN_NUM);}

"=" {//printf("Encontrado TKN_ASIGN: %s\n",yytext);

return(TKN_ASIGN);}

";" {//printf("Encontrado TKN_PTOCOMA: %s\n",yytext);

return(TKN_PTOCOMA);}

"*" {//printf("Encontrado TKN_MULT: %s\n",yytext);

return(TKN_MULT);}

"/" {//printf("Encontrado TKN_DIV: %s\n",yytext);

return(TKN_DIV);}

"+" {//printf("Encontrado TKN_MAS: %s\n",yytext);

return(TKN_MAS);}

"-" {//printf("Encontrado TKN_MENOS: %s\n",yytext);

return(TKN_MENOS);}

"(" {//printf("Encontrado TKN_PAA: %s\n",yytext);

return(TKN_PAA);}

Page 15: Flex y Bison

")" {//printf("Encontrado TKN_PAC: %s\n",yytext);

return(TKN_PAC);}

"cos" {//printf("Encontrado TKN_COS: %s\n",yytext);

return(TKN_COS);}

"sen" {//printf("Encontrado TKN_SEN: %s\n",yytext);

return(TKN_SEN);}

{ID} {//printf("Encontrado TKN_ID: %s\n",yytext);

return(TKN_ID);}

"\n" {nlines++;}

.

%%

/********

Para el lexico solo

void main(int argc,char **argv)

{

if (argc>1)

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

else

yyin=stdin;

yylex();

printf("\nNumero lineas analizadas: %d\n", nlines);

}

*******/

/* para compilar

flex lexico.l

cc lex.yy.c -o milex -lfl -lm

*/

Fichero sintactico.y (Bison)

%{

/* Ejemplo para una pequeña calculadora que permite trabajar

con numeros enteros y reales con las operaciones básicas de

suma, resta, producto, division y trigonometricas como el seno y el coseno */

#include <stdio.h>

Page 16: Flex y Bison

#include <stdlib.h>

#include <math.h>

extern int yylex(void);

extern char *yytext;

extern int nlines;

extern FILE *yyin;

void yyerror(char *s);

%}

%union

{

float real;

}

%start Calculadora

%token <real> TKN_NUM

%token TKN_ASIGN

%token TKN_PTOCOMA

%token TKN_MULT

%token TKN_DIV

%token TKN_MAS

%token TKN_MENOS

%token TKN_PAA

%token TKN_PAC

%token TKN_COS

%token TKN_SEN

%token <real> TKN_ID

%type Calculadora

%type <real> Expresion

%left TKN_MAS TKN_MENOS

%left TKN_MULT TKN_DIV

%%

Calculadora : TKN_ID { printf("El valor de %s es: ", yytext);}

TKN_ASIGN Expresion TKN_PTOCOMA { printf("%5.2f\n", $4); } ;

Expresion : TKN_NUM {$$=$1;}|

Page 17: Flex y Bison

Expresion TKN_MAS Expresion {$$=$1+$3;}|

Expresion TKN_MENOS Expresion {$$=$1-$3;}|

Expresion TKN_MULT Expresion {$$=$1*$3;}|

Expresion TKN_DIV Expresion {$$=$1/$3;} |

TKN_PAA Expresion TKN_PAC {$$=$2;}|

TKN_COS TKN_PAA Expresion TKN_PAC {$$=cos($3);}|

TKN_SEN TKN_PAA Expresion TKN_PAC {$$=sin($3);};

%%

void yyerror(char *s)

{

printf("Error %s",s);

}

int main(int argc,char **argv)

{

if (argc>1)

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

else

yyin=stdin;

yyparse();

printf("FIN del Analisis. Entrada CORRECTA\n");

printf("Numero lineas analizadas: %d\n", nlines);

return 0;

}

/* para compilar

bison -d sintactico.y

flex lexico.l

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

*/