• No se han encontrado resultados

10 Introducción a BISON/YACC

N/A
N/A
Protected

Academic year: 2021

Share "10 Introducción a BISON/YACC"

Copied!
9
0
0

Texto completo

(1)

10 Introducción a BISON/YACC

Objetivos:

Construir un analizador sintáctico haciendo uso de la herramienta Bison

Recursos:

Maquina virtual Linux distribución Bodhi

LXterminal , Flex , Bison

Introducción

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 lexicos se pueden también obtener de otras formas.

Bison convierte la descripción formal de un lenguaje, escrita como una gramática libre de contexto LALR, en un programa en C,C++, o Java que realiza análisis sintáctico. Es utilizado para crear analizadores para muchos lenguajes, desde simples calculadoras hasta lenguajes complejos. Para utilizar Bison, es necesaria experiencia con la sintaxis usada para describir gramáticas.

Bison es compatible con Yacc (el generador de analizador clásico de los sistemas UNIX), además añade una seríe de características no disponibles en Yacc.

fichero.y ---> BISON ---> fichero.tab.c

fichero.tab.c + (ficheros .c) ---> GCC ---> ejecutable | |-- main() |-- yyerror() |-- yylex() Compilación : $ bison fichero.y

Compila la especificación del analizador y crea el fichero fichero.tab.c con el código y las tablas del analizador LALR(1).

(2)

Con la opción -d ademas del fichero .c se genera fichero.tab.h con las definiciones de las constantes asociadas a los tokens, ademñas de variables y estrucutras de datos necesarias para el analizador léxico.

$ gcc fichero.tab.c (ficheros .c)

El usuario deberá de proporcinar sus propias funciones main(),yyerror() y yylex().

Dentro del código de usuario se deberá llamar a la función yyparse() que a su vez llamará a la función yylex() del analizador léxico cada vez que necesite un TOKEN.

ESTRUCTURA DE UNA ESPECIFICACIÓN BISON

Tres partes separadas por el símbolo %%.

(Las dos primeras son obligatorias, aunque pueden estar vacías)

<sección de declaraciones>

%%

<sección de reglas y acciones>

%%

<sección de rutinas de usuario>

Sección de Declaraciones.

En esta sección se puede incluir :

- Código C necesario para las acciones semánticas.

Se incluye código C necesario para las acciones asociadas a las reglas.

El código C se incluirá entre los símbolos %{ y %}, y será copiado tal cual al fichero XXXX.tab.c.

(Generalmente serán #includes y/o estructuras y variables del código de usuario que se vean afectadas por las acciones)

Definiciones de BISON.

Especificación de YSYTYPE (tipo de todos los posibles valores semánticos)

Incluye la declaración del tipo YYSTYPE, asociado a los elementos de la pila (es decir, el tipo de datos asociado a los tokens y a los no terminales).

(3)

Ej.:

%union {

int entero;

double real;

char * texto;

}

NOTA: Si el tipo es único y común para todos los TOKENs y no terminales se puede especificar el tipo TTSTYPE directamente en la sección de codigo C

Ej.:

%{

#define YYSTYPE double

%}

- Directiva %token

Declara un TOKEN indicado su nombre y opcionalmente su tipo (el tipo deberá ser uno de los identificadores declarados en la directiva %union).

Formato : %token <tipo> nombre

Ej. :

%token BEGIN END IF THEN ELSE

%token <entero> CONSTANTE_ENTERA

%token <real> CONSTANTE_REAL

%token <texto> NOMBRE_VARIABLE NOMBRE_FUNCION

NOTA: No es necesario declarar los TOKENS compuestos por único caracter. Cada caracter que se usa como TOKEN se identifica por el valor numérico de su código ASCII. (Para los demás TOKENS se asignan constantes numéricas empezando en 256)

- Directivas %left %right %nonasoc

Declaran un TOKEN especificando su asociatividad (izquierda, derecha o no asociativo) y determina como actuará el analizador sintáctico cuando se encuentre con una expresión varios TOKENs de ese tipo. Normalmente esos TOKENs serán operadores de algún tipo. Mismo formato que %token

Formato : %left <tipo> nombre

Ej. :

%left '-' '+' '*' '/'

%right '^' '=' - Directiva %type

Especifica el tipo de un no terminal.

No es necesario declarar previamente los no terminales (se diferencian por que aparecen en el lado izq. de las reglas)

Pero si es necesario especificar su tipo en el caso de que tengan asociado valores semánticos.

Formato : %type <tipo> nombre_no_terminal

Ej. :

(4)

%type <entero> expresion_entera

%type <real> expresion_real

Procedimento

Instalando entorno Linux Bodhi

1.

Abra el Virtual Box, en el menú archivo seleccione Importar Servicio Virtualizado y

buscar el archivo Bodhi.ova que se encuentra ubicado en la Unidad D. para poder

agregar la máquina virtual.

2.

La clave es 123456

Una vez iniciado utilizaremos las herramientas de (1) LXTerminal(ubicada en el menú

Aplicaciones->accesorios, la cual utilizaremos para compilar y (2) File Manager que

utilizaremos para el manejo de los archivos para la practica.

Cuando iniciemos las dos herramientas debemos recordar: el File Manager mostrará la

carpeta home/bodhi que es la carpeta principal de los archivos; y en la LXTerminal al abrirla

se estará trabajando en esta dirección por lo que cuando navequemos por las carpetas en la

terminal debemos considerar eso.

Una vez iniciado utilizaremos las herramientas de (1) LXTerminal, la cual utilizaremos para

compilar y (2) File Manager que utilizaremos para el manejo de los archivos para la practica.

Cuando iniciemos las dos herramientas debemos recordar: el File Manager mostrará la

carpeta home/bodhi que es la carpeta principal de los archivos; y en la LXTerminal al abrirla

(5)

se estará trabajando en esta dirección por lo que cuando naveguemos por las carpetas en la

terminal debemos considerar eso.

Ejemplo 1:

Crear un analizador para frases

Primero crearemos el archivo frase.l

%{ #include <string.h> #include "frase.tab.h" %} %% el|la|los|las { return ARTICULO; } hijo|hijo|hijos|hijas | coche|casa|barco | gato|gata|gatos|gatas | manzana|manazanas | pan|panes { return NOMBRE; } azul|rojo|veloz | alto|alta|altos|altas | feo|fea|feos|feas { return ADJETIVO; } come|comen|mira|miran | salta|saltan|rie|rien | vive|viven { return VERBO; } a|de|en|con|por|desde { return PREPOSICION; } \n { return ('\n'); } . ; %%

(6)

Ahora crearemos el archivo frase.y

%{

#include <stdlib.h> #include <stdio.h> #define YYSTYPE char* %}

%token ARTICULO NOMBRE ADJETIVO PREPOSICION VERBO %%

dialogo : frase

| dialogo frase ;

frase : '\n'

| sujeto predicado '\n' {printf("\n>> Frase correcta\n");} ;

sujeto : frase_nominal ;

frase_nominal : NOMBRE

| ARTICULO NOMBRE

| ARTICULO NOMBRE ADJETIVO

| ARTICULO NOMBRE frase_preposicional ;

frase_preposicional : PREPOSICION frase_nominal ; predicado : frase_verbal ; frase_verbal : VERBO | VERBO frase_nominal | VERBO frase_preposicional ; %% int main() { yyparse(); } yyerror (char *s) { printf ("%s\n", s); } int yywrap() { return 1; }

(7)

Para ejecutar utilice los siguientes comandos

$ bison -d frase.y

$ flex frase.l

$ gcc -o frase frase.tab.c lex.yy.c

Luego pruebe con una frase utilizando los parámetros del léxico en el archivo.l

El resultado debe ser igual al de la siguiente figura

Ejemplo 2. Calculadora que permite sumas y restas

Cree el archivo calculadora.l

%{ #include "calculadora.tab.h" %} NUM [0-9]+ %% {NUM} { yylval = atoi(yytext); return (ENTERO); } "+"|"-" { return (yytext[0]); } "\n" { return (yytext[0]); } . ; %%

(8)

Ahora cree el archivo calculadora.y

%{

#define YYSTYPE int #include <math.h> %} /* Declaraciones de BISON */ %token ENTERO %left '-' '+' /* Gramática */ %%

input: /* cadena vacía */ | input line ; line: '\n' | exp '\n' { printf ("\t%d\n", $1); } ; exp: ENTERO { $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } ; %% int main() { yyparse(); } yyerror (char *s) { printf ("%s\n", s); } int yywrap() { return 1; }

(9)

Para ejecutar utilice los siguientes comandos

$ bison -d calculadora.y

$ flex calculadora.l

$ gcc -o calculadora calculadora.tab.c lex.yy.c Nota: Presentará un warning pero se ejecuta el programa

Ejercicios:

o

Modifique la calculadora de manera que acepte multiplicación y

división

Referencias

Documento similar