[ Pobierz całość w formacie PDF ]
.Typ jest oznaczany za pomocą podania nazwy składnika unii wnawiasach trójkątnych w dyrektywie %token, tak jak w poniższym przykładzie:%token tIDENTIFIER%token tNUMBERNastępnym etapem będzie wykorzystanie wartości elementów w parserze.Działania w regułachKażda reguła w specyfikacji gramatycznej programu bison może zawierać fragmenty kodu,podobne do stosowanych w specyfikacji skanera.Zazwyczaj umieszcza się je w regule na końcukażdej alternatywy.Zmienimy teraz kilka reguł gramatycznych, dodając do nich proste działania(tylko w celach pokazowych):statement: tIDENTIFIER tASSIGN expression { printf("assignment seen\n"); }| tIF expression tTHEN statement| tIF expression tTHEN statement tELSE statement| tBEGIN statements tEND;statements: statement| statement ';' statements;expression: tNUMBER { printf("number seen: %d\n", $1); }| tIDENTIFIER { printf("identifier seen: %s\n", $1); }| expression '+' expression| expression '-' expression| expression '>' expression;Zmiany polegają na tym, że po rozpoznaniu instrukcji przypisania będzie wyświetlany komunikat.Komunikaty będą także pojawiać się po wystąpieniu identyfikatora lub liczby w wyrażeniu.Wartość elementu możemy uzyskać, stosując skrótowy zapis $1, który będzie rozwinięty do pełnejpostaci odnoszącej się do składnika unii yylval (w rzeczywistości jest to odniesienie do elementustosu wartości obsługiwanego przez parser, ale nie jest to przedmiot naszego zainteresowania).Dopozostałych elementów w regule można odnosić się za pomocą skrótów $2, $3 itd., zgodnie zmiejscem ich występowania w regule.Np.we fragmencie reguły:| expression '-' expressionwartość semantyczna pierwszego wyrażenia wynosi $1, a drugiego $3.Wartości mają również niezakończone struktury i można zdefiniować ich typy podobnie, jak wwypadku typów elementów.Do tego celu służy dyrektywa %type, która jest wstawiana w częśćdeklaracyjną w specyfikacji gramatycznej.Pisząc np.program obliczeniowy (kalkulator), możnażądać obliczania wartości wprowadzanych wyrażeń.Takie wymaganie mogą spełniać następującefragmenty reguł gramatycznych:%type expressionstatement: tIDENTIFIER tASSIGN expression{ printf("assignment seen, value is %d\n", $3); }| tIF expression tTHEN statement| tIF expression tTHEN statement tELSE statement| tBEGIN statements tEND;expression: tNUMBER { $$ = $1; }| tIDENTIFIER { $$ = 0; /* would be lookup($1); see text */; }| expression '+' expression { $$ = $1 + $3; }| expression '-' expression { $$ = $1 - $3; }| expression '>' expression { $$ = $1 > $3; }Stwierdzamy tutaj, że wyrażenia mają typ numval, czyli że ich wartości mogą byćprzechowywane jako liczby całkowite w składniku numval unii yylval.Można następnie użyćtej wartości wyrażenia w wyświetlanym komunikacie sygnalizującym przypisanie, jeżeli tylko o tozadbamy.Aby takie zadanie wykonać, musimy być pewni, że wszystkie alternatywy w regule opisującej towyrażenie będą zwracały wartość liczbową.W naszym przypadku jest to spełnione.Dooznaczenia zwracanej wartości struktury niezakończonej używamy skrótu $$ (będzie to w tymkonkretnym wypadku expression).Do wartości podwyrażeń w wyrażeniach złożonychodnosimy się tak jak poprzednio za pomocą skrótów $1 i $3.W tym prostym przykładzie dla identyfikatorów zwracana jest wartość zerowa.W pełnej aplikacjimożna by wyszukiwać wartość zmiennej w tablicy symboli.Można także przechować wartośćelementu e, jeśli stwierdzimy, że ma ona być użyta w instrukcji przypisania.W niektórych przypadkach może być potrzebna wartość struktury niezakończonej, której typ nienależy do grupy typów używanych dla elementów.Jako przykład można podać budowę strukturydanych odpowiadającej strukturze wejściowej, a następnie przetwarzanie otrzymanej strukturyjako całości (a nie stopniowe budowanie wyniku).Taka sytuacja może wystąpić przy tworzeniuaplikacji kalkulatora
[ Pobierz całość w formacie PDF ]