next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: El Cuerpo Sup: La Gramática de yapp Ant: La Cabecera Err: Si hallas una errata ...


La Cabecera: Diferencias entre yacc y yapp

Las declaraciones de tipo correspondientes a %union y a las especificaciones de tipo entre símbolos menor mayor (<tipo>) en declaraciones token y %type no son usadas por yapp. Estas declaraciones son necesarias cuando el código de las acciones semánticas se escribe en C como es el caso de yacc y bison. Sigue un ejemplo de programa yacc/bison que usa declaraciones %union y de tipo para los atributos:

 1 %{
 2 #include <stdio.h>
 3 
 4 #define CLASE(x) ((x == 1)?"global":"local")
 5 #define TIPO(x) ((x == 1)?"float":"integer")
 6 %}
 7 
 8 %union {
 9   int n;   /* enumerado */
10   char *s; /* cadena */
11 }
12 
13 %token <n> FLOAT INTEGER 
14 %token <n> GLOBAL 
15 %token <n> LOCAL 
16 %token <s> NAME
17 %type <n> class type
18 
19 %%
La declaración %union de la línea 8 indica que los atributos son de dos tipos: enteros y punteros a caracteres. El nombre del campo es posteriormente usado en las declaraciones de las líneas 13-17 para indicar el tipo del atributo asociado con la variable o con el terminal. Así, la declaración de la línea 13 indica que los terminales FLOAT e INTEGER son de tipo entero, mientras que la declaración de la línea 16 nos dice que el terminal NAME es de tipo cadena.
29 class
30   : GLOBAL { $$ = 1; }
31   | LOCAL  { $$ = 2; }
32   ;
33 
34 type
35   : FLOAT   { $$ = 1; }
36   | INTEGER { $$ = 2; }
37   ;
La información proveída sobre los tipos permite a yacc introducir automáticamente en el código C producido los typecasting o ahormados para las asignaciones de las líneas 30-31 y 35-36. Obsérve que en yacc el atributo de la variable en la parte izquierda se denota por $$.

Otra diferencia entre yacc y yapp es que en yacc los atributos de la parte derecha no constituyen un vector, denotándose por $1, $2, $3 ...

En ocasiones yacc no puede determinar el tipo de un atributo. En particular cuando se habla del atributo asociado con una acción intermedia, ya que esta no tiene variable sintáctica asociada explícitamente o bien cuando se habla de los atributos de símbolos que están a la izquierda de la reducción actual (véase la sección 8.28). Los atributos de símbolos a la izquierda de la producción actual se denotan en yacc por números no positivos $0, $-1, $-2 ....

En estos casos el programador deberá especificar explícitamente el tipo del atributo usando la notación $<tipo>#. Donde tipo es uno de los campos de la union y # es el numeral del símbolo correspondiente:

39 namelist
40   : NAME   { printf("%s de clase %s, tipo %s\n",$1,CLASE($<n>-1),TIPO($<n>0)); }
41   | namelist ',' NAME 
42       { printf("%s de clase %s, tipo %s\n",$3,CLASE($<n>-1),TIPO($<n>0)); }
43   ;
44 %%


next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: El Cuerpo Sup: La Gramática de yapp Ant: La Cabecera Err: Si hallas una errata ...
Casiano Rodríguez León
2012-05-22