Levá rekurze
Levá rekurze v teorii formálních jazyků v matematické informatice je speciální případ rekurze, kdy lze určitý neterminální symbol přepsat v jednom nebo více krocích na řetězec, který obsahuje stejný neterminální symbol. O levou rekurzi se jedná, pokud je příslušný neterminál na začátku výsledného řetězce. Lze také říct, že určitý řetězec je rozpoznán jako část jazyka tak, že se skládá z řetězce z téhož jazyka (vlevo) a zbytku, sufixu (vpravo).
Například ve výseku gramatiky pro aritmetický výraz:
,
,
,
je neterminál E zleva rekurzivní.
Výraz  je rozpoznán jako součet, protože jej lze rozložit na součet  a sufix .

V termínech bezkontextových gramatik neterminální symbol obsahuje levou rekurzi, jestliže první symbol v jednom z jeho pravidel je samotný (v případě přímé levé rekurze) nebo lze získat řetězec obsahující tentýž symbol nějakou posloupností substitucí (v případě nepřímé levé rekurze).

Definice 
Gramatika obsahuje levou rekurzi právě tehdy, když existuje neterminální symbol , ze kterého lze odvodit větnou formu, která začíná původním neterminálem. Symbolicky,
,
kde  je operace provedení jedné nebo více substitucí a  je libovolný řetězec terminálních a neterminálních symbolů.

Přímá levá rekurze 
O přímou levou rekurzi se jedná, když podmínky z definice rekurze jsou splněny již jedinou substitucí. Vyžaduje pravidlo tvaru

kde  je řetězec neterminálů a terminálů. Například pravidlo

je přímo s levou rekurzí. Analyzátor s rekurzivním sestupem zleva doprava pro toto pravidlo může být následující:
funkce Expression()
{
    Expression();  match('+');  Term();
}
Tento kód způsobí při svém provedení nekonečnou rekurzi.

Nepřímá levá rekurze 
O nepřímou levou rekurzi se jedná, když jsou podmínky z definice rekurze splněny až při použití více než jednoho přepsání. Má za následek sada pravidel následující vzorek

kde  jsou řetězce, které všechny mohou dávat prázdný řetězec, a  jsou libovolné řetězce. Derivace

pak dává  jako první symbol v poslední větné formě.

Odstraňování levé rekurze 
Levá rekurze často představuje problém pro analyzátory, buď protože vede k nekonečné rekurzi (v případě většiny analyzátorů shora dolů) anebo protože očekávají pravidla v normální formě, která rekurzi zakazuje (jako v případě mnoha analyzátorů zdola nahoru, včetně CYK algoritmu). Proto se gramatiky často upravují, aby levou rekurzi neobsahovaly.

Odstraňování přímé levé rekurze 
Následující algoritmus slouží pro odstranění přímé levé rekurze. Existuje několik jeho vylepšení.
Pro každý neterminál  s levou rekurzí, zahodíme všechna pravidla tvaru  a ostatní pravidla tvaru:

kde:
  jsou neprázdné řetězce neterminálů a terminálů a
  jsou řetězce neterminálů a terminálů, které nezačínají symbolem .
nahradíme dvěma množinami pravidel, jednou se symbolem  na levé straně:

a druhou s přidaným neterminálním symbolem  (obvykle nazývaným „zakončení“ nebo "zbytek"):

Uvedený postup se opakuje, dokud nezůstává žádná přímá levá rekurze.

Jako příklad uvažujme sadu pravidel

kterou lze přepsat, aby se zabránilo levé rekurzi jako

Odstraňování veškeré levé rekurze 
Topologickým setříděním neterminálů lze výše uvedený postup rozšířit na odstraňování nepřímé levé rekurze:
Vstup Gramatika: množina neterminálů  a jejich pravidel
Výstup Upravená gramatika generující stejný jazyk, ale bez levé rekurze
 Pro každý neterminál :
 Opakuj, dokud iterace mění gramatiku:
 Pro každé pravidlo ,  je řetězec terminálů a neterminálů:
 Jestliže  začíná neterminálem  a :
 Nechť  jsou  bez jeho úvodní .
 Odstraň pravidlo .
 Pro každé pravidlo :
 Přidej pravidlo .
 Odstraň přímou levou rekurzi pro , jak je popsáno výše.
Všimněte si, že tento algoritmus je velmi citlivý na pořadí neterminálů; jeho optimalizace se často zaměřují na správný výběr tohoto řazení.

Skryté nástrahy 
Ačkoli výše uvedené transformace nemění generovaný jazyk, mohou měnit derivační strom, na kterém závisí struktura řetězce. Existují postupy, které pomocí stromových transformací mohou vést k původním výsledkům. Při vynechání tohoto kroku však rozdíly mohou změnit sémantiku analýzy.

Obzvláště zranitelná je asociativita; zleva asociativní operátory jsou do nové gramatiky převedeny jako zprava asociativní. Pokud například uvažujeme následující gramatiku:

standardní transformace pro odstranění levé rekurze dává následující:

Syntaktická analýza řetězce „1 - 2 - 3“ LALR analyzátorem podle původní gramatiky (LALR analyzátor umožňuje analýzu gramatik s levou rekurzí) dává derivační strom:

Tento derivační strom seskupuje termy odleva, což dává správnou sémantiku (1 - 2) - 3.

Syntaktická analýza podle upravené gramatiky dává derivační strom
,
který je při správné interpretaci 1 + (-2 + (-3)) také správný, ale méně věrný vstupu, a implementace některých operátorů může být mnohem obtížnější. Všimněte si, že se termy vpravo vyskytují hlouběji ve stromě, podobně jako v gramatice s pravou rekurzí jejich úpravou na 1 - (2 - 3).

Ošetření levé rekurze při analýze shora dolů 
Formální gramatika, která obsahuje levou rekurzi, nemůže být analyzována LL(k)-analyzátorem nebo jiným naivním analyzátorem s rekurzivním sestupem, pokud není zkonvertována na tvar slabě ekvivalentní gramatiky s pravou rekurzí. Naproti tomu, levá rekurze je upřednostňovaná pro LALR analyzátory, protože vede k menšímu využívání zásobníku než pravá rekurze. Rafinovanější analyzátory shora dolů však mohou implementovat obecné bezkontextové gramatiky pomocí omezení. V roce 2006 popsali Frost a Hafiz algoritmus, který je použitelný pro nejednoznačné gramatiky s přímou levou rekurzí. Tento algoritmus v roce 2007 rozšířil Frost, Hafiz a Callaghan na úplný algoritmus analýzy, který dovoluje nepřímou i přímou levou rekurzi v polynomiálním čase a pro vysoce nejednoznačné gramatiky generuje kompaktní reprezentaci polynomiální velikosti pro potenciálně exponenciální funkci počtu stromů analýzy. Autoři pak implementovali algoritmus jako sadu kombinátorů syntaktických analyzátorů napsaný v jazyce Haskell.

Odkazy

Reference

Související články 
 Koncová rekurze

Externí odkazy 
 CMU lecture on left recursion 
 Practical Considerations for LALR(1) Grammars
 X-SAIGA – eXecutable SpecificAtIons of GrAmmars

Programovací konstrukce
Formální jazyky
Syntaktická analýza
Rekurze
Binární operátory