Laboratorium z użyciem analizatora leksykalnego FLEX

Podobne dokumenty
Generatory analizatorów

L E X. Generator analizatorów leksykalnych

Wstęp do Programowania, laboratorium 02

Podstawy Kompilatorów

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.

Analiza leksykalna i generator LEX

Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Generator skanerów Flex

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane

Ćwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013

Podstawy Kompilatorów

Część 4 życie programu

Argumenty wywołania programu, operacje na plikach

Programowanie w języku Python. Grażyna Koba

Podstawy programowania skrót z wykładów:

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.

Flex - generator analizatorów leksykalnych

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

Laboratorium 6: Ciągi znaków. mgr inż. Leszek Ciopiński dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak

automatem skończonym niedeterministycznym (ang. nondeterministic finite automaton) M N nazywamy system:

INFORMATYKA Studia Niestacjonarne Elektrotechnika

Skrypty powłoki Skrypty Najcz ciej u ywane polecenia w skryptach:

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Ćwiczenia nr 11. Translatory. Wprowadzenie teoretyczne

1 Podstawy c++ w pigułce.

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wstęp do programowania. Wykład 1

2 Przygotował: mgr inż. Maciej Lasota

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

Generator analizatorów leksykalnych - Lex. Bartosz Bogacki.

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Przedstawię teraz tzw. podstawowe symbole wyrażenia regularne (BRE, Basic Regular Expression)

Języki i metodyka programowania. Wprowadzenie do języka C

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 10 Kurs C++

4. Funkcje. Przykłady

Analiza leksykalna 1. Teoria kompilacji. Dr inż. Janusz Majewski Katedra Informatyki

1 Podstawy c++ w pigułce.

#include <stdio.h> int main( ) { int x = 10; long y = 20; double s; s = x + y; printf ( %s obliczen %d + %ld = %f, Wynik, x, y, s ); }

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,

Matematyczne Podstawy Informatyki

#include <stdio.h> void main(void) { int x = 10; long y = 20; double s; s = x + y; printf ( %s obliczen %d + %ld = %f, Wynik, x, y, s ); }

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

OPERACJE WEJŚCIA / WYJŚCIA. wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout)

Szablony klas, zastosowanie szablonów w programach

Analiza leksykalna 1. Języki formalne i automaty. Dr inż. Janusz Majewski Katedra Informatyki

Laboratorium 3: Tablice, tablice znaków i funkcje operujące na ciągach znaków. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

Język C, tablice i funkcje (laboratorium, EE1-DI)

Podstawy programowania w języku C++

System operacyjny Linux

Pliki. Informacje ogólne. Obsługa plików w języku C

Programowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw

2. Zmienne i stałe. Przykłady Napisz program, który wypisze na ekran wynik dzielenia 281 i 117 w postaci liczby mieszanej (tj. 2 47/117).

Zmienne, stałe i operatory

Biblioteka standardowa - operacje wejścia/wyjścia

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Wskaźniki. Informatyka

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Programowanie w językach wysokiego poziomu

JĘZYK SHELL JEST PEŁNYM JĘZYKIEM PROGRAMOWANIA

Struktura pliku projektu Console Application

Zakład Systemów Rozproszonych

Materiał. Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Funkcje Wskaźniki Referencje Tablice dynamiczne Typ string Przeładowania funkcji

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Języki programowania obiektowego Nieobiektowe elementy języka C++

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Podstawy Programowania Podstawowa składnia języka C++

Wstęp do informatyki- wykład 11 Funkcje

I - Microsoft Visual Studio C++

Język C, tablice i funkcje (laboratorium)

Wstęp do informatyki- wykład 9 Funkcje

Podstawy Kompilatorów

Pytania sprawdzające wiedzę z programowania C++

Język C++ zajęcia nr 2

Skanowanie OCR w aplikacji Kancelaria Komornika. Instrukcja dla użytkownika

Programowanie w C++ Wykład 1. Katarzyna Grzelak. 26 luty K.Grzelak (Wykład 1) Programowanie w C++ 1 / 28

Zadanie analizy leksykalnej

Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego

Podstawy programowania w C++

Systemy operacyjne. System operacyjny Linux - wstęp. Anna Wojak

Język C : programowanie dla początkujących : przewodnik dla adeptów programowania / Greg Perry, Dean Miller. Gliwice, cop

1. Wprowadzenie do C/C++

Instrukcja do ćwiczenia P4 Analiza semantyczna i generowanie kodu Język: Ada

Wstęp do programowania obiektowego. Przekazywanie parametrów do funkcji w C++ Metody i funkcje operatorowe Strumienie: standardowe, plikowe, napisowe

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

5 Przygotował: mgr inż. Maciej Lasota

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Warto też w tym miejscu powiedzieć, że w C zero jest rozpoznawane jako fałsz, a wszystkie pozostałe wartości jako prawda.

Podział programu na moduły

1. Wprowadzenie do C/C++

#include <iostream> using namespace std; void ela(int); int main( ); { Funkcja 3. return 0; }

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Program 14. #include <iostream> #include <ctime> using namespace std;

Transkrypt:

Laboratorium z użyciem analizatora leksykalnego FLEX Analizator leksykalny FLEX jest narzędziem służącym do tworzenia programów rozpoznających wzorce. FLEX na podstawie pliku wejściowego, za pomocą reguł i powiązanych z nimi akcji, tworzy program analizatora leksykalnego, który opiera się o maszynę stanów. Wynik działania tego programu jest zapisany w postaci kodu języka C, gdzie główna metoda rozpoczynająca działanie analizatora leksykalnego została nazwana yylex(). Analizator po pobraniu danych z wejścia dopasowuje wyrażenia regularne do podanych wzorców i wykonuje zdefiniowane dla nich akcje. Struktura pliku Plik podawany na wejście analizatora leksykalnego FLEX ma następującą postać: SEKCJA DEFINICJI SEKCJA REGUŁ SEKCJA KODU UŻYTKOWNIKA Przykłady najkrótszego programu, który przepisuje dane z wejścia na wyjście: %option noyywrap int main() Sekcja definicji Sekcja definicji zawiera deklaracje prostych nazwanych definicji, co ma za zadanie uprościć pisanie analizatora leksykalnego. Dodatkowo znajdują się tutaj definicję stanów analizatora. Składnia nazwanej definicji jest następująca: NAZWA DEFINICJA gdzie NAZWA jest dowolnym słowem, natomiast DEFINICJA jest zapisem wyrażenia regularnego. W sekcji reguł odwołujemy się do nazwanych definicji w następujący sposób: 1

NAZWA Przykłady nazwanych definicji: MAŁE [a-z]* CYFRY [0-9]? Jakikolwiek tekst nierozpoczynający się od pierwszego wiersza jak i wzięty w % % jest kopiowany bezpośrednio do pliku wyjściowego. Można również za pomocą bloku %top określić część tekstu, która ma zostać przekopiowana bezpośrednio do pliku wyjściowego, ale na samą górę tego pliku. Sekcja reguł Sekcja reguł składa się z serii reguł o następującym formacie: WZORZEC AKCJA, gdzie WZORZEC nie może być wcięty (nie może rozpoczynać go spacja) oraz AKCJA musi zaczynać się w tej samej linii. Przykłady reguł: [A-Z]* CYFRA printf( Rozpoznano duże litery %s, yytext); printf( Rozpoznano cyfrę ); Sekcja kodu użytkownika Sekcja kodu użytkownika jest opcjonalną częścią pliku, która jest bezpośrednio kopiowana do pliku wyjściowego. Zazwyczaj są tutaj umieszczane definicje funkcji napisanych w języku C, które wywoływane są w akcjach. Komentarze FLEX wspiera komentarze zgodnie ze składnią języka C i wszystko co znajduje się między znakami /* i */ kopiuje bezpośrednio do pliku wyjściowego. Jednak żeby komentarz nie został pomylony przez analizator z regułą, sugeruje się, aby nigdy nie rozpoczynał się on w pierwszej kolumnie. Wyrażenia regularne Wzorce zapisuje się za pomocą rozszerzonego zestawu wyrażeń regularnych. Poniżej wyrażenia regularne zgodnie z zapisem we FLEX Wzorzec Opis X Dopasuj znak X.. Dopasuj dowolny znak poza znakiem końca linii. \n Dopasuj koniec linii. [abc] (klasa znaków) Dopasuj znak a lub b lub c. [ab-fz] (klasa znaków z wykorzystaniem operatora zakresu) Dopasuj znak a lub od b do f lub z. [^A-C] (zanegowana klasa znaków) Dopasuj dowolny znak poza A, B i C. [a-z]* (* - zero lub wiele powtórzeń wyrażenia regularnego). Dopasuj ciąg składający się z zera lub wielu małych liter. [a-z]+ (+ - jedno lub wiele powtórzeń wyrażenia regularnego). Dopasuj 2

ciąg składający się z jednej lub wielu małych liter. [a-z]? (? zero lub jedno powtórzenie). Dopasuj ciąg składający się z żadnej lub jednej małej litery. [a-z]2,5 (n,m powtarzaj od n do m razy). Dopasuj ciąg skłdający się z od 2 do 5 małych liter. [a-z]2, (n,m). Dopasuj ciąg skłdający się z co najmniej 2 małych liter. [a-z]2 (n powtarzaj n razy). Dopasuj ciąg składający się z dokładnie 2 małych liter. CYFRY Odwołanie się do nazwanej definicji. Karolina Dopasuj ciąg do napisu Karolina. ([a-z]) (operator () do nadawania łączności regułom). [a-z] [A-Z] ( - operator wyboru) Dopasuj małą lub dużą literę. [a-z][a-z] (regularne wyrażenia następujące po sobie). Dopasuj ciąg znaków, gdzie pierwsza litera jest mała, a druga duża. A /[a-z] (dopasowanie warunkowe). Dopasuj A, ale tylko jeżeli występuje po nim mała litera. ^[a-z] (początek linii). Dopasuj małą literę, ale tylko na początku linii. [a-z]$ (koniec linii). Dopasuj małą literę ale tylko, jeżeli jest na końcu linii. <<EOF>> Koniec pliku. Dodatkowo zostały zdefiniowane pewne klasy wyrażeń znakowych, których nazwa jest podawana między znakami [: i :] i dodatkowo przy tworzeniu wyrażenia regularnego musi być wzięta w nawiasy kwadratowe. Klasa wyrażeń Znaczenie [[:lower:]] małe litery [[:upper:]] duże litery [[:digit:]] cyfry [[:space:]] spacja Działanie analizatora Po uruchomieniu analizator stara sie dopasować zadany ciąg znaków do wzorców znajdujących się w sekcji reguł w następujący sposób: W przypadku, gdy można dopasować kilka wzorców zawsze wybierany jest ten, który dopasowuje najwięcej znaków. Jeżeli istnieją dwa wzorce dopasowujące tą samą liczbę znaków, zawsze wybrany zostanie ten, który został zdefiniowany jako pierwszy. Po dopasowaniu do wzorca w akcji można odczytać dopasowany ciąg znaków poprzez odwołanie się do zmiennej yytext, natomiast długość bieżącego dopasowania jest przechowywana w zmiennej yyleng. Domyślnie zmienna yytext jest tablicą znakową o długości 256 znaków, jednak istnieje możliwość zdefiniowania jej jako wskaźnik poprzez zastosowanie przełącznika %pointer. Po dopasowaniu wzorca wywoływana jest akcja z nim związana, a następnie pozostała część ciągu znaków na wejściu jest dopasowywana do wzorców. 3

Przykłady zastosowania reguł: %option noyywrap LETTERS [a-z]* INTEGER [1-9][0-9]* 0 REAL INTEGER"."[0-9]+ DZIEN [1-9] 1[0-9] 2[0-9] 30 MIESIAC [1-9] 1[0-2] ROK [1-9][0-9]0,2 1[0-9]0,3 200[1-9] 20[1-4][0-9] 2050 DATA DZIEN"-"MIESIAC"-"ROK [^0-9] printf("to nie jest liczba %s\n", yytext); ^[a-z] printf("znak na poczatku linii %s\n", yytext); [a-z]$ printf("znak na koncu linii %s\n", yytext); REAL printf("rozpoznano liczbe zmiennoprzecinkowa %s\n", yytext); INTEGER printf("rozpoznano liczbe calkowita %s\n", yytext); DATA printf("rozpoznano date %s\n", yytext); LETTERS/INTEGER yytext); printf("rozpoznano litery przed liczbami %s\n", \n printf("koniec linii");. printf("nierozpoznany znak"); int main() Akcje Z każdym wzorcem połączona jest akcja, która może być dowolną instrukcją napisaną w języku C. Domyślnie akcja powinna zostać zapisana w jednej linii zaraz po wzorcu. W przypadku, gdy składa się ona z wielu instrukcji można zapisać instrukcje kolejno w jednej linii lub zapisać je w osobnych liniach; wtedy jednak należy zamknąć blok instrukcji w nawiasy i, dodatkowo takie rozwiązanie sprawia, że kod jest czytelniejszy. W akcjach można modyfikować zawartość zmiennej yytext, jednak nie można zmieniać jej długości, czy dopisywać znaków na końcu, gdyż spowoduje to nadpisanie znaków pobranych na wejściu analizatora; tych które nie zostały jeszcze przetworzone. W akcjach można również zmieniać wartość zmiennej yyleng, jednak jest to zabronione w przypadku gdy w tej samej akcji korzysta się z funkcji yymore(). Predefiniowane dyrektywy, z których można korzystać w akcjach: Dyrektywa Znaczenie ECHO Kopiuje zawartość zmiennej yytext na wyjście analizatora. BEGIN() Pozwala przechodzić między stanami w analizatorze leksykalnym. 4

REJECT yymore() yyless(int n) unput(char c) input() Wymusza na analizatorze znalezienie następnej pasującej reguły i wykonanie dla niej akcji. Wymusza na analizatorze pozostawienie w zmiennej yytext dopasowanego tokena, tak aby był on widoczny po dopasowaniu następnej reguły. Przesyła na wejście analizatora wszystkie poza n pierwszymi znakami z właśnie dopasowanego tokena, by umożliwić ich kolejne przetworzenie. Przesyła znak na wejście analizatora. Ten znak będzie jako pierwszy wzięty do dopasowania do wzorca. Pobiera kolejny znak z wejścia analizatora. Program do zliczania linii i znaków w pliku: %option noyywrap % % #include <stdlib.h> int liczbaznakow = 0; int liczbalinii = 0; \n liczbaznakow++;liczbalinii++;. liczbaznakow++; int main(int argc, char** argv) if(argc > 1) yyin = fopen(argv[1], r ); printf("liczba znaków wynosi %d natomiast liczba linii to %d", liczbaznakow, liczbalinii); fclose(yyin); Zadania: 1. Napisz program, który będzie zliczał liczbę liter oraz cyfr w linii tekstu. Po wciśnięciu entera powinien wypisać wynik. 2. Napisz program, który będzie liczył liczbę słów w podanej linii tekstu i po wciśnięciu entera wypisze wynik na ekranie. Wygenerowany analizator Wynikiem działania programu FLEX jest program zapisany w pliku lex.yy.c, który zawiera główną metodę yylex() oraz wygenerowane tablice służące do rozpoznawania tokenów oraz listę wygenerowanych makr oraz funkcji. 5

Metoda yylex() pobiera zawsze dane ze strumienia, do którego można mieć dostęp poprzez globalną zmienną plikową yyin (domyślnie jest to stdin), i działa tak długo, aż dotrze do końca pliku lub jedna z jej akcji będzie zawierała wyrażenie return. W przypadku gdy analizator dojdzie do końca pliku, kolejne odwołania do niego są niezdefiniowane, chyba że zmiennej yyin zostanie przypisany nowy plik z danymi do przetworzenia. W przypadku zakończenia pracy analizatora po wykonaniu wyrażenia return, kolejne wywołanie funkcji yylex() spowoduje wznowienie pracy analizatora w miejscu, gdzie ostatnio skończył. Gdy zostanie rozpoznany stan końca pliku, analizator automatycznie przechodzi do funkcji yywrap(). Jeżeli nie jest ona zdefiniowana, należy włączyć opcję %noyywrap, by została ona wygenerowana automatycznie. Funkcja yywrap domyślnie zwraca wartość prawda. Jeżeli jednak chcielibyśmy kontynuować pracę analizatora, powinniśmy zastąpić domyślną definicję tej funkcji w części kodu użytkownika i przypisać zmiennej yyin nowy plik, który będzie przetwarzany. Domyślnie strumień wyjściowy analizatora jest połączony ze standardowym wyjściem na ekran (stdout). Jednak istnieje możliwość przekierowania go na dowolne inne wyjście poprzez odpowiednie przedefiniowanie globalnej zmiennej plikowej yyout. Obsługa końca pliku Istnieje specjalny wzorzec <<EOF>>, który umożliwia wykonanie akcji w momencie, gdy został rozpoznany koniec pliku i jednocześnie funkcja yywrap() zwróciła prawdę. Akcje wykonane w przypadku dopasowania tego wzorca mogą być następujące: Przypisać zmiennej yyin nowy strumień. Wykonać instrukcję return. Wykonać funkcję yyterminate(), która informuje skaner o tym, że wszystko z wejścia zostało przetworzone i można zakończyć pracę. Przełączyć się między buforami za pomocą funkcji yy_switch_to_buffer. Wzorzec <<EOF>> nie może być łączony z innymi wzorcami. Jeżeli istnieje wzorzec <<EOF>> nieprzypisany do żadnego stanu, to będzie on dopasowywany w każdym ze stanów, jeżeli dla danego stanu nie został taki wzorzec zdefiniowany. Stany analizatora FLEX umożliwia warunkowe rozpoznawanie wzorców. Wykorzystywane są w tym celu stany analizatora. Stany analizatora definiuje się w sekcji definicji poprzez rozpoczęcie linii przełącznikiem %s lub %x i następnie podanie listy nazw stanów oddzielonych przecinkami. %s definiuje stany łączne, czyli takie, które rozpatrują również wzorce nie przypisane do żadnego stanu. Natomiast %x definiuje stany wyłączne i w tym przypadku rozpatrywane są wzorce należące tylko do tego stanu. W sekcji reguł analizatora każdy wzorzec może zostać przypisany do wybranego stanu lub grupy stanów w następujący sposób: 6

<STAN>WZORZEC %s definiuje stan inclusive (łączny) INITIAL %x definiuje stan exlusive (wyłączny) INITIAL gdzie STAN jest nazwą stanu zdefiniowaną w sekcji definicji. W przypadku większej liczby STANów należy rozdzielić je spacją. Dodatkowo, jeżeli do jednego stanu chcemy przypisać więcej wzorców, można zastosować następującą konstrukcję: <STAN> WZORZEC_1... WZORZEC_2 Po rozpoczęciu pracy analizator znajduje się w stanie domyślnym (INITIAL). Do zmiany stanu pracy analizatora służy makro BEGIN, któremu jako parametr podaje się nazwę stanu, do jakiego ma przejść. Należy pamiętać, że analizator sam nigdy nie zmieni stanu analizatora. Program rozpoznający napisy oraz komentarze: %option noyywrap %x STRING COMMENT \" BEGIN(STRING); "/*" BEGIN(COMMENT); <STRING>[a-z]* <STRING>\" printf("zawartosc stringa %s \n", yytext); BEGIN(INITIAL); <COMMENT> [a-z]* printf("w komentarzu %s \n", yytext); "*/" BEGIN(INITIAL); int main() Globalne zmienne YYSTATE oraz YY_START zwracają wartość bieżącego stanu analizatora. Istnieje również możliwość zagnieżdżania odwołań do stanów. W tym celu został stworzony stos, który umożliwia zapamiętywanie kolejnych stanów, przez które przechodzi analizator. Pamięć stosu przydzielana jest dynamicznie. W celu wykorzystania tego stosu należy posługiwać się następującymi funkcjami: Funkcja Działanie yy_push_state(nowy_stan) Przełącza bieżący stan pracy analizatora na nowy i odkłada jego wartość na stosie. yy_pop_state() Pobiera stan znajdujący się na góre stosu i przy 7

yy_top_state() wykorzystaniu funkcji BEGIN przechodzi do pracy w nim. Pobiera stan z góry stosu, bez zmiany zawartości. Zadania: 1. Napisz program, który będzie rozpoznawał zawartość komentarzy jednoliniowych w C (rozpoczynających się od znaków // i kończących wraz z końcem linii. Przetwarzanie wielu plików Niektóre analizatory wymagają współpracy z wieloma plikami. W tym celu został stworzony specjalny mechanizm buforów umożliwiający w prosty sposób przełączanie się między plikami. YY_BUFFER_STATE yy_create_buffer(file* file, int size) YY_BUFFER_STATE yy_new_buffer(file* file, int size) Pobiera zmienną plikową oraz rozmiar pliku i tworzy powiązany z nimi bufor danych. W przypadku gdy nie jest znany potrzebny rozmiar bufora, należy jako drugi parametr wywołania podać YY_BUF_SIZE. YY_BUFFER_STATE jest predefiniowaną strukturą: void yy_switch_to_buffer(yy_buffer_state nowy bufor); Funkcja podmienia plik na wejściu analizatora na ten powiązany z buforem podanym jako parametr. Funkcja ta często jest wykorzystywana w ciele funkcji yywrap(), by kontynuować skanowanie z kolejnego pliku. void yy_delete_buffer(yy_buffer_state bufor); Funkcja zwalnia zasoby związane z buforem. YY_CURRENT_BUFFER Makro zwracające YY_BUFFER_STATE dla bieżącego bufora. Współpraca z YACC Jednym z głównych zastosowań analizatora leksykalnego jest połączenie go wraz z analizatorem składniowym wygenerowanym przez program YACC. Interakcja między tymi programami przebiega w następujący sposób: Analizator składniowy wywołuje metodę yylex(), w wyniku której zostaje do niego przekazany token opisany przez typ oraz wartość (zapisywaną do zmiennej yylval). Nazwy tokenów ustalane są w ciele programu napisanego dla YACC a, jednak wywołanie kompilacji tego programu z opcją -d generuje dodatkowy plik nagłówkowy y.tab.h, w którym znajdują się definicje tokenów. Plik ten należy dołączyć do pliku napisanego w analizatorze leksykalnym. Umożliwia to odwołanie się do tych samych zmiennych. 8

Program do dołączania plików po słowie #include: % #define MAX 100 YY_BUFFER_STATE stos[max]; int nbufor = 0; % %x INCLUDE "include" BEGIN(INCLUDE); [a-za-z]+ ECHO; /*Wypisujemy zawartość pliku*/ [0-9]+ ECHO; <INCLUDE> [\t]* ; /*Omijaj tabulacje*/ [a-z]+"."[a-z]3 stos[nbufor++] = YY_CURRENT_BUFFER; yyin = fopen(yytext, "r"); yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); BEGIN(INITIAL); <<EOF>> if(nbufor == 0) yyterminate(); else yy_delete_buffer(yy_current_buffer); yy_switch_to_buffer(stos[--nbufor]); int yywrap() printf("wykryto koniec pliku\n"); return 1; int main(int argc, char** argv) 9