Movatterモバイル変換


[0]ホーム

URL:


Przejdź do zawartości
Wikipediawolna encyklopedia
Szukaj

Parser LL

Z Wikipedii, wolnej encyklopedii

Parser LL toparser czytający tekst od lewej do prawej i produkujący lewostronne wyprowadzeniemetodą zstępującą. Popularne rodzaje parserów LL to parsery sterowanetablicą irekurencyjne.

Parser sterowany tablicą

[edytuj |edytuj kod]

Parsery klasyLL(k) parsują znak po znaku, utrzymując stos zawierający „spodziewane symbole”. Na początku znajdują się tam symbol startowy i znak końca pliku. Jeśli na szczyciestosu jest ten sam symbol terminalny, jaki aktualne znajduje się na wejściu, usuwa się go ze szczytu stosu i przesuwa strumień wejściowy na kolejny znak. Jeśli inny symbol terminalny zwraca się błąd. Jeśli występuje tam jakiś symbol nieterminalny, to zdejmuje się go i zależnie od tego symbolu oraz odk kolejnych znaków wejścia, umieszcza na stosie odpowiedni zestaw symboli.

LL(1) jest bardzo ubogą klasą (jednak w wielu przypadkach wystarczająca), np. tak prostagramatyka jak:

  • Wyrażenie → liczba '+' Wyrażenie
  • Wyrażenie → liczba

już do niej nie należy, ponieważ spodziewając się Wyrażenia i widząc liczbę, nie wiemy czy zamienić ją na stosie na liczba czy liczba '+' Wyrażenie.

Na szczęście można przepisać tę gramatykę na równoważną gramatykę LL(1):

  • Wyrażenie → liczba OpcjonalnePlusWyrażenie
  • OpcjonalnePlusWyrażenie → ε
  • OpcjonalnePlusWyrażenie → '+' Wyrażenie

Zbudujmy tablicę parsingu dla gramatyki:

  • Wyrażenie → Iloczyn '+' Wyrażenie
  • Wyrażenie → Iloczyn
  • Iloczyn → liczba '*' Iloczyn
  • Iloczyn → liczba

Najpierw musimy przepisać ją do równoważnej gramatyki LL(k) (w tym przypadkuk jest równe 1):

  • Wyrażenie → Iloczyn OpcjonalnePlusWyrażenie
  • OpcjonalnePlusWyrażenie → ε
  • OpcjonalnePlusWyrażenie → '+' Wyrażenie
  • Iloczyn → liczba OpcjonalneRazyIloczyn
  • OpcjonalneRazyIloczyn → ε
  • OpcjonalneRazyIloczyn → '*' Iloczyn

Tablica parsingu to:

liczba+*koniec
WyrażenieIloczyn OpcjonalnePlusWyrażeniebłądbłądbłąd
OpcjonalnePlusWyrażeniebłąd + Wyrażeniebłądε
Iloczynliczba OpcjonalneRazyIloczynbłądbłądbłąd
OpcjonalneRazyIloczynbłądε* Iloczynε

I dla wyrażenia 5 + 3 * 8 * 2 + 7 * 2 parsing przebiega następująco:

StosWejście
Wyrażenie koniecliczba + liczba * liczba * liczba + liczba * liczba koniec
Iloczyn OpcjonalnePlusWyrażenie koniecliczba + liczba * liczba * liczba + liczba * liczba koniec
liczba OpcjonalneRazyIloczyn OpcjonalnePlusWyrażenie koniecliczba + liczba * liczba * liczba + liczba * liczba koniec
OpcjonalneRazyIloczyn OpcjonalnePlusWyrażenie koniec+ liczba * liczba * liczba + liczba * liczba koniec
OpcjonalnePlusWyrażenie koniec+ liczba * liczba * liczba + liczba * liczba koniec
+ Wyrażenie koniec+ liczba * liczba * liczba + liczba * liczba koniec
Wyrażenie koniecliczba * liczba * liczba + liczba * liczba koniec
Iloczyn OpcjonalnePlusWyrażenie koniecliczba * liczba * liczba + liczba * liczba koniec
liczba OpcjonalneRazyIloczyn OpcjonalnePlusWyrażenie koniecliczba * liczba * liczba + liczba * liczba koniec
OpcjonalneRazyIloczyn OpcjonalnePlusWyrażenie koniec* liczba * liczba + liczba * liczba koniec
* Iloczyn OpcjonalnePlusWyrażenie koniec* liczba * liczba + liczba * liczba koniec
Iloczyn OpcjonalnePlusWyrażenie koniecliczba * liczba + liczba * liczba koniec
liczba OpcjonalneRazyIloczyn OpcjonalnePlusWyrażenie koniecliczba * liczba + liczba * liczba koniec
OpcjonalneRazyIloczyn OpcjonalnePlusWyrażenie koniec* liczba + liczba * liczba koniec
* Iloczyn OpcjonalnePlusWyrażenie koniec* liczba + liczba * liczba koniec
Iloczyn OpcjonalnePlusWyrażenie koniecliczba + liczba * liczba koniec
liczba OpcjonalneRazyIloczyn OpcjonalnePlusWyrażenie koniecliczba + liczba * liczba koniec
OpcjonalneRazyIloczyn OpcjonalnePlusWyrażenie koniec+ liczba * liczba koniec
OpcjonalnePlusWyrażenie koniec+ liczba * liczba koniec
+ Wyrażenie koniec+ liczba * liczba koniec
Wyrażenie koniecliczba * liczba koniec
Iloczyn OpcjonalneRazyWyrażenie koniecliczba * liczba koniec koniec
liczba OpcjonalneRazyIloczyn OpcjonalneRazyWyrażenie koniecliczba * liczba koniec
OpcjonalneRazyIloczyn OpcjonalneRazyWyrażenie koniec* liczba koniec
* Iloczyn OpcjonalneRazyWyrażenie koniec* liczba koniec
Iloczyn OpcjonalneRazyWyrażenie koniecliczba koniec
liczba OpcjonalneRazyIloczyn OpcjonalneRazyWyrażenie koniecliczba koniec
OpcjonalneRazyIloczyn OpcjonalneRazyWyrażenie konieckoniec
OpcjonalneRazyWyrażenie konieckoniec
konieckoniec

Warunek LL(1)

[edytuj |edytuj kod]

Aby gramatyka była klasy LL(1) dla każdego symbolu nieterminalnego, produkcja powinna być rozpoznawana i wybierana już po podejrzeniu jednego symbolu terminalnego. Oznacza to, że dla każdej pary produkcji dla jednego symbolu nieterminalnegoAα|β:{\displaystyle A\Rightarrow \alpha |\beta {:}}

  1. Zα{\displaystyle \alpha } iβ{\displaystyle \beta } nie da się wyprowadzić tego samego symbolu terminalnego
  2. Nie można jednocześnie wyprowadzić ciągu pustego zα{\displaystyle \alpha } iβ{\displaystyle \beta }
  3. Jeżeli zβ{\displaystyle \beta } da się wyprowadzić ciąg pusty, wówczas zα{\displaystyle \alpha } nie można wyprowadzić żadnego ciągu zaczynającego się od terminala należącego FOLLOW(A). Analogicznie w drugą stronę, gdy zα{\displaystyle \alpha } da się wyprowadzić ciąg pusty.

Te warunki są równoważne

  1. FIRST(α){\displaystyle FIRST(\alpha )} iFIRST(β){\displaystyle FIRST(\beta )} muszą być zbiorami rozłącznymi
  2. jeśliϵFIRST(β){\displaystyle \epsilon \in FIRST(\beta )} wtedyFIRST(α){\displaystyle FIRST(\alpha )} iFOLLOW(A){\displaystyle FOLLOW(A)} muszą być zbiorami rozłącznymi i analogicznie gdyϵFIRST(α){\displaystyle \epsilon \in FIRST(\alpha )} wtedyFIRST(β){\displaystyle FIRST(\beta )} iFOLLOW(A){\displaystyle FOLLOW(A)} muszą być zbiorami rozłącznymi

Transformacja do LL(1)

[edytuj |edytuj kod]

Aby gramatyka dała się przekształcić do LL(1) musi być jednoznaczna, jednak nie każda jednoznaczna da się przekształcić.Mamy dwie transformacje, które dają szansę, że dostaniemy gramatykę LL(1):

  1. eliminacja lewostronnej rekursji
  2. lewostronna faktoryzacja

Eliminacja lewostronnej rekursji

[edytuj |edytuj kod]

Mamy

  • Wyrażenie → Wyrażenie '+' liczba
  • Wyrażenie → liczba

Lewostronną rekurencję da się przepisać jako prawostronną:

przepisujemy na

Lewostronna faktoryzacja

[edytuj |edytuj kod]

Mamy

Patrzymy ile pierwszych symboli (terminalnych i nieterminalnych) jest identycznych. Tu mamy tylko jeden symbol – number. Prawą stronę zamieniamy na nowy symbol: nazwijmy go PlusExpr

Gdy więcej niż dwie produkcje zaczynają się od tego samego:

Zamieniamy na

Gramatyka niejednoznaczna

[edytuj |edytuj kod]

Czasami niejednoznaczna definicja gramatyki jest konieczna jak w przypadku IF..THEN..ELSE:

Po lewostronnejfaktoryzacji:

Gramatyka jest niejednoznaczna dla ElseStat w przypadku napotkania symbolu else. Rozwiązujemy to przyjmując wybór zachłanny

bo w przeciwnym razie gdybyśmy wybraliϵ{\displaystyle \epsilon } mógłaby zostać część else, która nie miała by wcześniejszego if.

Parser rekurencyjny

[edytuj |edytuj kod]

Parsery LL można też łatwo pisać ręcznie, za pomocą zestawu wzajemnie wywołujących się funkcji.

znaknastępny_znak;/* zmienna globalna */voidparsujWyrażenie(){if(następny_znak==liczba){parsujIloczyn();parsujOpcjonalnePlusWyrażenie();}else{błąd();}}voidparsujIloczyn(){if(następny_znak==liczba){następny_znak=odczytaj_znak();parsujOpcjonalneRazyIloczyn();}else{błąd();}}voidparsujOpcjonalnePlusWyrażenie(){if(następny_znak=='+'){następny_znak=odczytaj_znak();parsujWyrażenie();}elseif(następny_znak==KONIEC_PLIKU){/* pusty ciąg znaków */}else{błąd();}}voidparsujOpcjonalneRazyIloczyn(){if(następny_znak=='*'){następny_znak=odczytaj_znak();parsujIloczyn();}elseif(następny_znak=='+'||następny_znak==KONIEC_PLIKU){/* pusty ciąg znaków */}else{błąd();}}voidparsuj(){następny_znak=odczytaj_znak();parsujWyrażenie();if(następny_znak!=KONIEC_PLIKU)błąd();}

Zobacz też

[edytuj |edytuj kod]

Bibliografia

[edytuj |edytuj kod]
  • Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman: Kompilatory. Reguły, metody i narzędzia. Warszawa: WNT, 2002.ISBN 83-204-2656-1.
Źródło: „https://pl.wikipedia.org/w/index.php?title=Parser_LL&oldid=70202500
Kategoria:
Ukryta kategoria:

[8]ページ先頭

©2009-2026 Movatter.jp