Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Protesis
Protesis
Flex - Bison
Objetivos 1ª parte
●
¿Qué son Flex y Bison?
●
Instalación.
●
Compilación.
●
Compilación - ejemplo.
●
Flex: “Fast Lexical Analyzer”.
●
Es un generador de analizadores léxicos (scanners).
●
Genera código fuente en C.
●
Distribuido bajo licencia BSD.
●
Disponible en: https://github.com/westes/flex/releases
●
Bison.
●
Es un generador de analizadores sintácticos (parsers).
●
Compatible con YACC (Yet Another Compiler-Compiler).
●
Genera código fuente en C, C++, Java.
●
Distribuido bajo licencia GPL.
●
Disponible en: https://www.gnu.org/software/bison/
●
Requisito: se requiere un compilador de C (GCC por ejemplo).
●
Ambos son de instalación sencilla. Sólo hay que descargar el código fuente y
seguir los pasos de instalación.
●
Linux: se puede instalar desde los repositorios.
Compilador a.out
de C
<file.tab.c>
Especificación Compilar con
Bison Y
Bison (GLC*) <file.tab.h>
●
Más sobre Flex.
●
Analizador léxico.
●
Ejemplo.
●
ER (expresiones regulares).
●
El scanner como corutina.
●
Es un generador de analizadores léxicos (scanners).
●
Genera código fuente en C.
Compiolador a.out
de C
<file.tab.c>
Especificación Compilar con
Bison Y
Bison (GLC) <file.tab.h>
Definiciones y opciones
%{
%}
%%
[Compilar y probar]
>> flex soloReglas.l
>> gcc lex.yy.c -lfl
>> ./a.out
Patrón Acción
Regla
Donde:
[Contador de caracteres]
/*DEFINICIONES*/
%{
int caracteres = 0;
%}
/*REGLAS*/
%% IMPORTANTE:
[a-zA-Z]+ { caracteres += strlen(yytext); }
\n { caracteres++; }
. { caracteres++; } Bloque reglas: SIN COMENTARIOS
%% yytext: patrón actual.
/*CODIGO C*/
yylex(): analizador léxico creado por Flex.
main(int argc, char **argv) Utilizar GCC + “lfl”.
{
yylex();
printf("%8d\n", caracteres);
}
Patrón Descripción
“x” Coincide únicamente con “x”.
. (punto) Coincide con cualquier carácter excepto nueva línea.
Coincide con “x” con “y” o con “z” (sólo una de las
[xyz]
tres).
Coincide con una “a” o con una “b” o con cualquier
[abj-o]
letra entre la “j” y la “o”.
Clase de caracteres negados. Coincide con cualquier
[^A-Z]
carácter menos excepto una letra mayúscula.
Cero o más ocurrencias de la expresión regular r (por
r*
ej: [0-9]*).
Una o más ocurrencias de la expresión regular r (por
r+
ej: [0-9]+).
r|s r o s (unión).
r? Cero o una ocurrencia de r.
r{3-6} De 3 a 6 ocurrencias de r.
%%
"+" { printf("MAS\n"); }
[0-9]+ { printf("NUMERO %s\n", yytext); }
\n { printf("SALTO LINEA\n"); }
[ \t] { }
. { printf("CARACTER DESCONOCIDO %s\n", yytext); }
%%
Ahora vamos a modificar nuestro escáner para que devuelva tokens para que un analizador
sintáctico los pueda utilizar...
%%
"+" { return SUMA; }
[0-9]+ { return NUMERO; }
[ \t] { /*ignorar espacios en blanco*/ }
%%
Tokens y valores
Cuando un escáner de Flex devuelve un flujo de tokens, cada token tiene dos
partes: el token y el valor del token. Es decir, un token es representado por un
entero pequeño. La cantidad de los tokens es arbitraria, excepto que el token cero
siempre significa fin de archivo. Cuando Bison crea un analizador sintáctico
(parser), este asigna automáticamente los números de token a partir de 258 (esto
evita colisiones con tokens de caracteres literales -ASCII) y crea un archivo con
extensión “.h” con definiciones de los números de tokens.
Token en sí
Token
●
Más sobre Bison.
●
Especificaciones.
●
Ejemplo (combinando Flex y Bison).
●
Es un generador de analizadores sintácticos (parsers).
●
Genera código fuente en C, C++, Java.
Compiolador a.out
de C
<file.tab.c>
Especificación Compilar con
Bison Y
Bison (GLC) <file.tab.h>
Definiciones y opciones
%{
%}
%%
●
Reglas: gramática libre de contexto (BNF) y acciones.
Donde:
<lado_derecho>: cadena de terminales (devueltos por el analizador léxico) y auxiliares (o no terminales).
<accion>: código C que se ejecuta.
Por ejemplo:
expresion : expresion OPSUMA expresion
| CTE
;
●
Código C: es el código C que se copia al escáner generado, por lo general pequeñas rutinas relacionadas con el
código en las acciones
⟨expresion⟩::=NUMERO+ NUMERO
Cada símbolo en una regla de Bison tiene un valor. El valor del símbolo de la parte
izquierda (target) de la producción se representa por $$ en el código, mientras que
los símbolos del lado derecho de la producción están numerados $1, $2, $3, …
El valor de los tokens viene de la variable yylval (“NUMERO” y “OPSUMA”) y el
valor de los otros símbolos (“expresion” en nuestro caso) están determinados por
las reglas en el parser.
[Y el archivo “.l”]
/*flexReglasParaSumaEnteros.l*/
%{
#include "bisonReglasSumaSimple.tab.h" Ya no hace falta declarar los
%}
%% tokens, pues lo hace Bison y los
"+" { return SUMA; } almacena en el archivo
[0-9]+ { yylval = atoi(yytext); return NUMERO; } <file.tab.c>
[ \t] { }
. { printf("Carácter desconocido %c\n", *yytext); }
%%
expresion:termino
∣ expresion OPSUMA termino { $$ = $1 + $3; }
;
termino : NUMERO ;
termino: NUMERO
;
%%
int main()
{
yyparse();
}
int yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
}
%{
int yylex();
int yyerror(char *);
#include <stdio.h>
%}
%% [Compilar y probar]
e: 'x'|
'y'|
'(' e '+' e ')'| >> bison soloReglas.y
'(' e '*' e ')' >> gcc soloReglas.tab.c -ly
%%
>> ./a.out
int yylex()
{char c = getchar();
if(c == '\n') return 0;
else
return c;}
void main()
{
printf("%i\n", yyparse());
}
●
“flex & bison”; John R. Levine; O'REILLY – 2009.
●
Universitat Politècnica de València – UPV - Canal oficial de la UPV en
el que se publican vídeos institucionales, informativos y docentes
producidos por la Universitat Politècnica de València.
URL: https://www.youtube.com/user/valenciaupv