 
 
 
 
 
 
 
 
 
 










 
%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 %%
 
 
 
 
 
 
 
 
 
 










