2010-04-16 12 views

Odpowiedz

13

Tak istnieje ogólna procedura, patrz np wikipedia.

E = TE' 
E'= (e) | +TE' 
T = FT' 
T'= (e) | *FT' 
F = a | b | c 

Należy wspomnieć, że ta zmienia skojarzenia z + i * od lewej do prawej. To znaczy, że przed a + b + c został przeanalizowany jako (a + b) + c, jest teraz analizowany jako a + (b + c).

To nie jest problem dodawania i mnożenia, ale na przykład problem z odejmowaniem i dzieleniem.

Artykuł w Wikipedii zawiera więcej szczegółów na temat procedury usuwania lewostronnego rekursji i jej zawiłości.

+4

Jak rozwiązać ten problem?(odwracania asocjatywności) Widzę wiele kopii (bezpośrednio pośrednich) tego algorytmu usuwania lewej rekursji, i zawsze piszą ostrzeżenie o zerwaniu skojarzeń, ale nie widziałem jeszcze żadnego rozwiązania tego problemu w żadnym z takich artykułów . Czy istnieje jakieś rozwiązanie? Lub tylko problem? Drugie pytanie brzmi: dlaczego to działa? – SasQ

+2

Pytam, ponieważ nie widziałem żadnego wiarygodnego PROOF tego algorytmu. Były "dowody", które pokazały, że język uzyskany z przetworzonej gramatyki jest wciąż ten sam, ale dla mnie istnieje BŁĄD w takich dowodach: założenie, że jeśli składnia generuje ten sam wynik, to jest to samo. Bo to nie jest! Jest to zupełnie inny język, ponieważ ma inne drzewo parse, więc jest "rozumiany" inaczej przez maszynę. Ta sama różnica, co interpretacja "Drzewa składni abstrakcyjnej" jako "Drzewo składniowe" i "Drzewo składniowe" - dwie różne rzeczy. – SasQ

+1

To samo dotyczy składni lewej i prawej rekursywnej rekursywnej. Jedna z nich jest skojarzona, druga jest prawostronna. I nie wiem w żaden sposób, aby mieć składankę rekursywną lewostronną z prawostronnym skojarzeniem. Czy wiesz? – SasQ

2

Jak zauważyli inni, istnieje ogólna procedura zastępowania lewej rekursji prawą rekurencją. Pozostałe odpowiedzi pokazują, jak wykorzystać tę ogólną procedurę do usunięcia lewej rekursji w danej gramatyce.

Oto rozwiązanie, które zmienia strukturę gramatyki w sposób właściwy dla tej gramatyki.

E= T+E|T 
T= F*T|F 
F= a|b|c 
+0

Więc rzeczywiście mówisz, że proponowana gramatyka w lewej rekursji jest darmowa? Zastanawiam się, ponieważ natknąłem się na to w kursie w językach formalnych i stwierdzono, że lewostronne? –

3

Ogólna procedura znajduje się na przykład pod adresem Wikipedia. Będę zademonstrować, że E = E+T|T:

E to lewy-rekurencyjny nie-terminalny. +T jest sekwencją niepustą (alfa). T to sekwencja, która nie rozpoczyna się od E (beta).

Tworzymy nowy nieterminal dla "odpoczynku", czyli. sekwencja inna niż zerowa. To obsługuje rekursję.

E' = epsilon|+TE'

A my zmodyfikować oryginalny przepis do korzystania z nowego nieterminalowi obsłużyć rekursji.

E = TE'

1

produkcji

E = E+T 
    | T 
T = T*F 
    | F 
F = a|b|c 

idzie

E= T ('+' T)* 
T= F ('*' F)* 
F= a|b|c 

Aby utrzymać taką samą obróbkę gdzie pięści e dysjunktywnej jest przetwarzany A(E,T). nowa wersja używa:

ret = T1; 
while(set.more()) ret = A(ret, set.pop_front().T);