Lewy rekurencji - Left recursion

W formalnego języka teorii z informatyki , po lewej rekursji jest szczególnym przypadkiem rekursji gdzie ciąg jest rozpoznawany jako część języka przez fakt, że rozkłada się na sznurku od tego samego języka (po lewej) i przyrostka (na prawo). Na przykład, może być uznane jako suma ponieważ może być podzielony na również sumę i , odpowiednie rozszerzenie.

W zakresie kontekstu wolne gramatyki , A nieterminalowi do lewej rekurencyjne, że od lewej symboli w jednym z jego produkcji, jest sama w sobie (w przypadku lewego bezpośredniego rekursji) lub można się o około sekwencji podstawień (w przypadku pośrednich lewej rekursji).

Definicja

Gramatyka jest lewy rekurencyjny wtedy i tylko wtedy, gdy istnieje nieterminalowi symbol , który może czerpać do zdań postaci z siebie jak skrajnej lewej symbolem. Symbolicznie,

,

gdzie wskazuje operację wytwarzania jednego lub więcej podstawień, a to dowolna sekwencja symbol terminalny.

Bezpośredni lewej rekursji

Bezpośredni lewej rekursji występuje, gdy definicja może być spełniony tylko jeden zastąpienia. Wymaga ona regułę formularza

gdzie to sekwencja nieterminali i zaciskami. Na przykład, zasada

jest bezpośrednio po lewej rekurencyjne. W lewej do prawej rekurencyjne zejście parser dla tej reguły może wyglądać

void Expression() {
  Expression();
  match('+');
  Term();
}

i taki kod spadnie do nieskończonej rekursji, gdy wykonywane.

Pośrednie lewej rekursji

Pośrednie lewej rekursji występuje, gdy definicja lewej rekursji jest spełniony poprzez kilka zastępstw. To pociąga za sobą zestaw reguł następujący wzór

w których to sekwencje, z których każda może wydzielały łańcuch pusty , natomiast mogą być dowolne sekwencje symbol terminalny wcale. Zauważ, że te sekwencje mogą być puste. wyprowadzenie

następnie podaje jako od lewej w jego ostatecznej postaci zdań.

Usuwanie lewej rekursji

Lewy rekurencji często stwarza problemy dla analizatorów, albo dlatego, że prowadzi je do nieskończonej rekurencji (jak w przypadku większości top-down parserami ) lub dlatego, że oczekują zasady w normalnej formie, która zabrania (jak w przypadku wielu oddolnych parser , włącznie z algorytmem cyk ). Dlatego gramatyka jest często wstępnie przetworzone w celu wyeliminowania lewy rekursji.

Usuwanie lewy bezpośredniej rekursji

Ogólny algorytm do usunięcia lewej bezpośredni rekurencji następująco. Liczne udoskonalenia tej metody zostały dokonane. Na lewo-rekurencyjne nieterminalowi , odrzucić wszelkie zasady formie i za te, które pozostają:

gdzie:

  • każdy jest sekwencją niepusty z nieterminali i terminali oraz
  • każdy jest sekwencją nieterminali i terminali, które nie rozpoczyna się .

Zastąpić te dwa zestawy, jeden zestaw produkcjach dla :

oraz innego zestawu do świeżej nieterminalowi (często nazywana „ogon” lub „reszta”):

Powtórz ten proces, dopóki nie bezpośrednich lewą szczątków rekursji.

Jako przykład rozważmy zestaw reguł

Może to być przepisywane w celu uniknięcia lewej rekursji jako

Usuwanie wszystkich lewej rekursji

Poprzez utworzenie topologii zamawianie na nieterminali, powyższy proces może być rozszerzony również wyeliminować pośrednie lewej rekursji:

Wejścia gramatyki: zestaw nieterminali i ich produkcjach
Wyjście Zmodyfikowany gramatyka generując tym samym językiem, ale bez lewej rekursji
  1. Dla każdego nieterminalowi :
    1. Powtarzać aż iteracji gramatyka pozostawia bez zmian:
      1. Dla każdej reguły , jest sekwencją terminali i nieterminali:
        1. Jeśli zaczyna się od nieterminalowi i :
          1. Pozwolić być bez swoich czołowych .
          2. Usuń regułę .
          3. Dla każdej reguły :
            1. Dodaj regułę .
    2. Usuń lewy bezpośredniej rekursji dla jak opisano powyżej.

Należy zauważyć, że algorytm ten jest bardzo wrażliwy na nieterminalowi zamawiającego; optymalizacje często koncentrują się na wyborze tego zamawianie dobrze.

pułapki

Chociaż powyższe przekształcenia zachowania języka generowanego przez gramatykę, mogą zmienić drzew analizowania że świadek uznania strun. Dzięki odpowiedniej księgowości, drzewo przepisywanie można odzyskać oryginały, ale jeśli ten krok zostanie pominięty, różnice mogą zmienić semantykę do przetworzenia.

Łączność jest szczególnie podatny; lewy-asocjacyjne operatorzy zazwyczaj pojawiają się w prawym asocjacyjne podobny ustaleń wynikających z nowej gramatyki. Na przykład, wychodząc z tym gramatyki:

standardowe przekształcenia usunąć lewy rekursji otrzymując następujące:

Parsowania ciąg „1 - 2 - 3” z pierwszej gramatyki w parsera LALR (który może obsługiwać lewej rekurencyjnych gramatyk) skutkowałoby drzewie parsowania:

Lewy-rekurencyjne parsowania z podwójnym odejmowania

Tego parsowania grupy drzew warunki, na lewo, podając poprawne semantykę (1 - 2) - 3 .

Parsowania z drugiej daje gramatyka

Prawym rekurencyjne parsowania z podwójnym odejmowania

które są odpowiednio interpretowane oznacza 1 + (-2 + (-3)) , a także prawidłowe, ale mniej wierny wejściu i znacznie trudniejsze do realizacji kilku operatorów. Wskazówki, jak warunki na prawo pojawić się głębiej w drzewie, podobnie jak gramatyka prawym rekurencyjne by ułożyć je na 1 - (2 - 3) .

Uwzględnienie lewej rekursji w Analiza zstępująca

Formalnej gramatyki , który zawiera lewy rekurencji nie może być analizowany przez LL (k) -parser lub innego naiwnego rekurencyjnego zejścia parsera chyba że jest konwertowany na słabo równoważnej formie prawym rekurencyjne. W przeciwieństwie do lewej rekursji jest korzystna dla parserami LALR ponieważ powoduje użycie stosu niższej niż prawe rekursji . Jednak bardziej wyrafinowane top-down parser może realizować ogólne gramatyk bezkontekstowych autorem stosowania ograniczenia. W 2006 roku Frost i Hafiz opisany algorytm, który może pomieścić niejednoznaczne gramatyk z bezpośrednich lewych-rekurencyjne zasad produkcji . Że algorytm został rozszerzony do kompletnej analizy składniowej algorytmu, aby pomieścić pośrednie jak i lewej bezpośredni rekurencji w wielomianowym czasie, a do generowania kompaktowych reprezentacje wielomian-size dotyczące liczby potencjalnie wykładniczej o drzewo wyprowadzenia dla wysoce niejednoznaczne gramatyk przez mróz, Hafiza i Callaghan w 2007 roku . autorzy następnie wdrożony algorytm jako zestaw kombinatorów parsera napisane w Haskell języku programowania.

Zobacz też

Bibliografia

  1. ^ Uwagi o teorii języka formalnego i parsowania , James Power, Wydział Informatyki National University of Ireland, Maynooth Maynooth, Co Kildare, Irlandia. JPR02
  2. ^ Moore, Robert C. (maj 2000). „Usuwanie Lewa rekursji z gramatyk bezkontekstowych” (PDF) . 6-ty Applied przetwarzanie języka naturalnego Konferencja : 249-255.
  3. ^ Frost, R .; Hafiz R. (2006). „A New Top-Down analizowaniem Algorytm pomieścić dwuznaczność i lewej rekursji w czasie wielomianowym” . ACM SIGPLAN Uwagi . 41 (5): 46-54. doi : 10.1145 / 1149982.1149988 .Dostępny od autora w http://hafiz.myweb.cs.uwindsor.ca/pub/p46-frost.pdf zarchiwizowanych 8.01.2015 w Wayback Maszynie
  4. ^ Frost, R .; R. Hafiz; P. Callaghan (czerwiec 2007). „Modułowa i wydajniejszy Top-Down analizowaniem za niejednoznaczne lewej rekurencyjnych gramatyk” (PDF) . 10. Międzynarodowe Warsztaty parsowania Technologies (IWPT), ACL-SIGPARSE : 109-120. Zarchiwizowane z oryginałem (PDF) na 2011-05-27.
  5. ^ Frost, R .; R. Hafiz; P. Callaghan (styczeń 2008). Parser kombinatorów dla niejednoznacznych zostawienie rekurencyjnych gramatyk (PDF) . 10. Międzynarodowe Sympozjum na temat praktycznych aspektów deklaratywnej języki (PADL), ACM-SIGPLAN . Lecture Notes in Computer Science. 4902 . ss. 167-181. doi : 10.1007 / 978-3-540-77442-6_12 . ISBN 978-3-540-77441-9,

Zewnętrzne linki