Ejemplo Flex Bison TiposValores

December 2, 2017 | Author: xuleliezer | Category: Integer, Syntax, Real Number, Areas Of Computer Science, Computer Programming
Share Embed Donate


Short Description

Download Ejemplo Flex Bison TiposValores...

Description

Tipos de valores en Flex y Bison A continuación se detalla un ejemplo de cómo usar Flex y Bison conjuntamente pero asociando valores a los tokens en Flex. Flex puede proporcionar tokens a Bison, y además asociarles un valor: algunos ejemplos típicos son pasarle el token NUMERO_ENTERO asociando a ese token el valor concreto del número leído, o pasarle el token IDENTIFICADOR y asociarle la cadena concreta que corresponde al identificador. Para esto en Flex se usa la variable global yylval, y en Bison la sintaxis $x para acceder a los valores asociados a los tokens. Por defecto yylval es de tipo int. Si sólo queremos pasar valores enteros de Flex a Bison no habrá que declarar nada más, se usará yylval en Flex como si fuera un entero, y en Bison se podrá acceder al valor asociado a cada token utilizando la sintaxis $x de para ese token (los $x se manejarían como variables enteras). Si queremos pasar otros tipos de valores de Flex a Bison, la forma más general es la siguiente: 1. Definir en Bison una unión de los distintos valores posibles. Por ejemplo la siguiente dice que podremos usar enteros y reales: %union { int valInt; float valFloat; } 2. Desde Flex accederemos a los distintos valores de la unión con la sintaxis yylval.nombre: En el ejemplo anterior yylval.valInt sería un entero e yylval.valFloat sería un real. 3. Dentro de Bison habrá que usar las declaraciones de %token para asignar tipos a cada token y las de %type para asignar tipos a los no terminales (al menos a los que se vayan a usar con valores asociados). Hay unas cuantas cosas más que se pueden hacer en Bison, pero no se van a detallar en esta introducción. El siguiente ejemplo debería aclarar cómo se utilizan valores asociados a tokens. El ejemplo también es ilustrativo de cómo se usan los $x para almacenar valores, por ejemplo para acumular las mediciones de temperaturas y luego poder hacer la media.

Ejemplo Flex y Bison Un sensor meteorológico proporciona temperaturas tomadas a distintas horas del día. Cada varios días, no periódicamente, se toma la información que ha proporcionado, se guarda en un fichero de texto, y se analiza. El formato con que llega esta información es el siguiente: horaH valor_temperatura unidades_temperatura horaH valor_temperatura unidades_temperatura ... horaH valor_temperatura unidades_temperatura ... Notas: • Cada línea es una medición de temperatura a una hora concreta. • Hay un número desconocido de mediciones. • El número de mediciones diarias es variable, pero se sabe que el sensor siempre proporciona una medición diaria tomada a las 12 horas. • hora es un entero (que puede tomar valores entre 0 y 23). • valor_temperatura también es un número real (negativo o positivo y siempre con punto decimal). • unidades_temperatura puede tomar dos valores: C (centígrados) y F (farenheit). A continuación se muestra un ejemplo de información de 8 mediciones:

5H 15.0 C 10H 20.25 C 12H 24.52 C 19H 21.0 C 5H 85.5 F 12H 94.2 F 10H 23.5 C 12H 100.2 F

1.1. Escribid un analizador léxico en FLEX para el fichero con la sintaxis dada: Este analizador deberá reconocer los siguientes tokens: Un token para las horas y otro para las temperaturas. Las horas serán un entero seguido de una H (ver el ejemplo de fichero de antes) mientras que las temperaturas serán simplemente un número real. Además se deberán pasar los valores leídos (tanto las horas como las temperaturas) a BISON para su posterior análisis. Un token para cada unidad de temperatura (serán 2 tokens). Ayudas: 1) Para las horas, no hace falta comprobar que las horas están entre las 0 y las 23, si no que basta reconocer un número entero seguido de una H, suponiendo pues que son correctas. 1.2. Escribid un analizador sintáctico en BISON que reconozca una lista de mediciones con la sintaxis dada. Este analizador sintáctico usará el analizador léxico resultante del apartado anterior. También deberá calcular e imprimir por pantalla: El valor de la temperatura a las 12 horas, para cada medición tomada a esa hora y siempre en grados centígrados. El valor medio, en grados centígrados, de la temperatura entre todas las recibidas. La salida del analizador con el fichero de ejemplo de antes debería ser algo así: Temp a las 12 son: 24.520000 C Temp a las 12 son: 34.555553 C Temp a las 12 son: 37.888885 C Temperatura Media en Total: 25.804583 C Nota: Para pasar de X grados farenheit (F) a Y grados centígrados (C) la fórmula es: Y = (X – 32.0) * 5.0 / 9.0.

Solución Fuente Flex (ej1.l) %{ #include #include "y.tab.h" %} entero "-"?[0-9]+ real "-"?[0-9]+"."[0-9]+ %% C {return tCentigrados;} F {return tFarenheit;} {entero}H {yylval.valInt = atoi(yytext); return tHora;} {real} {yylval.valFloat = atof(yytext); return tValorTemperatura;} . ; \n ;

Fuente Bison (ej2.y) %{ int numMedidas = 0; %} %union{ int valInt; float valFloat; } %token tCentigrados tFarenheit %token tHora %token tValorTemperatura %type TEMPERATURA MEDICION LISTA_TEMPERATURAS %start S %% S : LISTA_TEMPERATURAS {printf("Temperatura Media en Total: %f C\n", $1/(float)numMedidas);} ; LISTA_TEMPERATURAS : LISTA_TEMPERATURAS MEDICION {$$ = $1 + $2; numMedidas++;} | MEDICION {$$ = $1; numMedidas++;} ; MEDICION : tHora TEMPERATURA { if ($1 == 12) { printf ("Temp a las 12 son: %f C\n", $2); } $$ = $2; } ; TEMPERATURA : tValorTemperatura tCentigrados {$$ = $1;} | tValorTemperatura tFarenheit {$$ = (($1 - 32.0) * 5.0) / 9.0;} ; %% main() { yyparse(); }

Compilar flex ej1.l bison ej2.y -yd gcc lex.yy.c y.tab.c -ll -ly

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF