1 / 58

Wykład 9

Wykład 9. Metoda pierwszeństwa operatorów. Metoda pierwszeństwa operatorów. Dla ważnej klasy gramatyk (gramatyka operatorowa) możemy łatwo ręcznie budować wydajne analizatory redukujące. Cecha charakterystyczną tej ważnej, lecz wąskiej grupy gramatyk jest to, że:

sasson
Download Presentation

Wykład 9

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Wykład 9 Metoda pierwszeństwa operatorów

  2. Metoda pierwszeństwa operatorów • Dla ważnej klasy gramatyk (gramatyka operatorowa) możemy łatwo ręcznie budować wydajne analizatory redukujące. • Cecha charakterystyczną tej ważnej, lecz wąskiej grupy gramatyk jest to, że: • prawa strona jakiejkolwiek produkcji nie jest Ʌ, • nie zawiera dwóch sąsiadujących nieterminali

  3. Gramatyka operatorowa • Gramatyka E->EAE | (E) | -E | id, A-> + | - | * | / | ↑ nie jest gramatyką operatorową. • Gramatyka E->E+E | E-E | E*E | E/E | E↑E | (E) | -E | id Jest gramatyką operatorową.

  4. Technika pierwszeństwa operatorów • Metoda pierwszeństwa operatorów została najpierw opisana jako manipulacje na symbolach, bez żadnych odwołań do ukrytej gramatyki. • Gdy skończymy budować analizator dla gramatyki pisany metodą pierwszeństwa operatorów, możemy ignorować gramatykę, używając nieterminali na stosie tylko do zajmowania miejsca dla atrybutów związanych z nieterminalami.

  5. Technika pierwszeństwa operatorów Wady metody pierwszeństwa operatorów: • Niektóre symbole są trudne do obsłużenia. , np. znak minus (-), który ma dwa różne priorytety w zależności od tego czy ma jeden czy dwa argumenty; • Związek pomiędzy analizowaną gramatyką a analizatorem napisanym metoda pierwszeństwa jest słaby; • Metodą pierwszeństwa operatorów można analizować tylko małą klasę gramatyk.

  6. Metoda pierwszeństwa operatorów W metodzie pierwszeństwa operatorów między pewnymi parami terminali definiujemy trzy rozłączne relacje priorytetów: <· , = , ·> Kierują one wyborem uchwytów i mają następujące znaczenie: • a<·b - a ma mniejszy priorytet niż b; • a=b – a ma taki sam priorytet jak b; • a·>b – a ma większy priorytet niż b.

  7. Metoda pierwszeństwa operatorów Uwaga. Podobieństwo do relacji arytmetycznych jest iluzoryczne. Relacje priorytetów mają całkiem inne własności. Przykład: • dla tego samego języka może zachodzić a<·b i a·>b. • dla pewnej pary terminali a i b może nie zachodzić ani a<·b ani a=b ani a·>b .

  8. Metoda pierwszeństwa operatorów Istnieją dwie metody sprawdzania, jakie relacje priorytetów zachodzą miedzy parami terminali: • Metoda intuicyjna – opiera się na tradycyjnych pojęciach łączności i priorytetów operatorów; • Metoda wyboru relacji priorytetów.

  9. Metoda intuicyjna Metoda intuicyjna – opiera się na tradycyjnych pojęciach łączności i priorytetów operatorów. Przykład: Jeśli * ma wyższy priorytet niż +, to ustalamy +<·* oraz *·>+. Podejście takie usuwa niejednoznaczność z gramatyki E->E+E | E-E | E*E | E/E | E↑E | (E) | -E | id oraz pozwala nam napisać dla niej analizator metodą pierwszeństwa operatorów (pomimo iż jednoargumentowy minus stwarza problemy).

  10. Metoda wyboru relacji priorytetów Metoda wyboru relacji priorytetów polega na zbudowaniu jednoznacznej gramatyki dla języka, takiej, że drzewa wyprowadzenia budowane przy jej użyciu będą oddawać właściwą łączność i priorytety operatorów. Przykładowo dla często spotykanego źródła niejednoznaczności „wiszącego else” modelem może być gramatyka:......

  11. Metoda wyboru relacji priorytetów instr -> dopas_instr | niedopas_instr dopas_instr -> if wyr then dopas_instr else dopas_instr | inna niedopas_instr -> if wyr then instr | if wyr then dopas_instr else niedopas_instr

  12. Metoda wyboru relacji priorytetów Gdy dysponujemy już jednoznaczną gramatyką, korzystamy z mechanicznego sposobu, aby używając jej, skonstruować relacje priorytetów. Relacje te mogą nie być rozłączne i mogą pozwalać na analizowanie innych języków niż generowane przez początkową gramatykę, ale przy standardowych wyrażeniach arytmetycznych w praktyce nie spotyka się wielu problemów.

  13. Relacje priorytetów operatorów Zadaniem relacji priorytetów jest oddzielenie uchwytów prawostronnych form zdanio-wych, z <· oznaczającym lewy kraniec, = występującym w środku uchwytu i ·> na prawym krańcu.

  14. Relacje priorytetów operatorów Przyjmijmy, że mamy prawostronną formę zdaniową gramatyki operatorowej. Możemy prawostronną formę zdaniową zapisać jako : β0 a1β1 a2β2 ... anβn gdzie każde z βi jest albo Ɛ (pustym ciągiem) albo nieterminalem, zaś ai jest pojedynczym terminalnym, i=1,...,n. Załóżmy, że między ai i ai+1 zachodzi dokladnie jedna z relacji: <· , = lub ·> .

  15. Relacje priorytetów operatorów Do ustalenia końca ciągu będziemy używali symbolu $ oraz ustalimy, że dla wszystkich symboli terminalnych $ <· b oraz b ·> $. Przypuśćmy teraz, że usuwamy nieterminale z ciągu i umieszczamy symbol właściwej relacji <·= lub ·>. Symbol ten umieszczamy między każdą parą terminali i między krańcowymi terminalami i znakami $ oznaczającymi krańce ciągu. Przykładowo dla ciągu: id + id * id Otrzymujemy: $ <·id·> + <·id·> * <·id·> $.

  16. Relacje priorytetów operatorów Ustalamy relację priorytetów operatorów

  17. Relacje priorytetów operatorów Metoda znalezienia uchwytu. - Przeglądamy ciąg od lewej strony aż do napotkania pierwszego ·>. $ <·id·> + <·id·> * <·id·> $. - Następnie przechodzimy do tyłu (w prawo) po kolejnych =, aż napotkamy <· . $ <·id·> + <·id·> * <·id·> $. - Uchwyt składa się ze wszystkich symboli leżących między pierwszym ·> z prawej strony a <· z lewej strony, włączając wszystkie zawarte lub otaczające nieterminale. UWAGA: Dołączenie otaczających nieterminali jest konieczne, aby nie spowodować sąsiadowania dwóch nieterminali w prawostronnej formie zdaniowej.

  18. Relacje priorytetów operatorów Zatem uchwytem jest w tym przypadku id. Przypomnijmy gramatykę: E->E+E | E-E | E*E | E/E | E↑E | (E) | -E | id Po dokonaniu redukcji względem produkcji E->id dostajemy prawostronną formę zdaniową E + id * id . Następnie po eliminacji w ciągu nieterminali i zastosowaniu symbolu właściwej relacji dostajemy $ <· + <·id·> * <·id·> $. Po analogicznym zredukowaniu dwóch pozostałych id do E otrzymamy prawostronną formę zdaniową E + E* E Następnie po eliminacji w ciągu nieterminali i zastosowaniu symbolu właściwej relacji dostajemy $ <· + <· * ·> $. Oznacza to, że lewy koniec uchwytu jest między + oraz *, zaś prawy między * a $. Takie relacje priorytetów wskazują, że w prawostronnej formie zdaniowej uchwytem jest E* E .

  19. Relacje priorytetów operatorów Aby uniknąć sytuacji, gdy w każdym kroku aby znaleźć uchwyt przeglądamy całą prawostronną formę zdaniową, używamy stosu do przechowywania już obejrzanych symboli wejściowych i korzystamy z relacji priorytetów do sterowania działaniem analizatora redukującego. Jeśli między termnalem na wierzchołku stosu a kolejnym symbolem z wyjścia zachodzi <· lub = , analizator wykonuje przesunięcie (oznacza to że nie znalazł jeszcze uchwytu); Jeżeli zachodzi ·> , to wykonywana jest redukcja (w tym momencie analizator znalazł prawy koniec uchwytu, a relacji priorytetów można użyć do znalezienia na stosie lewego krańca). Jeśli między parą terminali nie zachodzi żadna z relacji (idid), to wykryto błąd składniowy i należy wywołać procedurę obsługi błędu.

  20. Algorytm analizy metodą pierwszeństwa operatorów Wejście: Tekst wejściowy ω i tablica relacji priorytetów. Wyjście: Jeśli ω jest poprawny – szkieletowe drzewo wyprowadzenia, z zajmującym miejsce nieterminalem E etykietującym wszystkie węzły wewnętrzne, w prze-ciwnym wypadku informacja o błędzie;

  21. Algorytm analizy metodą pierwszeństwa operatorów Metoda: Początkowo stos zawiera $, a bufor ω$. • Zainicjuj ip tak, aby wskazywał pierwszy symbol ω$. • Repeat forever • if $ jest na wierzcholku stosu oraz ip wskazuje $ then • return else begin • niech a będzie symbolem z wierzcholku stosu a b – symbolem wskazanym przez ip; • if a<·b lub a=b then begin • odloz b na stos; • przesun ip do nastepnego symbolu wejsciowego; end; • else if a·>b then /*redukcja*/ • repeat • zdejmi element ze stosu • until szczytowy element ze stosu jest w relacji <· z poprzednio zdjetym terminalem • else blad(); end

  22. Wyznaczanie relacji priorytetów z łączności i priorytetów operatorów 1) Jeśli operator θ1 ma wyższy priorytet niżθ2 , przyjmujemy, że θ1 ·>θ2 oraz θ2 <· θ1 Jeśli przykładowo, priorytet * jest większy niż +, przyjmujemy, że *·>+oraz +<· * (relacje te gwarantują, że, w wyrażeniach E+E*E+E, centralne E*E jest uchwytem, który będzie zredukowany jako pierwszy); 2) Jeśli θ1 iθ2 są operatorami o tym samym priorytecie (lub jest to jeden operator) przyjmijmy, że: θ1 ·>θ2 oraz θ2 ·>θ1 – jeśli te operatory są łączne lewostronnnie, θ1 <· θ2 oraz θ2 <· θ1 – jeśli te operatory są łączne lewostronnnie. Jeśli przykładowo, + i – są lewostronnie łączne, to przyjmijmy: + ·> + , + ·> - , - ·> - , - ·> + Jeśli natomiast operator ↑ jest łączny prawostronnie, to przyjmujemy ↑ <· ↑ (relacje te dają pewność, że w E-E+E wybranym uchwytem będzie E-E, a w E ↑ E ↑ E wybrane zostanie drugie E ↑ E .

  23. Wyznaczanie relacji priorytetów z łączności i priorytetów operatorów 3) Przyjmijmy, że θ <· id , id ·> θ ,θ <· ( , (·> θ , θ ·> ) , θ ·> $ <·θ dla wszystkich operatorów θ. Ponad to niech ( = ) $<· ( $ <· id ( <· ( id ·> $ ) <· id ( <· id id ·> ) )·> ) (reguły te zapewniają zredukowanie id i () do E. Ponadto, $ będący znakiem zarówno lewego, jaki i prawego krańca, powoduje - tak długo jak to możliwe – wyszukiwanie kolejnych uchwytów $.

  24. Relacje priorytetów operatorów Przyjmujemy, że: • Operator ↑ ma najwyższy priorytet i jest prawostronnie łączny; • * oraz / mają drugi w kolejności priorytet i są lewostronnie łączne; • + oraz - mają najniższy priorytet i są lewostronnie łączne.

  25. Obsługa operatorów jednoargumentowych Mamy dwa rodzaje operatorów jednoargumento-wych: • ¬ (negacja logiczna) - nie jest on jednocześnie operatorem dwuargumentowym; • Znak - , który jest zarówno prefiksowym operatorem jednoargumentowym (np. -6), jaki i infiksowanym operatorem dwuargumentowym.

  26. Obsługa operatorów jednoargumentowych ¬ (negacja logiczna) – operator ten możemy dołączyć do schematu tworzenia relacji priorytetów operatorów. A. Zakładając, że ¬ jest prefiksowym operatorem jedno-argumentowym, przyjmujemy θ <·¬ dla wszystkich operatorów θ, zarówno jedno-, jak i dwuargumentowych; Ponadto, jeśli ¬ ma wyższy priorytet niż θ, to przyjmujemy, że: ¬ ·> θ a jeśli nie, to przyjmujemy: ¬<·θ B. Reguły dla postfiksowych operatorów jednoargumentowych są analogiczne.

  27. Obsługa operatorów jednoargumentowych ¬ (negacja logiczna) – przykład Jeśli ¬ ma wyższy priorytet niż &, a & jest lewostronnie łączny, to według tych reguł formę: E&¬ E&E odczytalibyśmy jako: ( E & (¬ E) ) & E

  28. Obsługa operatorów jednoargumentowych Znak - jest zarówno prefiksowym operatorem jednoargumentowym (np. -6), jaki i infiksowanym operatorem dwuargumentowym. Nawet jeśli jedno- i dwuargumentowemu minusowi nadamy ten sam priorytet, relacje opisane wyżej nie pozwolą poprawnie przeanalizować wejścia, takiego jak np. id*-id. Najlepszym podejściem jest w takim przypadku zmiana analizatora leksykalnegotak aby rozróżniał minus jednoargumentowy od dwuargumentowego i zwracał dla nich różne symbole. Niestety analizator leksykalny nie może podglądać symboli w celu ich odróżnienia (musi on pamiętać poprzedni symbol). Można to zrobić na przykład: minus jest jednoargumentowy, jeśli poprzednim symbolem był operator, lewy nawias, przecinek, albo symbol przypisania.

  29. Funkcje priorytetów Kompilatory używające analizatorów działających metoda pierwszeństwa operatorów nie muszą przechowywać tablic opisujących relację priorytetów. W większości przypadków tablice te można zakodować przy użyciu dwóch funkcji priorytetów f: T->Z i g: T->Z (odwzorowujące symbole terminalne w liczby całkowite). Można więc odczytać relację priorytetów a i b, porównując ze sobą funkcje. Próbujemy dobrać f i g tak aby dla symboli a i b zachodziło: f(a) < f(b), gdy a<·b f(a) = f(b), gdy a=b f(a) > f(b), gdy a·>b

  30. Funkcje priorytetów UWAGI. Przy wykorzystaniu funkcji priorytetów tracimy informacje o błędach zapisane w tablicy priorytetów (id i id były nieporównywalne), gdyż niezależnie od wartości f(a) i f(b) – jeden z powyższych warunków zawsze będzie zachodzić. Zazwyczaj utrata możliwości wykrywania błędów nie jest na tyle ważna, żeby rezygnować z użycia funkcji priorytetów jeśli tylko jest to możliwe ( błędy mogą być wykrywane, gdy chcemy wykonać redukcję, a nie możemy znaleźć uchwytu). Nie wszystkie tablice dla relacji priorytetów mają odpowiadające im funkcje priorytetów, ale w praktyce zazwyczaj takie funkcje daje się znaleźć.

  31. Tablica priorytetów ..

  32. Tablica priorytetów Mamy, na przykład, * <· id oraz f(*)=4 < 5=g(id) Zauważmy, że chociażf(id) >g(id), sugeruje, żeid ·> id, to id nie jest w żadnej relacji z id.

  33. Algorytm wyznaczania funkcji priorytetów Wejście: Tablica priorytetów operatorów. Wyjście: Funkcje priorytetów reprezentujące wejściową tablicę albo informacja, że one nie istnieją. Metoda:

  34. Algorytm wyznaczania funkcji priorytetów KROK I. Dla każdego a, będącego terminalem lub symbolem $, stwórz symbole fa i ga. KROK II. Podziel uzyskane symbole na tak wiele grup, jak jest to możliwe i w taki sposób, aby fa i fb były w tej samej grupie, jeśli a=b. (Zauważmy, że możemy umieścić symbole w tej samej grupie, nawet jeśli nie są one w relacji =. Istotnie, jeśli na przykład a=b oraz c=b, to fa i fc będą w tej samej grupie, co gb. Jeśli dodatkowo c=d to fa i gd będą w tej samej grupie, mimo, że wcale nie musi zachodzić a=d).

  35. Algorytm wyznaczania funkcji priorytetów KROK III. Stwórz graf skierowany, którego wierzchołkami są grupy znalezione w kroku II. Dla dowolnego a i b, - jeśli a <· b, dodaj do grafu krawędź z grupy, w której jest gb, do grupy z fa. - jeśli a ·> b, dodaj krawędź od grupy z fa do grupy z gb Krawędź będąca ścieżką z fa do gb oznacza, że f(a) musi być większe od g(b), itd. KROK IV. Jeśli w grafie uzyskanym w kroku III są cykle, to funkcje priorytetów nie istnieją. Jeśli cykli nie ma, to niech f(a) będzie długością najdłuższej ścieżki zaczynającej się w grupie z fa; niech g(b) będzie długością najdłuższej ścieżki o początku w grupie z gb.

  36. Relacje priorytetów operatorów Ustalamy relację priorytetów operatorów

  37. Relacje priorytetów operatorów • W grafie nie ma cykli, więc funkcje priorytetów • Istnieją; • Ponieważ z f$ i g$ nie wychodzą żadne krawę- • dzie, to f($)=g($)=0; • Najdłuższa ścieżka z g+ ma długość 1, więc • g(+)=1; • Istnieje ścieżka z gid do f* do g* do f+ do g+ do f$, • więc g(id)=5.

  38. Obsługa błędów w analizatorach Istnieją dwa miejsca, w których analizator działający metodą pierwszeństwa operatorów może wykryć błędy: • Jeśli terminal na wierzchołku stosu i aktualny symbol wejściowy nie są ze sobą w żadnej relacji priorytetów; • Jeśli znaleziono uchwyt, ale nie ma produkcji, dla której ten uchwyt byłby prawą stroną.

  39. Obsługa błędów w analizatorach UWAGI. • Algorytm analizy metodą pierwszeństwa operatorów zdaje się redukować uchwyty złożone tylko z terminali. Jednakże, mimo że nieterminale są traktowane anonimowo, to na stosie analizatora dla każdego z niech jest zajęte miejsce. Czyli, gdy w powyższym błędzie 2. mówimy o uchwycie pasującym do prawej strony produkcji, oznacza to, że terminale do siebie pasują i pozycje zajmowane przez nieterminale są takie same.

  40. Obsługa błędów w analizatorach UWAGI. • Sam fakt, że znaleźliśmy na stosie ciąg symboli a <· b1 = b2 =... =bk, nie oznacza, że b1b2...bk jest ciągiem terminali po prawej stronie jakiejś produkcji. Nie sprawdzaliśmy tego warunku w algorytmie, ale możemy to zrobić, a nawet musimy, jeśli chcemy z redukcjami związać akcje semantyczne. Mamy więc możliwość wykrywania błędów w algorytmie z krokami (10)-(12) zmodyfikowanymi tak, aby sprawdzać, która z produkcji jest uchwytem podczas redukcji.

  41. Obsługa błędów podczas redukcji Procedurę wykrywania i obsługi błędów możemy podzielić na kilka części. Pierwsza z nich obsługuje błędy typu 2. Procedura ta może, na przykład, zdejmować symbole ze stosu, tak jak korki (10)-(12) algorytmu. Ponieważ nie ma produkcji, zgodnie z którą można by wykonać redukcję, więc nie jest wykonywana żadna akcja semantyczna. Zamiast tego wypisywany jest komunikat diagnostyczny. Aby stwierdzić jak ma wyglądać ten komunikat, procedura obsługująca przypadek 2. musi zdecydować, do której produkcji „jest podobna” prawa strona zdejmowana ze stosu.

  42. Obsługa błędów podczas redukcji Przykład: Zdejmujemy abc i nie ma prawej strony produkcji składającej się z a,b,c oraz zera lub więcej nieterminali. Możemy wówczas sprawdzić, czy usuniecie któregoś z a, b lub c daje popraną prawą stronę (z pominiętymi terminalami). Przykładowo jeśli prawa strona jest: aEcE to możemy wypisać komunikat: nieprawidlowy symbol b w wierszu (wiersz zawierajacy b)

  43. Obsługa błędów podczas redukcji Przykład: Zdejmujemy abc i nie ma prawej strony produkcji składającej się z a,b,c oraz zera lub więcej nieterminali. Możemy również rozważać zmianę bądź wstawienie terminala. Jeśli prawą stroną byłyby napis abEdc, to moglibyśmy wypisać komunikat: pominiete d w wierszu (wiersz zawierajacy c) Może się również okazać, że prawa strona jest właściwym ciągiem terminali, ale z inaczej położonymi nieterinalami. Jeśli abc jest zdejmowane ze stosu bez zawartych lub otaczających nieterminali i abc nie jestprawą stroną, aleaEbc jest, możemy wypisać komunikat: pominiete E w wierszu (wiersz zawierajacy b) gdzie E oznacza odpowiednią kategorię składniową reprezsentowaną przez nieterminal E.

  44. Obsługa błędów podczas redukcji Trudność znalezienia właściwego komunikatu, gdy nie znaleziono odpowiedniej prawej strony, zależy od tego, czy istnieje skończenie, czy nieskończenie wiele ciągów, które mogą być zdejmowane ze stosu w wierszach (10)-(12). W każdym takim ciągu b1b2...bk, sąsiednie symbole muszą być w relacji =, czyli b1 = b2 =... =bk. Jeśli z tablicy priorytetów operatorów wynika, że istnieje tylko skończona liczba ciągów terminali powiązanych ze sobą relacją =, to możemy rozpatrywać te ciągi indywidualnie. Dla każdego takiego ciągu x możemy wcześniej wyznaczyć najbliższą mu prawą stronę y i wypisywać komunikat mówiący, że znaleziono x a oczekiwano y.

  45. Obsługa błędów podczas redukcji Łatwo jest wyznaczyć wszystkie ciągi, które mogą być zdejmowane ze stosu w krokach (10)-(12), gdyż są one widoczne w grafie skierowanym, którego wierzchołki reprezentują terminale, a krawędź od a do b istnieje wtedy i tylko wtedy gdy a=b. Możliwe ciągi składają się wówczas z etykiet wierzchołków leżących na ścieżkach w tym grafie. Ścieżki mogą składać się z jednego wierzchołka Aby ścieżkę b1b2...bk można było zdjąć przy jakimś wejściu, musi: • istnieć symbol a (może nim być $), taki że a<· b1 = b2 =... =bk (b1 nazwijmy początkowy) • istnieć symbol c (może nim być $) taki, że bk·>c (bk nazwijmy końcowym). Tylko jeśli takie symbole istnieją może wystąpić redukcja, w wyniku której ze stosu zdejmiemy b1b2...bk. Jeśli w grafie istnieje ścieżka od wierzchołka początkowego do końcowego zawierająca cykl, to istnieje nieskończenie wiele ciągów, które mogą zostać zdjęte ze stosu. W przeciwnym razie ciągów jest skończona liczba.

  46. Obsługa błędów podczas redukcji Przypomnijmy gramatykę: E->E+E | E-E | E*E | E/E | E↑E | (E) | -E | id Tablica priorytetów Graf tablicy priorytetów

  47. Obsługa błędów podczas redukcji Procedura wyszukująca błędy: • Jeśli redukowany jest +,-,*,/ lub ↑, sprawdza, że nieterminale są po obu stronach. Jeśli nie to wypisuje komunikat: . brakuje oczekiwanych argumentow • Jeśli redukowany jest id sprawdza, czy po obu stronach nie ma nieterminali. Jeśli jakiś jest, to ostrzega: brakuje oczekiwanego operatora • Jeśli redukowane są ( ) to sprawdza, czy między nawiasami jest nieteriminal. Jeśli nie to może poinformować nie ma wyrażenia pomiędzy nawiasami • Procedura musi ponadto sprawdzić, że nie ma nieterminala po lewej lub prawej stronie nawiasów. Jeśli jest, to procedura wypisuje komunikat: brakuje oczekiwanego operatora

  48. Obsługa błędów przesunięcie/redukcja Gdy zaglądamy do tablicy priorytetów, aby zdecydować, czy wykonujemy przesunięcie czy redukcję (wiersze (6) i (9), może okazać się, że symbole z wierzchołka stosu i pierwszy symbol z wejścia nie są ze sobą w żadnej relacji. Przypuśćmy że a i b to dwa symbole z wierzchołka stosu ( b jest na wierzchu), c i d to dwa kolejne symbole wejściowe oraz, że b i c nie są w żadnej relacji priorytetów. wejście stos

  49. Obsługa błędów przesunięcie/redukcja Aby odzyskać kontrolę, musimy zmodyfikować stos, wejście albo jedno i drugie. Możemy wówczas: • zmieniać symbole; • wstawiać symbole na stos i do wejścia • kasować symbole z wejścia i stosu. Jeśli wstawiamy lub zmieniamy symbole, musimy uważać, żeby nie wpaść w pętlę nieskończoną, w której na przykład ciągle wstawialibyśmy symbole na początek wejścia, nie mogąc zredukować ani przesunąć żadnego z wstawionych symboli.

  50. Obsługa błędów przesunięcie/redukcja Nie stworzymy pętli nieskończonych jeśli zapewnimy, aby po odzyskaniu kontroli aktualny symbol z wejścia mógł być przesunięty ( jeśli aktualnym symbolem jest $, mamy pewność, że nie dodamy symboli do wejścia, a stos w końcu się zmniejszy). Przykład. • gdy ab jest na stosie a cd jest na wejściu, to jeśli a<·=c, to możemy zdjąć b ze stosu; • Jeśli b<·=d, to możliwe jest usunięcie c ze stosu; • Jeśli uda się znaleźć taki symbol e, że b<·=e <·=c, to możliwe jest wstawienie e przed c na wejściu. Ogólniej możemy wstawić taki ciąg symboli, że b<·=e1<·=... <·=en<·=c (jeśli nie możemy znaleźć pojedynczego symbolu do wstawienia). Dla każdego pustego miejsca w tablicy priorytetów musimy podać procedurę obsługi błędów (ta sama procedura może być używana w kilku miejscach). Gdy analizator sprawdza wpis dla a i b w kroku (6) a a i b nie są w żadnej z relacji priorytetów – znajduje on wskaźnik procedury obsługi dla tego błędu.

More Related