Flex y Bison
Flex y Bison
Flex y Bison
SEDE IBARRA
1. DATOS INFORMATIVOS
1.1 Nombre: Cristian Proao
1.2 Carrera: Sistemas
1.3 Nivel: 7mo
1.4 Tema: Trabajo de Compiladores
1.5 Fecha: 08-07-2015
2. DESARROLLO
Herramientas para la construccin de procesadores de lenguaje
A continuacin se muestran algunas de las herramientas disponibles que pueden utilizarse
para la realizacin de la Prctica de Procesadores de Lenguajes. Estas herramientas
funcionan bajo Windows, aunque se puede utilizar, si se desea, cualquier otra
herramienta.
Resea Histrica
Los primeros lenguajes de programacin surgieron de la idea de Charles Babagge, la cual
se le ocurri a este hombre a mediados del siglo XIX. Era un profesor matemtico de la
universidad de Cambridge e inventor ingls, que al principio del siglo XIX predijo
muchas de las teoras en que se basan los actuales ordenadores. Consista en lo que l
denominaba la maquina analtica, pero que por motivos tcnicos no pudo construirse
hasta mediados del siglo XX. Con l colaboro Ada Lovedby, la cual es considerada como
la primera programadora de la historia, pues realizo programas para aqulla supuesta
mquina de Babagge, en tarjetas perforadas. Como la maquina no llego nunca a
construirse, los programas de Ada, lgicamente, tampoco llegaron a ejecutarse, pero si
suponen un punto de partida de la programacin, sobre todo si observamos que en cuanto
se empez a programar, los programadores utilizaron las tcnicas diseadas por Charles
Babagge, y Ada, que consistan entre otras, en la programacin mediante tarjetas
perforadas. A pesar de ello, Ada ha permanecido como la primera programadora de la
historia. Se dice por tanto que estos dos genios de antao, se adelantaron un siglo a su
poca, lo cual describe la inteligencia de la que se hallaban dotados.
En 1823 el gobierno Britnico lo apoyo para crear el proyecto de una mquina de
diferencias, un dispositivo mecnico para efectuar sumas repetidas. Pero Babagge se
dedic al proyecto de la mquina analtica, abandonando la mquina de diferencias, que
se pudiera programar con tarjetas perforadas, gracias a la creacin de Charles Jacquard
(francs). Este hombre era un fabricante de tejidos y haba creado un telar que poda
reproducir automticamente patrones de tejidos, leyendo la informacin codificada en
patrones de agujeros perforados en tarjetas de papel rgido. Entonces Babagge intento
crear la mquina que se pudiera programar con tarjetas perforadas para efectuar cualquier
clculo con una precisin de 20 dgitos. Pero la tecnologa de la poca no bastaba para
hacer realidad sus ideas. Si bien las ideas de Babagge no llegaron a materializarse de
forma definitiva, su contribucin es decisiva, ya que los ordenadores actuales responden
a un esquema anlogo al de la mquina analtica. En su diseo, la mquina constaba de
cinco unidades bsicas: 1) Unidad de entrada, para introducir datos e instrucciones; 2)
Memoria, donde se almacenaban datos y resultados intermedios; 3) Unidad de control,
para regular la secuencia de ejecucin de las operaciones; 4) Unidad Aritmtico-Lgica,
que efecta las operaciones; 5) Unidad de salida, encargada de comunicar al exterior los
resultados. Charles Babbage, conocido como el "padre de la informtica" no pudo
completar en aquella poca la construccin del computador que haba soado, dado que
faltaba algo fundamental: la electrnica. El camino sealado de Babbage, no fue nunca
abandonado y siguindolo, se construyeron los primeros computadores.
Cuando surgi el primer ordenador, el famoso ENIAC (Electronic Numerical Integrator
And Calculator), su programacin se basaba en componentes fsicos, o sea, que se
programaba, cambiando directamente el Hardware de la mquina, exactamente lo que s
hacia era cambiar cables de sitio para conseguir as la programacin de la mquina. La
entrada y salida de datos se realizaba mediante tarjetas perforadas.
Algoritmos de bsqueda.
rboles, Hashing.
Programacin modular.
Lenguaje Assembly.
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 ubicacin en la lnea de
comandos) debes hacer lo siguiente:
Clic derecho en Mi PC.
Selecciona Propiedades
Clic en la pestaa Opciones Avanzadas
Presiona el botn Variables de entorno
En la ventana de variables de entorno, ubicarse en la seccin Variables del
sistema luego haz clic en PATH y luego en el botn Modificar (si no est
hacer clic en Nueva y agregar PATH) En la nueva ventana, escribir la ruta
completa al directorio bin de la aplicacin flex/bison. Si existe otro valor,
separarlos con comas.
Aceptar los cambios y luego reiniciar el sistema operativo.
Si se desea invocar a bison (recordar que bison trabaja en conjunto con flex):
Una alternativa es utilizar un compilador para windows como DevC++ o Borland C++
4.5
Abriendo el archivo lex.yy.c y luego compilndolo se generar el ejecutable
lex.yy.exe
BISON y FLEX en conjuncin:
%%
/***************
Reglas
*****************/
/* Creamos las reglas que reconocern 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] {}
""
{}
%{
/********************
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 */
Exp_l:
Exp_l Calc
|Calc
;
Calc
: Exp PTOCOMA {printf ("%4.1f\n",$1)}
;
/* Con el smbolo de $$ asignamos el valor semntico de toda la accin 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
smbolo $ y le concatenamos un nmero que representa la posicin 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;
}
Guardamos este archivo con el nombre sintctico.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 parmetro 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 sintctico.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 compilacin. 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 pestaa permisos elegimos la opcin de Permitir
ejecutar el archivo como un programa, cerramos esa ventana.
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:
EJEMPLO 2
46"FinFuncion"
{printf("Palabra reservada para finalizar
47funcion\n");return PRFINFUNCION;}
{printf("Palabra reservada para retorno de
48"Retorna"
funcion\n");return
PRRETORNA;}
49
{printf("Palabra reservada para funcion sin valor
50"SinValor"
de retorno\n");return PRSINVALOR;}
51
{printf("Palabra reservada para definir
52"Definir"
funciones\n");return PRDEFINIR;}
53
"Constante"
{printf("Palabra reservada para definir
54constantes\n");return PRCONSTANTE;}
55"Entrada"
{printf("Palabra reservada para definir
56entradas\n");return PRENTRADA;}
57"Salida"
{printf("Palabra reservada para definir
58salidas\n");return PRSALIDA;}
{printf("Identificador\n");return
59{letra}({letra}|{digito})*
IDENT;}
60
{letra}+
{printf("Caracter\n");return CARACTER;}
61{binario}+
{printf("Binario\n");return BOOLEANO;}
62{digito}+
{printf("Entero\n");return ENTERO;}
{digito}+"."{digito}+
{printf("Real\n");return REAL;}
63
{comparador}
{printf("Comparador\n");return
64
COMPARADOR;}
65
":="
{printf("Asignador\n");return ASIG;}
66
{printf("Fin sentencia\n");return PCOMA;}
67";"
"!="
{printf("Diferente\n");return DIF;}
68
{printf("Coma\n");return COMA;}
69","
{printf("Igual\n");return IGUAL;}
70"=="
"."
{printf("Punto\n");return
PTO;}
71
{printf("Signo mayor-igual\n");return MAIGU;}
72">="
"<="
{printf("Signo menor-igual\n");return MEIGU;}
73
{printf("(\n");return PARIZ;}
74"("
")"
{printf(")\n");return PARDE;}
75
{printf(">\n");return MAYOR;}
76">"
"<"
{printf("<\n");return MENOR;}
77
{printf("{\n");return LLIZ;}
78"{"
{printf("}\n");return LLDE;}
79"}"
{printf("+\n");return MAS;}
80"+"
81"-"
{printf("-\n");return MENOS;}
82"*"
{printf("*\n");return POR;}
"/"
{printf("/\n");return ENTRE;}
"&"
{printf("&\n");return YLOG;}
"$"
{printf("Operador Logico\n");return OLOG;}
.
{printf("ERROR LEXICO EN LINEA %d
\n",yylineno);}
%%
int main(int argc,char *argv[])
{
if ((yyin = fopen(argv[1], "rt")) == NULL)
{
printf("\nNo se puede abrir el archivo: %s\n", argv[1]);
}
else
{
//yylex();
yyparse();
}
fclose(yyin);
return 0;
}
Arhcivo parser.h
?
1 #ifndef YYSTYPE
2 #define YYSTYPE int
3 #endif
#define PRENTERO 257
4 #define PRREAL
258
5 #define PRBOOLEANO 259
6 #define PRCARACTER 260
261
7 #define PRSI
#define PRSINO
262
8 #define PRSINOSI 263
9 #define PRENTONCES 264
10#define PRFINSI
265
266
11#define PRPARA
12#define PRFINPARA 267
#define PRMIENTRAS 268
13#define PRHACER
269
14#define PRFINMIENTRAS 270
15#define PRFINHACERMIENTRAS 271
272
16#define PRFUNCION
#define PRFINFUNCION
273
17#define PRRETORNA
274
18#define PRSINVALOR
275
19#define PRESTRUCTURA
276
20#define MAS 277
21#define MENOS 278
#define POR 279
22#define ENTRE 280
23#define OLOG 281
24#define YLOG 282
25#define PRDEFINIR 283
26#define PRCONSTANTE 284
#define IDENT 285
27#define ENTERO 286
28#define REAL 287
29#define BOOLEANO 288
30#define CARACTER 289
#define COMPARADOR 290
31#define ASIG 291
32#define PCOMA 292
33#define DIF 293
34#define COMA 294
35#define IGUAL 295
#define PTO 296
36#define MAIGU 297
37#define MEIGU 298
38#define PARIZ 299
39#define PARDE 300
MAYOR 301
40#define
#define MENOR 302
41#define LLIZ 303
42#define LLDE 304
43#define PRSALIDA 305
%{
int yystopparser=0;
%}
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
;
funcion : PRFUNCION j
j : PRENTERO k
| PRREAL k
| PRBOOLEANO k
| PRCARACTER k
| PRSINVALOR k
k : IDENT PARIZ l
l : kl
kl : declaracion l
| ll
ll : PARDE sentencia m
m : PRRETORNA IDENT p
| p
p : PRFINFUNCION funcion
| PRFINFUNCION
;
comparacion : IDENT COMPARADOR b
b : IDENT
| REAL
| ENTERO
| BOOLEANO
;
declaracion : PRENTERO c
| PRREAL c
| PRBOOLEANO c
| PRCARACTER c
c : IDENT PCOMA
;
asignacion : IDENT ASIG a
a : IDENT PCOMA
| ENTERO PCOMA
| REAL PCOMA
| BOOLEANO PCOMA
| oparitmetica PCOMA
;
mientras : PRMIENTRAS PARIZ x
x : comparacion y
| oplogica y
y : PARDE sentencia PRFINMIENTRAS
;
hacermientras : PRHACER sentencia PRFINHACERMIENTRAS PRMIENTRAS
PARIZ cc
cc : comparacion PARDE
| oplogica PARDE
;
para : PRPARA PARIZ asignacion comparacion PCOMA asignacion PARIZ
sentencia PRFINPARA
;
si
sh
: PRSI PARIZ sh
: comparacion shh
| oplogica shh