De thermostaat uitbreiden om parameters te verwerkenZoals we hebben gezien kunnen we de thermostaat commands nu correct parsen,
en zelfs fouten correct opmerken. Maar als je misschien hebt geraden door de
dubbelzinnige bewoordingen, heeft het programma geen idee wat het zou moeten
doen, de waarden die je invoert worden er niet naar doorgestuurd.Laten we beginnen met het vermogen om de nieuwe doeltemperatuur te lezen.
Hiervoor moeten we de NUMMER match in de Lexer leren zichzelf in een integer
waarde om te zetten, die dan ingelezen kan worden in YACC.Als Lex een doel matcht, stopt het de tekst van de match in de string
`yytext'. YACC op zijn beurt verwacht een waarde in `yylval'. In voorbeeld 5
zien we de voor de hand liggende oplossing:
%{
#include <stdio.h>
#include "y.tab.h"
%}
%%
[0-9]+ yylval=atoi(yytext); return NUMMER;
warmte return TOKWARMTE;
aan|uit yylval=!strcmp(yytext,"aan"); return TOESTAND;
doel return TOKDOEL;
temperatuur return TOKTEMPERATUUR;
\n /* negeer einde regel */;
[ \t]+ /* negeer whitespace */;
%%
Zoals je ziet draaien we atoi() op yytext, en stoppen we de uitkomst in
yylval, waar YACC het kan vinden. Net zoiets voor de TOESTAND match, waarbij
we yylval op 1 zetten als deze `aan' is. Merk op dat een aparte `aan' en
`uit' match in Lex een sneller programma zou genereren, maar ik wilde voor
de verandering een ingewikkelder regel en actie laten zien.Nu moeten we YACC leren hoe hiermee om te gaan. Wat in Lex `yylval' genoemd
wordt, heeft in YACC een andere naam. Laten we de regel die het nieuwe
temperatuurdoel instelt bekijken:target_set:
TOKDOEL TOKTEMPERATUUR NUMMER
{
printf("\tTemperatuur ingesteld op %d\n",$3);
}
;Om toegang te krijgen tot het derde gedeelte van de regel (NUMMER), moeten
we $3 gebruiken. Steeds als yylex() returnt, wordt de waarde van yylval aan
de terminal (vertaler: token) toegekend, en kan benaderd worden met de
$-constructie.Om hier verder op in te gaan, beschouw de nieuwe `heat_switch' regel:
heat_switch:
TOKWARMTE TOESTAND
{
if($2)
printf("\tWarmte aan\n");
else
printf("\tWarmte uit\n");
}
;Als je nu example5 draait, voert het netjes uit wat je hebt ingevoerd.