flex y bison
Post on 02-Aug-2015
375 Views
Preview:
TRANSCRIPT
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]
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)
"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.
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.
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.
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:
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:
Ejemplos
/*****************
Definiciones
Se colocan las cabeceras, variables y expresiones regulares
********************
%{
#include <stdio.h>
#include <stdlib.h>
#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.
*/
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
%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;
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
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
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);}
")" {//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>
#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;}|
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
*/
top related