yylval voor gevorderden: %unionMomenteel moeten we *het* type van yylval definiëren. Dit is echter niet altijd toepasselijk. Er zijn tijden dat we meerdere datatypen moeten kunnen verwerken. Terugkerend naar onze hypothetische thermostaat, willen we misschien een verwarming die we willen beheersen uitkiezen, als volgt:Verwarming hoofdgebouw `hoofdgebouw' verwarming geselecteerd doel temperatuur 23 `hoofdgebouw' verwarming doel temperatuur nu 23Hiervoor moet yylval een union wezen, die zowel strings als integers kan bevatten - maar niet tegelijk.Bedenk dat we YACC eerder verteld hebben welk type yylval was door YYSTYPE te definiëren. We zouden YYSTYPE op deze manier als union kunnen definiëren, maar YACC heeft hier een gemakkelijker methode voor: het %union statement.Gebaseerd op Voorbeeld 4, schrijven we nu de YACC grammatica van Voorbeeld 7. Eerst de intro: %token TOKVERWARMING TOKWARMTE TOKDOEL TOKTEMPERATUUR %union { int number; char *string; } %token <number> TOESTAND %token <number> NUMMER %token <string> WOORDWe definiëren onze union, die alleen een nummer en een string bevat. Dan leggen we YACC met een uitgebreide %token syntax uit welk deel van de union ieder token moet benaderen.In dit geval laten we het TOESTAND token een integer gebruiken, net als zonet. Hetzelfde geldt voor het NUMMER token, dat we gebruiken om temperaturen te lezen.Nieuw is het WOORD token, dat gedeclareerd is om een string te gebruiken.Het lexerbestand verandert ook een beetje: %{ #include <stdio.h> #include <string.h> #include "y.tab.h" %} %% [0-9]+ yylval.number=atoi(yytext); return NUMMER; verwarming return TOKVERWARMING; warmte return TOKWARMTE; aan|uit yylval.number=!strcmp(yytext,"aan"); return TOESTAND; doel return TOKDOEL; temperatuur return TOKTEMPERATUUR; [a-z0-9]+ yylval.string=strdup(yytext);return WOORD; \n /* negeer einde regel */; [ \t]+ /* negeer whitespace */; %% Zoals je ziet benaderen we de yylval niet meer direct, we voegen een suffix toe om aan te geven welk deel we willen benaderen. In de YACC grammatica hoeft dat echter niet, want YACC doet het voor ons:heater_select: TOKVERWARMING WOORD { printf("\tVerwarming '%s' geselecteerd\n",$2); heater=$2; } ;Vanwege de %token declaratie hierboven kiest YACC automatisch het `string' lid uit onze union. Merk ook op dat we een kopie van $2 opslaan, die later gebruikt wordt om de gebruiker te vertellen naar welke verwarming hij commando's stuurt:target_set: TOKDOEL TOKTEMPERATUUR NUMMER { printf("\tTemperatuur van verwarming '%s' ingesteld op %d\n",heater,$3); } ; Lees voor meer details example7.y.