Wykład 5. Jan Pustelnik

Podobne dokumenty
0.1 Lewostronna rekurencja

Metody Kompilacji Wykład 8 Analiza Syntaktyczna cd. Włodzimierz Bielecki WI ZUT

Parsery LL(1) Teoria kompilacji. Dr inż. Janusz Majewski Katedra Informatyki

Języki formalne i automaty Ćwiczenia 4

Metody Kompilacji Wykład 7 Analiza Syntaktyczna

Analizator syntaktyczny

Analiza metodą zstępującą. Bartosz Bogacki.

Języki formalne i automaty Ćwiczenia 3

Wprowadzenie do analizy składniowej. Bartosz Bogacki.

Uproszczony schemat działania kompilatora

JIP. Analiza składni, gramatyki

Włączenie analizy leksykalnej do analizy składniowej jest nietrudne; po co więc jest wydzielona?

Usuwanie lewostronnej rekursji. Usuwanie lewostronnej faktoryzacji. Wyznaczanie zbioru FIRST. Wyznaczanie zbioru FOLLOW. Konstrukcja parsera LL

Gramatyka operatorowa

Metody Realizacji Języków Programowania

Języki formalne i automaty Ćwiczenia 2

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

10. Translacja sterowana składnią i YACC

Metody Kompilacji Wykład 13

3.4. Przekształcenia gramatyk bezkontekstowych

Uproszczony schemat działania kompilatora

JAO - Wprowadzenie do Gramatyk bezkontekstowych

Automat ze stosem. Języki formalne i automaty. Dr inż. Janusz Majewski Katedra Informatyki

Zadanie analizy leksykalnej

Języki formalne i automaty Ćwiczenia 9

Generator YACC: gramatyki niejednoznaczne

PARADYGMATY I JĘZYKI PROGRAMOWANIA. Analiza leksykalna i syntaktyczna. w- 5

Matematyczne Podstawy Informatyki

Metody Kompilacji Wykład 3

2.2. Gramatyki, wyprowadzenia, hierarchia Chomsky'ego

Języki formalne i automaty Ćwiczenia 1

Gramatyki rekursywne

Wykład 10. Translacja sterowana składnią

Lingwistyka Matematyczna Języki formalne i gramatyki Analiza zdań

Wybrane narzędzia do tworzenia analizatorów leksykalnych i składniowych w C/C++ by Kapitol Team

Podstawy generatora YACC. Bartosz Bogacki.

Generator YACC: gramatyki niejednoznaczne

Efektywna analiza składniowa GBK

ZYKI BEZKONTEKSTOWE (KLASA

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

Zadanie 1. Czy prawdziwa jest następująca implikacja? Jeśli L A jest językiem regularnym, to regularnym językiem jest też. A = (A, Q, q I, F, δ)

Gramatyki, wyprowadzenia, hierarchia Chomsky ego. Gramatyka

Program We Kompilator Wy Źródłowy

Algorytmy i struktury danych. wykład 2

Generatory analizatorów

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

Generator LLgen. Wojciech Complak Generator LLgen - charakterystyka. Generator LLgen -składnia specyfikacji

Przegląd metod error recovery (dla parsingu top-down, przykłady)

Programowanie i techniki algorytmiczne

Języki formalne i automaty Ćwiczenia 8

5. JĘZYKI BEZKONTEKSTOWE (KLASA "2") GRAMATYKI BEZKONTEKSTOWE AUTOMATY ZE STOSEM DETERMINISTYCZNE JĘZYKI BEZKONTEKSTOWE I

Podstawy kompilatorów. Generator LLgen. Wojciech Complak.

Algorytmy i struktury danych. Drzewa: BST, kopce. Letnie Warsztaty Matematyczno-Informatyczne

Układy VLSI Bramki 1.0

Translacja sterowana składnią w generatorze YACC

Gramatyki atrybutywne

Temat 20. Techniki algorytmiczne

Wykład 6. Reguły inferencyjne systemu aksjomatycznego Klasycznego Rachunku Zdań

Języki programowania zasady ich tworzenia

Rekurencja (rekursja)

Wstęp do programowania

Programowanie strukturalne i obiektowe : podręcznik do nauki zawodu technik informatyk / Adam Majczak. Gliwice, cop

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

Paradygmaty programowania

Spis treści WSTĘP CZĘŚĆ I. PASCAL WPROWADZENIE DO PROGRAMOWANIA STRUKTURALNEGO. Rozdział 1. Wybór i instalacja kompilatora języka Pascal

Translacja sterowana składnią w metodzie zstępującej

Notacja RPN. 28 kwietnia wyliczanie i transformacja wyrażeń. Opis został przygotowany przez: Bogdana Kreczmera.

JAO - lematy o pompowaniu dla jezykow bezkontekstowy

2.8. Algorytmy, schematy, programy

Programowanie w języku C++ Grażyna Koba

Teoretyczne podstawy informatyki. Wykład 12: Gramatyki. E. Richter-Was 1

Wykład 11a. Składnia języka Klasycznego Rachunku Predykatów. Języki pierwszego rzędu.

Dla człowieka naturalnym sposobem liczenia jest korzystanie z systemu dziesiętnego, dla komputera natomiast korzystanie z zapisu dwójkowego

Bison - generator analizatorów składniowych

SYLABUS DOTYCZY CYKLU KSZTAŁCENIA Bieżący sylabus w semestrze zimowym roku 2016/17

Bash - wprowadzenie. Bash - wprowadzenie 1/39

Funkcje i instrukcje języka JavaScript

Języki formalne i automaty Ćwiczenia 5

Obiektowa implementacja parsera klasy LL(1)

TRANSLACJA I TRANSLATORY

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

Programowanie w języku Python. Grażyna Koba

Programowanie w Logice Gramatyki metamorficzne. Przemysław Kobylański na podstawie [CM2003] i [SS1994]

11 Probabilistic Context Free Grammars

Wyrażenia regularne.

Odtworzenie wywodu metodą wstępującą (bottom up)

Definiowanie języka przez wyrażenie regularne(wr)

Definicje. Algorytm to:

Wprowadzenie: języki, symbole, alfabety, łańcuchy Języki formalne i automaty. Literatura

Informatyka wprowadzenie do algorytmów (II) dr hab. inż. Mikołaj Morzy

Zapisywanie algorytmów w języku programowania

Algorytmy i. Wykład 5: Drzewa. Dr inż. Paweł Kasprowski

PoniŜej znajdują się pytania z egzaminów zawodowych teoretycznych. Jest to materiał poglądowy.

Odwrotna Notacja Polska

Zapisywanie w wybranej notacji algorytmów z warunkami i iteracyjnych

JĘZYKI FORMALNE I METODY KOMPILACJI

Algorytmy i struktury danych. Wykład 4

Edytor tekstu MS Word 2010 PL. Edytor tekstu MS Word 2010 PL umożliwia wykonywanie działań matematycznych.

12. Rekurencja. UWAGA Trzeba bardzo dokładnie ustalić <warunek>, żeby mieć pewność, że ciąg wywołań się zakończy.

Transkrypt:

Wykład 5 Jan Pustelnik

Konstruowanie parsera Istnieje kilka podstawowych metod konstrukcji parsera bez nawracania Ze względów wydajnościowych parser bez nawracania jest jedynym sensownym rozwiązaniem (prawo Moore'a jest w stanie przyspieszyć znacząco wyłącznie algorytmy O(n))

Konstruowanie c.d. Podstawowymi metodami konstruowania parserów bez nawracania są: top-down (metoda zejścia rekursywnego, oznaczana często LL, szczególnie dobra dla ręcznego budowania parsera dla prostych języków, zasadna zwłaszcza tam, gdzie nie mamy możliwości skorzystania z yacca/bisona, tak np. zbudowany jest freepascal, gdzie source jest w pascalu)

Konstruowanie c.d. bottom-up metoda wstępująca; zwykle używana jest któryś z wariantów ogólnej metody zwanej LR (L czytaj od lewej do prawej, R wywódź prawostronnie czyli od terminali do symbolu głównego): SLR simple LR (LR(0)) LALR lookahead LR (LR(k), k>0, zwykle LR(1)) LR(k) to ogólny symbol, k oznacza tutaj liczbę znaków lookahead, które są rozważane w czasie analizowania jaką ścieżką podążyć; k=0 bierze pod uwagę wyłącznie bieżący symbol, k=1 patrzy jeden znak naprzód

Konstruowanie c.d. Wszystkie wspomniane metody należą do rodziny L czytających tekst od lewej strony, w związku z czym konieczne w ich wypadku jest wykonanie dwóch operacji: usunięcia lewostronnej rekursji i wykonanie lewostronnej faktoryzacji (wyjęcia największego wspólnego czynnika przed nawias)

Konstruowanie c.d. W metodzie zejścia rekursywnego naturalną postacią parsera jest program w postaci ciągu rekurencyjnych procedur, które wywołują same siebie lub inne procedury; schemat wzajemnych zależności odpowiada gramatycje języka

Konstruowanie c.d. W wypadku metod LR (wstępujących) mamy do czynienia z tablicami ACTION i GOTO oraz akcjami SHIFT i REDUCE akcja SHIFT wkłada symbol na stos akcja REDUCE implementuje dokonanie zwinięcia kilku symboli prostszych w jeden symbol bardziej ogólny zgodnie z którąś z reguł gramatyki tablica ACTION decyduje, czy mamy wykonać SHIFT czy REDUCE tablica GOTO mówi do którego stanu mamy się udać

Konstruowanie c.d. tablice ACTION i GOTO konstruowane są zgodnie z określonymi regułami; najbardziej zgrubną regułą jest: preferuj REDUCE względem SHIFT (reguła zdroworozsądkowa nie odkładaj rzeczy na później) niestety reguła ta zawodzi w szczególnych przypadkach, dlatego dla rzeczywistego parsera potrzebne są jeszcze trzy narzędzia: zbiory FIRST zbiory FOLLOW zbiory konfiguracji

Konstruowanie c.d. Dlatego na wstępie powiemy sobie w ogólności o metodach eliminacji rekursji i faktoryzacji a także o zbiorach FIRST, FOLLOW i zbiorach konfiguracji tak, by rzeczy nudne, ale potrzebne zmieściły się w ramach niniejszego wykładu; potem będziemy już tylko mówić o konkretnych metodach analizy składniowej

Rekurencja lewostronna Gramatyka jest lewostronnie rekurencyjna, jeśli ma terminal A taki, że istnieje wyprowadzenie A A dla pewnego napisu. Powoduje to następujący problem: jeżeli analizujemy tekst od lewej strony, wówczas nigdy nie dotrzemy do, ponieważ ugrzęźniemy w A Ceterum censeo rekurencja lewostronna delendam esse

i jej eliminacja Przeanalizujmy przypadek szczególny (nieterminal bezpośrednio rekurencyjny): Zastępujemy produkcję o postaci: A A Następującymi produkcjami: A A' A' A' Zwróćmy uwagę na pojawienie się epsilon-produkcji!

eliminacji c.d. Przeanalizujmy teraz następujący przykład gramatyki: S Aa b A Ac Sd Nieterminal S jest teraz lewostronnie rekurencyjny, ale nie jest bezpośrednio lewostronnie rekurencyjny. Zatem musimy zastosować pewien algorytm, polegający na sukcesywnym rozwinięciu wszystkich produkcji tak, by

eliminacji c.d. dowolna produkcja zawierała po prawej stronie wyłącznie terminale, nieterminale w pozycjach prawostronnie rekurencyjnych lub nieterminal znajdujący się po lewej stronie w pozycji lewostronnie rekurencyjnej, a następnie wykonaniu eliminacji bezpośredniej lewostronnej rekurencji z wszystkich produkcji

eliminacji c.d. Warunkiem powodzenia algorytmu eliminacji jest brak pętli oraz brak epsilon-produkcji w startowej gramatyce; efektem ubocznym jest stworzenie epsilon produkcji. Zwykle algorytm ten omijamy po prostu pisząc gramatykę w taki sposób, by nie było lewostronnej rekurencji

Faktoryzacja lewostronna Weźmy następujące dwie produkcje: instr if wyr then instr else instr if wyr then instr Jeśli na wejściu widzimy symbol if, wówczas nie wiemy, którą produkcję wybrać, należy wyciągnąć pierwszą część przed nawias, otrzymując następujące produkcje: instr if wyr then instr część-else część-else else instr

faktoryzacja c.d. Standardowo postępujemy pisząc gramatykę tak, by od razu uwzględnić lewostronną faktoryzację Należy zauważyć, że algorytm eliminacji lewostronnej faktoryzacji może zostać łatwo zintegrowany z algorytmem tworzenia analizatora składniowego typu LR

Zbiory FIRST i FOLLOW Zbiory FIRST i FOLLOW budowane są w trakcie konstrukcji algorytmu analizatora składniowego metodą LR Rozumienie ich konstrukcji jest konieczne dla analizy błędów w gramatyce raportowanych przez generator analizatorów składniowych yacc/bison

FIRST Zbiór FIRST dla dowolnego ciągu symboli z gramatyki X jest zbiorem terminali, od których zaczynają się ciągi wyprowadzalne z X; jeżeli z X można wyprowadzić epsilon, to epsilon jest także w FIRST(X); należy zauważyć, że wszystkie zbiory FIRST są konstruowane jednocześnie dla całej gramatyki, dzięki czemu czas obliczania ich jest proporcjonalny do długości najdłuższego wyprowadzenia

FIRST c.d. FIRST ALGORYTM: 1. Jeśli X jest terminalem, to FIRST(X) jest równe {X} 2. Jeśli mamy epsilon produkcję dla X, to dodajemy epsilon do FIRST(X) 3. Jeśli X jest nieterminalem, wówczas dla wszystkich produkcji postaci: X Y 1 Y 2 Y 3... Należy wykonać następujący algorytm: a) dodaj do FIRST(X) zbiór FIRST(Y 1 ) b) jeśli FIRST(Y 1 ) zawiera epsilon, wówczas dodaj do FIRST(X) zbiór FIRST(Y 2 ) c) jeśli FIRST(Y 2 ) zawiera epsilon... itd.

FIRST c.d. d) jeśli wszystkie FIRST(Y j) zawierają epsilon, wówczas FIRST(X) też będzie zawierał epsilon

FOLLOW Zbiory FOLLOW obliczamy zgodnie z następującym algorytmem: 1) dla symbolu startowego S w FOLLOW(S) umieszczamy $ 2) dla każdej produkcji A B, gdy FIRST( ) nie zawiera, wszystkie symbole z FIRST( ) umieszczamy w FOLLOW(B) 3) jeżeli FIRST( ) zawiera, lub mamy do czynienia z produkcją A B, wówczas do FOLLOW(B) dodajemy FOLLOW(A)

Prosty przykład analizatora LL Teraz podamy prosty przykład analizatora LL, żeby już dalej nie zajmować się tym tematem; dla nas ważne są analizatory LR, które są generowane automatycznie przez odpowiedni generator analizatorów składniowych

Prosty przykład c.d. Analizatory LL zasadniczo nadają się wyłącznie do generowania ręcznego i jako takie sprawdzają się w wypadkach prostych języków (kalkulator) lub gdy do dyspozycji nie mamy odpowiednich narzędzi (Pascal), a dodatkowo zależy nam na małym kodzie wykonywalnym (tablice LR potrafią być duże, dla ośmiobitowców LL było jedynym wyjściem)