Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

L L G E N Generator analizatorów składniowych. GENERATOR L LGEN Zadaniem generatora LLgen jest wygenerowanie analizatora składniowego, inaczej parsera.

Podobne prezentacje


Prezentacja na temat: "L L G E N Generator analizatorów składniowych. GENERATOR L LGEN Zadaniem generatora LLgen jest wygenerowanie analizatora składniowego, inaczej parsera."— Zapis prezentacji:

1 L L G E N Generator analizatorów składniowych

2 GENERATOR L LGEN Zadaniem generatora LLgen jest wygenerowanie analizatora składniowego, inaczej parsera (w języku C) metodą zejść rekurencyjnych, bez nawrotów; Kod źródłowy generowany jest przez LLgena w oparciu o plik zawierający specyfikację; W specyfikacji można korzystać z rozszerzonych specyfikacji gramatyk LL(1). Ponieważ LLgen zawiera wbudowane mechanizmy statycznego i dynamicznego rozstrzygania konfliktów, pozwala on na korzystanie z gramatyk niejednoznacznych; 2

3 GENERATOR LLGEN Schemat organizacji działania LLgena: scan.l scan.c scane.exe plik.txt WYNIK G C C L E X 3 gram.g LLgen gram.c Lpars.c Lpars.h

4 GENERATOR LLGEN flex –l scan.l (użycie generatora LEX) flex –l scan.l (użycie generatora LEX)lex.yy.c LLgen gram.g (uzycie generatora LLgen dla pliku specyfikacji gram.g) Lpars.c i Lparse.h gcc lex.yy.c Lpars.c gram.c (kompilacja gcc lex.yy.c Lpars.c gram.c (kompilacja C++) C++)./a.out < plik.in (analiza pliku) 4 4

5 GENERATOR LLGEN Generator LLgen domyślnie korzysta z zewnętrznego analizatora leksykalnego, (wygenerowanego za pomocą LEXa). W tym celu wywoływana jest funkcja yylex(); Plik Lpars.h, który powstaje podczas pracy generatora LLgen, zawiera definicje przypisujące stałe liczbowe nazwom zadeklarowanych token-ów; 5

6 GNENRATOR LLGEN Sposoby na wykorzystanie innego analizatora są następujące: Sposoby na wykorzystanie innego analizatora są następujące: umieścić implementację skanera bezpośrednio w specyfikacji gramatyki (w bloku { } lub w zewnętrznym pliku; umieścić implementację skanera bezpośrednio w specyfikacji gramatyki (w bloku { } lub w zewnętrznym pliku; W specyfikacji wskazać nazwę funkcji, którą Llgen ma wywołać; W specyfikacji wskazać nazwę funkcji, którą Llgen ma wywołać; %lexical nazwa_funkcji; w razie potrzeby włączyć do analizatora leksykalnego plik Lpars.h; w razie potrzeby włączyć do analizatora leksykalnego plik Lpars.h; 6

7 GENERATOR LLGEN LLgen jest narzędziem wierszowym, do którego plik specyfikacji przygotowujemy w zwykłym pliku tekstowym, czasem w kilku plikach; Każdy wygenerowany kod źródłowy zawiera produkcje, dyrektywy generatora LLgen i deklaracje i kod w języku C Każdy wygenerowany kod źródłowy zawiera produkcje, dyrektywy generatora LLgen i deklaracje i kod w języku C 7

8 TWORZENIE SPECYFIKACJI Każdy produkcja ze specyfikacji dla programu LLgen składa się z: nieterminalu, znaku : i prawej strony produkcji. Zakończona jest średnikiem; Alternatywne prawe strony produkcji rozdzielane są znakiem |; Prawa strona produkcji może składać się z terminali, nieterminali i akcji semantycznych; nieterminal : prawa strona produkcji ; 8

9 TWORZENIE SPECYFIKACJI Reguły tworzenia specyfikacji: Reguły tworzenia specyfikacji: białe spacje są ignorowane, jednak nie mogą występować w obrębie nazwy; białe spacje są ignorowane, jednak nie mogą występować w obrębie nazwy; Komentarze wprowadzamy po znaku /* a zamykamy */; Komentarze wprowadzamy po znaku /* a zamykamy */; Komentarze nie mogą być zagnieżdżone; Komentarze nie mogą być zagnieżdżone; Komentarze mogą wystąpić w każdym miejscu, gdzie dozwolone jest wystąpienie nazwy; Komentarze mogą wystąpić w każdym miejscu, gdzie dozwolone jest wystąpienie nazwy; 9

10 TWORZENIE SPECYFIKACJI Reguły tworzenia specyfikacji c.d. : Nazwy symboli terminalnych i nieterminalnych mogą być dowolnej długości. Maja one składnię taką, jak identyfikatory języka C; Nazwy symboli terminalnych i nieterminalnych mogą być dowolnej długości. Maja one składnię taką, jak identyfikatory języka C; Nazwy symboli nie mogą kolidować ze słowami kluczowymi języka C; Nazwy symboli nie mogą kolidować ze słowami kluczowymi języka C; Wielkość liter w nazwie jest rozróżnialna; Wielkość liter w nazwie jest rozróżnialna; 10

11 TWORZENIE SPECYFIKACJI Reguły tworzenia specyfikacji c.d. : Nazwy symboli mogą być dowolnej długości, jednak w LLgen znaczących jest 50 pierwszych znaków; Nazwy symboli mogą być dowolnej długości, jednak w LLgen znaczących jest 50 pierwszych znaków; Wszystkie nazwy generowane i wykorzystywane przez LLgen rozpoczynają się prefiksem LL; Wszystkie nazwy generowane i wykorzystywane przez LLgen rozpoczynają się prefiksem LL; 11

12 DEKLARACJA TERMINALI Terminale, które nie są literałami deklarujemy: %token ken; Jeśli mamy kilka terminali do deklaracji możemy to zrobić tak: %token nazwa1, nazwa2, nazwa3; Każde użycie terminala musi być poprzedzone jego deklaracją; 12

13 DEKLRACJE TERMINALI Terminale, które są literałami są ujmowane w apostrofy; LLgen rozpoznaje także (podobnie jak C) zestaw literałów specjalnych, tzn.: nowa linia \n nowa linia \n tabulator \t tabulator \t powrót karetki \r powrót karetki \r apostrof \ apostrof \ wycofanie znaku \b wycofanie znaku \b odwrotny ukośnik \\ odwrotny ukośnik \\ liczba oktalna \xxx liczba oktalna \xxx 13

14 DEKLRACJE TERMINALI ZAPAMIETAJ!!! Napotkana w pliku specyfikacji nazwa, która nie była zadeklarowana jako token, będzie traktowana przez LLgen jako symbol nieterminalny; 14

15 DEKLRACJE TERMINALI Nieterminal jest implementowany jako funkcja języka C; W LLgenie możemy korzystać ze zmiennych lokalnych funkcji. Generator pozwala je deklarować, w nawiasach klamrowych, jedynie po lewej stronie produkcji za symbolem nieterminalnym, np.: A {int zmienna;} : S ken T ; 15

16 DEKLRACJE TERMINALI Przez akcję semantyczną rozumiemy dowolną pojedynczą instrukcję (grupę instrukcji) napisaną w języku C, które są ujęte w nawiasy klamrowe; W LLgenie akcje semantyczne możemy wstawić jedynie po prawej stronie produkcji, np.: A {int zmienna} : S ken {licznik=1;} T ; 16

17 NIETERMINAL STARTOWY Analizatory generowane przez LLgen mogą posiadać wiele nieterminali startowych; Deklaracja nieterminalu startowego inaczej aksjomatu wygląda następująco: %start funkcja, nazwa_nieterminala; %start funkcja, nazwa_nieterminala;np.: %start parse, S; 17

18 KOMPILACJA Polecenie, które służy do uruchomienia generatora to LLgen. Polecenie to jest wywoływane dla pilku specyfikacji (rozszerzenie g), np.: LLgen gram.g Generator Llgen na wyjściu produkuje trzy pliki: gram.c – plik w C zwierający implementację gram.c – plik w C zwierający implementację parsera; parsera; Lpars.h – plik zawierający interfejs analizatora Lpars.h – plik zawierający interfejs analizatora leksykalnego; leksykalnego; Lpars.c – szkielet parsera i tablica sterująca; Lpars.c – szkielet parsera i tablica sterująca; 18

19 OPCJA -V Czasem warto jest przy uruchamianiu i testowaniu parsera korzystać z opcji –v; Czasem warto jest przy uruchamianiu i testowaniu parsera korzystać z opcji –v; Dzięki opcji –v wygenerowany zostanie plik LL.output, który będzie zwierał informacje o nierozwiązanych konfliktach, które pojawiły się w gramatyce; 19

20 ROZSZERZENIE SKŁADNI GRAMATRYK Rozszerzenia standardowej składni gramatyk bezkontekstowych: * (*liczba) – domknięcie zwrotne * (*liczba) – domknięcie zwrotne + (+liczba) – domknięcie dodatnie ; + (+liczba) – domknięcie dodatnie ; ? – operator opcjonalności; ? – operator opcjonalności; [...] – możliwość grupowania symboli; [...] – możliwość grupowania symboli; 20

21 Przykład Niech ={a,b}. Rozważmy język regularny L=L(b*a). Wówczas: 21 S : B A ; B : | b B ; A : a ; S : B A ; B : b * ; A : a ;

22 Przykład Niech ={a,b}. Rozważmy język L={b, ab, aab, aaab}. Wówczas: 22 S : A B ; A : | a C ; C : | a ; B : b ; S : A B ; A : a *3 ; B : b ;

23 Przykład Niech ={a,b}. Rozważmy język L={ab, aab, aaab}. Wówczas: 23 S : A B ; A : a C ; C : | a ; B : b ; S : A B ; A : a +3 ; B : b ;

24 Przykład Niech ={a,b}. Rozważmy język L={b, ab}. Wówczas: 24 S : A B ; A : | a ; B : b ; S : A B ; A : a ? ; B : b ;

25 Przykład Niech ={a,b}. Rozważmy język L={A * : |A|=2}. Wówczas: 25 S : a B | b B ; B : a | b ; S : [ a | b ] +2 ;

26 PORÓWNANIE Rozważmy gramatykę, która nie jest gramatyką LL(1). Porównajmy pracochłonność procedury dostosowania gramatyki a bezpośrednią implemantacją gramatyki w generatorze LLgen; Niech =[a,b}. Napiszmy program akceptujący język bezkontekstowy L={A * : A=a n b n ; n }; 26

27 PORÓWNANIE { int ilosc_a, ilosc_b; } %start parse, S; S : A B { if (ilosc_a= = ilosc_b) puts(OK.); else puts(Blad); } else puts(Blad); } ; 27

28 PORÓWNANIE Usuwamy lewostronną rekurencję; 28 A : a { ilosc_a=1; } | A a { ilosc_a++; } ; B : b { ilosc_b=1; } | B b { ilosc_b++; } ; A : a { ilosc_a=1; } | a A { ilosc_a++; } ; B : b { ilosc_b=1; } | b B { ilosc_b++; } ;

29 PORÓWNANIE A : a C { ilosc_a++; } ; C : { ilosc_a=0; } | a C { ilosc_a++; } ; B : b D { ilosc_b++; } ; D : { ilosc_b=0; } | b D { ilosc_b++; } ; 29

30 PORÓWNANIE S : {ilosc_a=ilosc_b=0} A B { if (ilosc_a= = ilosc_b) puts(OK.); else puts(Blad); } else puts(Blad); } ; A : [ a {ilosc_a++} ] + ; B : [ b {ilosc_b++} ] + ; 30

31 LLSYMB LLsymb jest globalną zmienną całkowitą, która może przyjmować różne wartości. To jaka wartość będzie przyjęta, zależy od położenia głowicy czytającej po prawej stronie produkcji: Możliwe wartości: Jeśli przeczytany został token, to LLsymb przechowuje token; Jeśli przeczytany został token, to LLsymb przechowuje token; Po grupowaniu i alternatywie w zmiennej znajduje się podglądany token; Po grupowaniu i alternatywie w zmiennej znajduje się podglądany token; 31

32 TWORZENIE SPECYFIKACJI W pliku ze specyfikacją do generatora LLgen obowiązkowo powinna znaleźć się implementacja funkcji main; W pliku ze specyfikacją do generatora LLgen obowiązkowo powinna znaleźć się implementacja funkcji main; %start parse, S ; int main(){ parse(); return 0; } 32

33 TWORZENIE SPECYFIKACJI W pliku ze specyfikacją do generatora LLgen powinna także znaleźć się implementacja funkcji LLmessage; Funkcja ta jest automatycznie wywoływana przez parser, gdy wystąpi bład składniowy; void LLmessage ( int tk ); Nie zwraca żadnej wartości Ma jeden parametr typu całkowitego 33

34 TWORZENIE SPECYFIKACJI Zmienna tk przyjmuje następujące wartości: gdy oczekiwany był token tk – tk > 0; gdy oczekiwany był token tk – tk > 0; gdy wczytany został nieoczekiwany token i został on usunięty – tk = 0; gdy wczytany został nieoczekiwany token i został on usunięty – tk = 0; gdy nie został napotkany oczekiwany koniec pliku i pozostałe wejście będzie pominięte – tk = - 1; gdy nie został napotkany oczekiwany koniec pliku i pozostałe wejście będzie pominięte – tk = - 1; 34

35 Przykład Działanie generatora LLgen najlepiej zobaczyć na przykładzie. Na wejściu znajduje się ciąg słów złożonych z alfabetu naturalnego, słowa kończą się znakiem dwukropka i są rozdzielane przecinkiem. Dany na wejście ciąg zawiera co najmniej jedno słowo

36 KONFLIKTY W trakcie pracy generatora składniowego może dojść do konfliktu polegającego na: W trakcie pracy generatora składniowego może dojść do konfliktu polegającego na: nie jesteśmy w stanie określić, którą z prawych stron należy rozwijać – konflikt alternatyw; nie jesteśmy w stanie określić, którą z prawych stron należy rozwijać – konflikt alternatyw; Konstrukcja która jest aktualnie przetwarzana zawiera domkniecie i trudno określić, czy wejście jest jej dalszym ciągiem, czy też rozpoczyna inną konstrukcję – konflikt powtórzeń; Konstrukcja która jest aktualnie przetwarzana zawiera domkniecie i trudno określić, czy wejście jest jej dalszym ciągiem, czy też rozpoczyna inną konstrukcję – konflikt powtórzeń; 36

37 KONFLIKTY Konflikt alternatyw można rozstrzygnąć na dwa sposoby: dynamiczne rozstrzyganie konfliktu alternatywy: dynamiczne rozstrzyganie konfliktu alternatywy: %if (warunek) statyczne rozstrzyganie konfliktu alternatyw: statyczne rozstrzyganie konfliktu alternatyw: %prefer %if(1) %aviod %if(0) 37

38 Przykład Rozważmy zadanie badania parzystości liczby binarnej; Rozważmy zadanie badania parzystości liczby binarnej; Analizator leksykalny rozpoznaje i zwraca liczby binarne; % [01] { return yytext[0]; } 38

39 Przykład { int wczytcyfra; } %start parse, S; S : 0 { wczytcyfra = 0; } R | 1 { wczytcyfra = 1; } R | 1 { wczytcyfra = 1; } R; R : %if (wczytcyfra ==0 ) {puts(parzysta);} | {puts(nieparzysta);} | {puts(nieparzysta);} | S | S; 39

40 ROZWIĄZYWANIE KONFLIKTÓW Przykład użycia mechanizmu statycznego rozwiązywania konfliktów alternatyw jest problemem tzw. wiszącego else; Przykład użycia mechanizmu statycznego rozwiązywania konfliktów alternatyw jest problemem tzw. wiszącego else; Problem ten omówimy szczegółowo na wykładzie poświęconym generatorowi YACC; 40

41 ROZWIĄZYWANIE KONFLIKTÓW Konflikt powtórzeń jest rozstrzygany przy pomocy słowa kluczowego %while; %while ( warunek ) W ewaluacji warunku bardzo przydatne może być makro języka C, które jest generowane przez Llgen na podstawie słowa kluczowego %first; W ewaluacji warunku bardzo przydatne może być makro języka C, które jest generowane przez Llgen na podstawie słowa kluczowego %first; %first fmac, nonterm ; 41

42 KONIEC KONIEC WYKŁADU SZÓSTEGO


Pobierz ppt "L L G E N Generator analizatorów składniowych. GENERATOR L LGEN Zadaniem generatora LLgen jest wygenerowanie analizatora składniowego, inaczej parsera."

Podobne prezentacje


Reklamy Google