TALLER DE COMPILADORES (Flex y Bison).

65 views 27 slides Jun 21, 2019
Slide 1
Slide 1 of 27
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27

About This Presentation

TALLER DE COMPILADORES (Flex y Bison).


Slide Content

Compiladores

Rubén Pilca
Utilizando la herramienta de búsqueda de la Web, Investigar los siguientes temas: Herramientas
para la construcción de procesadores de lenguaje.

Contenido
 Reseña Histórica Flex y Bison .................................................................................. 2
 Diseño y construcción de un compilador .................................................................... 2
Las herramientas Flex y Bison. ........................................................................................ 3
 Que es flex .............................................................................................................. 3
 Como se instala Flex y Bison .................................................................................... 3
 Patrones en flex ...................................................................................................... 4
 Emparejamiento de la entrada ................................................................................. 5
 Condiciones de arranque .......................................................................................... 5
 Variables disponibles para el usuario ......................................................................... 5
 Compilación y ejecución en flex de un programa. ............................................................. 5
Introducción a Bison ...................................................................................................... 6
 Símbolos terminales y no terminales ......................................................................... 6
 Sintaxis de las reglas gramaticales (producciones) ...................................................... 6
 Declaraciones en Bison ............................................................................................ 6
 Precedencia de operadores ....................................................................................... 7
 Funcionamiento del analizador ............................................................................... 7
 Ejemplos de compiladores con Flex y Bison ............................................................... 8
Flex y Bison en un solo analizador ................................................................................ 10

Reseña Histórica Flex y Bison

Los primeros lenguajes de programación surgieron de la idea de Charles Babagge, la
cual se le ocurrió a este hombre a mediados del siglo XIX. Era un profesor matemático de
la universidad de Cambridge e inventor inglés, que al principio del siglo XIX predijo
muchas de las teorías en que se basan los actuales ordenadores. Consistía en lo que
él denominaba la maquina analítica, pero que por motivos técnicos 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 aquélla supuesta
máquina de Babagge, en tarjetas perforadas. Como la maquina no llego nunca a
construirse, los programas de Ada, lógicamente, tampoco llegaron a ejecutarse, pero si
suponen un punto de partida de la programación, sobre todo si observamos que en
cuanto se empezó a programar, los programadores utilizaron las técnicas diseñadas por
Charles Babagge, y Ada, que consistían entre otras, en la programación 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 antaño, se
adelantaron un siglo a su época, lo cual describe la inteligencia de la que se hallaban
dotados.

Tanto flex como 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.

Diseño y construcción de un compilador
Actualmente, existen varias herramientas que forman parte del mundo de los
compiladores.

En el proceso de construcción de compiladores se integran muchos conceptos, unos
conocidos y otros no tanto:
-Algoritmos de búsqueda
-Árboles, Hashing
-Programación modular
-Lenguaje Assembly


Herramientas de análisis:
-Analizador léxico
-Analizador semántico
-Analizador sintáctico


Las herramientas Flex y Bison.


Flex es una herramienta que permite generar analizadores léxicos. Mientras que
Bison es un generador de analizadores sintácticos, ambos son herramientas y
mecanismos bastante estructurados para generar analizadores útiles y necesarios para
procesos de compilación.


Que es flex
Flex es 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.

Como se instala Flex y Bison

1. Descargar el software para proceder con la instalación.
2. Instalar el software en la ruta elegida
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 deseamos que flex y bison se integren al conjunto de variables del entorno (esto va
a permitir llamar a flex/bison desde cualquier ubicación en la línea de comandos)
debemos hacer lo siguiente:

5. Instalar un compilador de C como Dev C++
6. Una vez creada la variable global del sistema se puede acceder a flex y bison desde
donde sea sin necesidad de redireccionar a alguna ruta en específico.

Patrones en flex

`x' empareja el caracter `x'
`.' cualquier caracter (byte) excepto una
línea nueva
`[xyz]' una "clase de caracteres"; en este caso, el
patrón empareja una `x', una `y', o una `z'
`[abj-oZ]' una "clase de caracteres" con un rango;
empareja una `a', una `b', cualquier letra
desde la `j' hasta la `o', o una `Z'
`[^A-Z]' una "clase de caracteres negada", es
decir, cualquier caracter menos los que
aparecen en la clase. En este caso,
cualquier caracter EXCEPTO una letra
mayúscula.
`[^A-Z\n]' cualquier caracter EXCEPTO una letra
mayúscula o una línea nueva
`r*' cero o más r's, donde r es cualquier
expresión regular
`r+' una o más r's
`r?' cero o una r (es decir, "una r opcional")
`r{2,5}' donde sea de dos a cinco r's
`r{2,}' dos o más r's
`r{4}' exactamente 4 r's

Emparejamiento de la entrada

Cuando el escáner generado está funcionando, este analiza su entrada buscando
cadenas que concuerden con cualquiera de sus patrones. Si encuentra más de un
emparejamiento, toma el que empareje el texto más largo. Si encuentra dos o más
emparejamientos de la misma longitud, se escoge la regla listada en primer lugar en el
fichero de entrada de Flex. Una vez que se determina el emparejamiento, el texto
correspondiente al emparejamiento (denominado el token) está disponible en el
puntero de carácter global yytext, y su longitud en la variable global entera yyleng.
Entonces la acción correspondiente al patrón emparejado se ejecuta y luego la entrada
restante se analiza para otro emparejamiento. Si no se encuentra un emparejamiento,
entonces se ejecuta la regla por defecto: el siguiente carácter en la entrada se considera
reconocido y se copia a la salida estándar.

Condiciones de arranque

Flex dispone de un mecanismo para activar reglas condicionalmente. Cualquier
regla cuyo patrón se prefije con "<sc>" únicamente estará activa cuando el
analizador se encuentre en la condición de arranque llamada "sc".
Las condiciones de arranque se declaran en la (primera) sección de definiciones de la
entrada usando líneas sin sangrar comenzando con %s seguida por una lista de nombres.
Una condición de arranque se activa utilizando la acción BEGIN. Hasta que se ejecute la
próxima acción BEGIN, las reglas con la condición de arranque dada estarán activas y las
reglas con otras condiciones de arranque estarán inactivas. Las reglas sin condiciones de
arranque también estarán activas.

Variables disponibles para el usuario

A continuación, se describen algunos de los diferentes valores disponibles al usuario en
las acciones de las reglas:
- char *yytext apunta al texto del token actual (última palabra reconocida en algún
patrón). Por ejemplo printf(“%s”, yytext) lo escribiría por pantalla.
- int yyleng contiene la longitud del token actual.

Compilación y ejecución en flex de un programa.

Al ejecutar el comando Flex nombre_fichero_fuente se creará un fichero en C
llamado “lex.yy.c”. Si se compila este fichero con la instrucción “gcc lex.yy.c –ll
–o nombre_ejecutable” (-ll indica enlazar con la biblioteca de lex) se obtendrá
como resultado un fichero ejecutable llamado nombre_ejecutable). El archivo
ejecutable se lanza por defecto como a.out.

El archivo a.out se puede ejecutar directamente una vez que se haya terminado de
compilar. El programa de flex está a la espera de ingresos de cadenas de texto para

analizar, pero si se requiere de textos más complejos se pueden crear ficheros de texto de
entrada.

Introducción a Bison

Bison es un generador de analizadores sintácticos de propósito general que
convierte una descripción para una gramática independiente del contexto (en realidad
de una subclase de éstas, las LALR) en un programa en C que analiza esa gramática.
Es compatible al 100% con Yacc, 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.

Símbolos terminales y no terminales
Los símbolos terminales de la gramática se denominan en Bison tokens y
deben declararse en la sección de definiciones. Por convención se suelen escribir los
tokens en mayúsculas y los símbolos no terminales en minúsculas. Los nombres de los
símbolos pueden contener letras, dígitos (no al principio), subrayados y puntos. Los
puntos tienen sentido únicamente en no-terminales.

Sintaxis de las reglas gramaticales (producciones)
Una regla gramatical de Bison tiene la siguiente forma general:
resultado: componentes...
;
donde resultado es el símbolo no terminal que describe esta regla y componentes son los
diversos símbolos terminales y no terminales que están reunidos por esta regla. Por
ejemplo:
exp: exp ‘+’ exp
;

Se pueden escribir por separado varias reglas para el mismo resultado o pueden unirse
con el caracter de barra vertical ‘|’ así:
resultado: componentes-regla1...
| componentes-regla2...
...
;

Declaraciones en Bison

Las declaraciones de Bison contiene declaraciones que definen símbolos terminales
y no terminales, especifica la precedencia, etc. En algunas gramáticas simples puede que
no necesite ninguna de las declaraciones.

Estructura de un programa en YACC/BISON

%{
Declaraciones globales C
}%
Declaraciones bison
%%
Gramáticas Nombre:prod1|prod2|…|prodn;
Código auxiliar C


Precedencia de operadores

Bison permite especificar estas opciones con las declaraciones de precedencia
de operadores %left y %right. Cada una de tales declaraciones contiene una lista de tokens,
que son los operadores cuya precedencia y asociatividad se está declarando.
Ladeclaración %left hace que todos esos operadores sean asociativos por la izquierda y la
declaración %right los hace asociativos por la derecha. Una tercera alternativa es
%nonassoc, que declara que es un error de sintaxis encontrar el mismo operador dos
veces "seguidas".

La precedencia de operadores se usa cuando existe ambigüedad en operadores dentro de
una expresión, por ejemplo:
1-2*3
El programa debe ser capaz de analizar todas las posibles reglas de los operadores, y su
respectiva jerarquía para saber cual operador ejecutarlo o analizarlo primero.

Funcionamiento del analizador
La fuente de Bison se convierte en una función en C llamada yyparse. Aquí se
describe las convenciones de interfaz de yyparse y las otras funciones que éste necesita
usar. Hay que tener en cuenta que el analizador utiliza muchos identificadores en C
comenzando con ‘yy’ e ‘YY’ para propósito interno. Si utiliza tales identificadores (a
parte de aquellos descritos en el manual) en una acción o en código C adicional en
el archivo de la gramática, es probable que se encuentre con problemas.

Ejemplos de compiladores con Flex y Bison

COMPILADOR CON BISON Y FLEX
GENERADOR DEL EJECUTABLE E INSTALACIÓN DE PROGRAMAS

A continuación, voy a explicar cómo funciona un analizador léxico sintáctico
utilizando las herramientas de flex y bison, para empezar, tenemos que tener
descargados los programas de bison, flex y mingw. Las instalamos, luego vamos a
proceder a configurar nuestras variables de entorno, para eso vamos a: propiedades de
equipo>propiedades del sistema>variables de entorno en este cuadro buscamos PATH
y ponemos editar y agregamos en la ruta ya dada la direccion de la carpeta bin de cada
carpeta de los instaladores: bison, flex y mingw, separándolas con punto y coma; una
vez terminado esto damos en aceptar a todo y necesariamente tenemos que reiniciar el
sistema.
Una vez ya hecho esto, usaremos nuestro analizador léxico en flex y nuestro analizador
sintáctico en bison, de la carpeta de instaladores los archivos "lexico.l" que va a ser para
flex y "sintactico.y" que va a ser para bison, copiamos estos archivos a la carpeta
C:/>GnuWin32>bin; una vez copiada hacia esa carpeta, copiamos la dirección en donde
se pegó esos archivos y abrimos el cmd; ya en el cmd escribimos "cd" ponemos espacio
seguido pegamos la ruta copiada y le damos enter.

Luego escribimos en el cmd "flex lexico.l" y damos enter para general algunos archivos
de flex, lo mismo realizamos para bison, escribimos en el cmd "bison -dy sintactico.y" y
le damos enter y generamos algunos archivos de bison .

A continuación, vamos a copiar los archivos "lex.yy" , "y.tab" y el otro "y.tab" de
la carpeta bin de la carpeta GnuWin32 y lo pegamos en la carpeta bin de la carpeta
MinGW; luego vamos a copiar también el archivo "libfl.a" de la carpeta lib de la carpeta
GnuWin32 y lo pegamos en la carpeta lib de la carpeta MinGW; ahora copiamos la
dirección de la carpeta bin de la carpeta MinGW y nos vamos a cmd, en el cmd
escribimos "cd" espacio y pegamos la dirección que copiamos y le damos enter.

Ahora vamos a utilizar MinGW para que nos proporcione un ejecutable es decir la
ejecución final ya de nuestro compilador, para ello necesitamos la siguiente linea de
código "gcc y.tab.c lex.yy.c -lfl -o salida7" aquí están escritos todos los archivos que se
nos ejecutaron y que nos proporcionó flex y bison salida7 es el nombre de nuestro
ejecutable, copiamos esa linea de código y lo pegamos en el cmd y le damos enter.

Ahora podemos observar que se nos generó el ejecutable "salida7".

Flex y Bison en un solo analizador
Lo primero que tenemos que hacer es tener nuestro Flex y Bison configurados. Luego de eso
debemos tener nuestros archivos tanto para flex como para bison listos.



























ARCHIVO PARA FLEX

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
%{
#include <stdio.h>
#include <conio.h>
#include "parser.h"
%}
%option noyywrap
%option yylineno
letra [a-zA-Z]
digito [0-9]
binario [0-1] ignora
" "|\t|\n operarit
*|+|-|/ operlog &|$
comparador <|>|<=|>=|==|!=
%%
{ignora}+ {;}
"Entero" {printf("Palabra reservada para tipo de dato
entero\n");return PRENTERO;}
"Real" {printf("Palabra reservada para tipo de dato
real\n");return PRREAL;}
"Booleano" {printf("Palabra reservada para tipo de dato
booleano\n");return PRBOOLEANO;}
"Caracter" {printf("Palabra reservada para tipo de dato
caracter\n");return PRCARACTER;}
"Si" {printf("Palabra reservada para
condicional\n");return PRSI;}
"Sino" {printf("Palabra reservada para otro
condicional\n");return PRSINO;}
"SinoSi" {printf("Palabra reservada para definir
condicionales secundarias\n");return PRSINOSI;}
"Entonces" {printf("Palabra reservada para definir accion a
realizar\n");return PRENTONCES;}
"FinSi" {printf("Palabra reservada finalizar
condicional\n");return PRFINSI;}
"Para" {printf("Palabra reservada para bucle de tipo
Para\n");return PRPARA;}
"FinPara" {printf("Palabra reservada para fin de bucle de tipo
Para\n");return PRFINPARA;}
"Mientras" {printf("Palabra reservada para bucle de tipo
Mientras\n");return PRMIENTRAS;}
"Hacer" {printf("Palabra reservada para indicar que se empieza
algo\n");return PRHACER;}
"FinMientras" {printf("Palabra reservada fin de bucle de tipo
Mientras\n");return PRFINMIENTRAS;}
"FinHacerMientras" {printf("Palabra reservada para indicar fin de bucle
Hacer-Mientras\n");return PRFINHACERMIENTRAS;} "Funcion"
{printf("Palabra reservada para declaracion de
funciones\n");return PRFUNCION;}
"Estructura" {printf("Palabra reservada para declaracion de
estructuras\n");return PRESTRUCTURA;}
"FinFuncion" {printf("Palabra reservada para finalizar
funcion\n");return PRFINFUNCION;}
"Retorna" {printf("Palabra reservada para retorno de

52 funcion\n");return PRRETORNA;}
"SinValor" {printf("Palabra reservada para funcion sin valor de
retorno\n");return PRSINVALOR;}

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
"Definir" {printf("Palabra reservada para definir
funciones\n");return PRDEFINIR;}
"Constante" {printf("Palabra reservada para definir
constantes\n");return PRCONSTANTE;}
"Entrada" {printf("Palabra reservada para definir
entradas\n");return PRENTRADA;}
"Salida" {printf("Palabra reservada para definir
salidas\n");return PRSALIDA;}
{letra}({letra}|{digito})* {printf("Identificador\n");return
IDENT;}
{letra}+ {printf("Caracter\n");return
CARACTER;}
{binario}+ {printf("Binario\n");return
BOOLEANO;}
{digito}+ {printf("Entero\n");return ENTERO;}
{digito}+"."{digito}+ {printf("Real\n");return REAL;}
{comparador} {printf("Comparador\n");return
COMPARADOR;}
":=" {printf("Asignador\n");return ASIG;}
";" {printf("Fin sentencia\n");return PCOMA;} "!="
{printf("Diferente\n");return DIF;}
"," {printf("Coma\n");return COMA;}
"==" {printf("Igual\n");return IGUAL;}
"." {printf("Punto\n");return PTO;}
">=" {printf("S igno mayor-igual\n");return MAIGU;} "<="
{printf("Signo menor-igual\n");return MEIGU;} "("
{printf("(\n");return PARIZ;}
")" {printf(")\n");return PARDE;}
">" {printf(">\n");return MAYOR;}
"<" {printf("<\n");return MENOR;}
"{" {printf("{\n");return LLIZ;}
"}" {printf("}\n");return LLDE;}
"+" {printf("+\n");return MAS;}
"-" {printf("-\n");return MENOS;}
"*" {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;
}

Archivo librería parser.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

#ifndef YYSTYPE
#define YYSTYPE int
#endif
#define PRENTERO 257
#define PRREAL 258
#define PRBOOLEANO 259
#define PRCARACTER 260
#define PRSI 261
#define PRSINO 262
#define PRSINOSI 263
#define PRENTONCES 264
#define PRFINSI 265
#define PRPARA 266
#define PRFINPARA 267
#define PRMIENTRAS 268
#define PRHACER 269
#define PRFINMIENTRAS 270
#define PRFINHACERMIENTRAS
271
#define PRFUNCION 272
#define PRFINFUNCION 273
#define PRRETORNA 274
#define PRSINVALOR 275
#define PRESTRUCTURA 276
#define MAS 277
#define MENOS 278
#define POR 279
#define ENTRE 280
#define OLOG 281
#define YLOG 282
#define PRDEFINIR 283
#define PRCONSTANTE 284
#define IDENT 285
#define ENTERO 286
#define REAL 287
#define BOOLEANO 288
#define CARACTER 289
#define COMPARADOR 290
#define ASIG 291
#define PCOMA 292
#define DIF 293
#define COMA 294
#define IGUAL 295
#define PTO 296
#define MAIGU 297
#define MEIGU 298
#define PARIZ 299
#define PARDE 300
#define MAYOR 301
#define MENOR 302
#define LLIZ 303
#define LLDE 304
#define PRSALIDA 305

#define PRENTRADA
306 extern YYSTYPE
yylval;

Con esto ahora debemos definir el archivo para
bison. Archivo para Bison:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
%{
int yystopparser=0;
%}


%token PRENTERO PRREAL PRBOOLEANO PRCARACTER PRSI PRSINO PRSINOSI PRENTONCES PR
PRFINPARA PRMIENTRAS PRHACER PRFINMIENTRAS PRFINHACERMIENTRAS PRFUNCION PRFINFU
YLOG
PRDEFINIR PRCONSTANTE IDENT E NTERO REAL BOOLEANO CARACTER COMPARADOR ASIG PCOMA
MAIGU MEIGU PARIZ PARDE MAYOR MENOR LLIZ LLDE PRSALIDA PRENTRADA
%start inicio

%%
inicio : funcion
| constante
| estructura
;

estructura : PRESTRUCTURA IDENT LLIZ n
n : declaracion n
| declaracion nn
nn : LLDE IDENT PCOMA o
o : estructura
| constante
| funcion
;

constante : PRDEFINIR PRCONSTANTE e
e : PRENTERO IDENT f
| PRREAL IDENT f
| PRBOOLEANO IDENT f
f : ASIG g
g : ENTERO PCOMA y
| REAL PCOMA y
| BOOLEANO PCOMA y
y : constante
| estructura
| funcion
;

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

55 b : IDENT
56 | REAL
57 | ENTERO
58 | BOOLEANO
59
;

60
61
declaracion : PRENTERO c
62
| PRREAL c
63
| PRBOOLEANO c
64 c

65
66
| PRCARACTER c
: IDENT
PCOMA
;
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

a
s
i
g
n
a
c
i
o
n
:
I
D
E
N
T
A
S
I
G
a
:
I
D
E
N
T
P
C
O
M
A
|
E
N
T
E
R
O
P
C
O
M
A
|
R
E
A
L
P
C
OMA
| 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 PR
;

si : PRSI PARIZ sh
sh : comparacion shh
| oplogica shh
shh : PARDE PRENTONCES sentencia h
h : PRFINSI
| PRSINOSI PARIZ comparacion PARDE PRENTONCES sentencia i
i : h
| z
z : PRSINO PRENTONCES sentencia PRFINSI
;

sentencia : declaracion sentencia
| declaracion
| asignacion sentencia
| asignacion
| mientras sentencia
| mientras
| hacermientras sentencia
| hacermientras
| para sentencia

|
p
a
r
a
|
s
i
s
e
n
t
e
n
c
i
a
|
s
i
|
e
n
t
r
a
d
a
s
e
n
t
e
n
c
i
a
|
e
n
t
r
a
d
a
|
s
a
l
i
d
a
sentencia

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
| salida
;

salida : PRSALIDA ASIG LLIZ LLDE
PCOMA
;

entrada : PRENTRADA IDENT PCOMA
;

oparitmetica : MAS PARIZ q
| POR PARIZ q
| suma
| producto
q : oparitmetica PARDE r
suma : MAS r t
producto : POR r t t : r
u
u : t
|
r : IDENT
| REAL
| ENTERO
;


oplogica : OLOG PARIZ qq
| YLOG PARIZ qq
| yy
| oo
qq : oplogica PARDE rr
oo : OLOG rr tt
yy : YLOG rr tt tt
: rr uu
uu : tt
|
rr : comparacion
;


Con esos tres archivos ya casi estamos listos. También dentro del directorio donde están
trabajando (Directorio en donde se encuentra el archivo de flex y bison) deben crear el
siguiente archivo:


Archivo error.c
?

1 void yyerror(char * msg)

2
3
4
{
printf ("%s\n", msg);
}


Ahora solo nos queda compilar los scripts de flex y bison del siguiente modo:


Con esto nuestro directorio de trabajo debería quedar algo así:

Ahora si usan DevC++ solo deben crear un proyecto y añadir todos los archivos ahí
presentes. Observen además que para correr el programa no se nos pedirá que ingresemos
el nombre de del archivo sino que lo debemos mandar como parámetro, en otras palabras
el archivo generado no se debe ejecutar con doble clic sino por medio de la consola del
windows. Creo que una imágen vale más que mil palabras:




El hecho que el programa tenga una forma especial de ejecutarse es que nosotros hicimos
un proyecto en la Universidad en donde desde una aplicación en Java invocabamos a un
ejecutable generado en C que se encargaba de realizar el procesamiento de la gramática
y esa salida la mostrabamos en Java (que lógicamente presenta una mejor interfaz de
usuario). Esto lo cuento a modo de anécdota por si tuvieran que hacer algo similar.


Y bueno, lógicamente también les pondré unos ejemplos de código. El primero es el que
está escrito correctamente:


Codigo00.txt
?

1
Estructura est
{

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Entero num;
Entero nfgj;
Booleano ggnum;
} est1;


Definir Constante Entero numero := 145 ;


Funcion Entero miFuncion( Caracter Cadena; )


Car:=Carro;
Entero Num;


Mientras ( c<d )


Car:=Carro;
Entero bandera;
Booleano boole;
boole:=1;

Mientras ( a>=4 )


Car:=Carro;
Entero bandera;
Booleano boole;
boole:=1;


Para ( a:=14; a<=25; a:= + 5 4 ;(




Si ( a==4 ) Entonces
Bool:=1;
FinSi

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
FinPara




FinMientras


FinMientras


Si ( a==4 ) Entonces
Bool:=1;
FinSi


Retorna Numero


FinFuncion

Y el programa Shark Analyzer 3.0 lo analiza de la siguiente manera:

Y el siguiente código está mal
escrito Codigo01.txt
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


Definir Constante Entero numero := 145 ; Definir
Booleano nume := 1 ;
Funcion Entero ( Entero num; Real fre; Booleano boll;) Mientras (
)
Booleano ghjfg;
bocfgh:=1; Mientras
( a>=4 )
Car:=Carro;
Entero bandera;
Booleano boole;
boole:=1;
Si ( a==4 )
Bool:=1;
Booleano boolean;
SinoSi (a==5) Entonces
Bool:=2;
Sino Entonces
Bool:=3;
FinSi
FinMientras
FinMientras
Retorna Carro
FinFuncion
Shark Analyzer 3.0 nos muestra lo siguiente:
Tags