recursão esquerda - Left recursion
Na teoria linguagem formal de ciência da computação , recursão esquerda é um caso especial de recursão , onde uma string é reconhecido como parte de uma linguagem pelo fato de que ele se decompõe em uma string a partir desse mesmo idioma (à esquerda) e um sufixo (em o certo). Por exemplo, pode ser reconhecido como uma soma porque pode ser dividida em , também uma soma, e , um sufixo adequado.
Em termos de gramática livre de contexto , um não-terminal está à esquerda-recursiva se o símbolo mais à esquerda em uma das suas produções é em si (no caso de recursividade esquerda directo) ou pode ser feito em si por uma sequência de substituições (no caso de indirecta recursão à esquerda).
Definição
A gramática é deixado-recursiva se e somente se existe um símbolo não-terminal que pode derivar de uma forma sentencial com ele mesmo como o símbolo mais à esquerda. simbolicamente,
- ,
onde indica a operação de fazer uma ou mais substituies, e é qualquer sequência de símbolos terminais e não terminais.
recursão direta esquerda
recursão direta esquerdo ocorre quando a definição pode ser satisfeita com apenas uma substituição. Ela exige uma regra da forma
onde é uma sequência de não-terminais e terminais. Por exemplo, a regra
está diretamente deixou-recursiva. A da esquerda para a direita analisador descendente recursivo para esta regra pode parecer
void Expression() {
Expression();
match('+');
Term();
}
e tal código cairia em recursão infinita quando executado.
Indireta recursão esquerda
recursão esquerda indireta ocorre quando a definição de recursão esquerda está satisfeito através de várias substituições. Ela implica um conjunto de regras seguindo o padrão
onde são sequências que podem cada produzem a cadeia vazia , enquanto podem ser quaisquer sequências de símbolos terminais e não terminais de todo. Note-se que estas sequências podem ser vazio. a derivação
em seguida, dá como mais à esquerda, na sua forma sentenciai final.
Removendo recursão esquerda
Recursão esquerda muitas vezes coloca problemas para os analisadores, ou porque ele leva-los para recursão infinita (como no caso da maioria dos analisadores top-down ) ou porque esperam regras de uma forma normal que o proíbe (como no caso de muitos bottom-up analisadores , incluindo o algoritmo cyk ). Portanto, uma gramática é muitas vezes pré-processado para eliminar a recursão esquerda.
Removendo recursão esquerda direto
O algoritmo geral para remover recursão direta esquerda segue. Várias melhorias para este método foram feitas. Para um não-terminal deixou-recursiva , descartar quaisquer regras da forma e considerar aqueles que permanecem:
Onde:
- cada é uma sequência não vazio de não-terminais e os terminais, e
- cada é uma sequência de não-terminais e os terminais que não começa com .
Substitua-os com dois conjuntos de produções, um conjunto para :
e outro conjunto para o não-terminal fresco (muitas vezes chamado de "cauda" ou o "resto"):
Repita este processo até que não haja restos de recursão esquerda diretos.
Como exemplo, considere o conjunto de regras
Esta poderia ser reescrito para evitar recursão esquerdo como
Removendo todos os recursão esquerda
Ao estabelecer uma ordenação topológica em nonterminals, o processo acima pode ser estendido para também eliminar a recursão esquerda indireta:
- Entradas Uma gramática: um conjunto de não-terminais e suas produções
-
Saída Uma gramática modificada gerando a mesma língua, mas sem recursão esquerda
-
Para cada não-terminal :
-
Repita até uma iteração deixa a gramática inalterada:
-
Para cada regra , sendo uma seqüência de terminais e não terminais:
-
Se começa com um não-terminal e :
- Vamos ser sem o seu líder .
- Remover a regra .
-
Para cada regra :
- Adicione a regra .
-
Se começa com um não-terminal e :
-
Para cada regra , sendo uma seqüência de terminais e não terminais:
- Remover recursão esquerda direto para como descrito acima.
-
Repita até uma iteração deixa a gramática inalterada:
-
Para cada não-terminal :
Note-se que este algoritmo é altamente sensível à ordenação não-terminal; otimizações muitas vezes se concentrar em escolher esta ordenação bem.
armadilhas
Embora as transformações acima preservar a linguagem gerada por uma gramática, eles podem alterar as árvores de análise que testemunha o reconhecimento cordas. Com a contabilidade adequada, reescrita árvore pode recuperar os originais, mas se este passo for omitido, as diferenças podem mudar a semântica de uma análise.
Associativity é particularmente vulnerável; associativo esquerda operadores normalmente aparecem no direito associativo-like regime reservado pela nova gramática. Por exemplo, começando com esta gramática:
as transformações convencionais para remover recursão esquerda deu o seguinte:
Analisar a string "1 - 2 - 3" com a primeira gramática em um analisador LALR (que pode lidar com gramáticas deixou-recursiva) teria resultado na árvore de análise:
Este de análise grupos de árvores os termos do lado esquerdo, dando a semântica correta (1 - 2) - 3 .
Analisando com o segundo gramática dá
que, devidamente interpretadas, significa 1 + (-2 + (-3)) , também correctas, mas menos fiel para a entrada e muito mais difícil de executar para alguns operadores. Observe como termos para a direita aparecem mais profundo na árvore, tanto quanto uma gramática direito recursivo iria organizá-los para 1 - (2-3) .
Acomodando recursão esquerdo na análise top-down
A gramática formal que contém recursão esquerda não pode ser analisado por um LL (k) -parser ou outro ingênuo analisador descendente recursivo a menos que seja convertida para um fracamente equivalente forma correta recursiva. Em contraste, a recursividade esquerda é preferido para analisadores LALR porque resulta no uso da pilha inferior a recursividade direita . No entanto, mais sofisticados analisadores top-down pode implementar gerais gramáticas livres de contexto por uso de corte. Em 2006, Frost e Hafiz descrito um algoritmo que acomoda gramática ambígua com esquerda-recursiva diretos regras de produção . Esse algoritmo foi estendido para uma completa análise algoritmo para acomodar indireta, bem como recursão direta esquerda na polinomial tempo, e para gerar representações de tamanho polinomial compactas do número potencialmente exponencial de árvores de análise para gramáticas altamente ambíguas por Geada, Hafiz e Callaghan, em 2007 . os autores, em seguida, implementou o algoritmo como um conjunto de combinadores analisador escritas no Haskell linguagem de programação.
Veja também
Referências
- ^ Notas sobre a teoria formal Língua e Análise , James Energia, Departamento de Ciência da Computação da Universidade Nacional da Irlanda, Maynooth Maynooth, Co. Kildare, na Irlanda. JPR02
- ^ Moore, Robert C. (Maio de 2000). "Removendo esquerda recursão de Context-Free Gramáticas" (PDF) . 6ª Conferência Applied Natural Language Processing : 249-255.
- ^ Geada, R .; R. Hafiz (2006). "A New Top-Down Análise de Algoritmo para acomodar Ambiguidade e recursão esquerda na polinomial Time" . ACM SIGPLAN Avisos . 41 (5): 46-54. doi : 10,1145 / 1.149.982,1149988 ., Disponível a partir do autor em http://hafiz.myweb.cs.uwindsor.ca/pub/p46-frost.pdf Arquivado 2015/01/08 no Wayback Machine
- ^ Geada, R .; R. Hafez; P. Callaghan (Junho de 2007). "Modular e eficiente Top-Down de análise para ambíguas Esquerda recursiva Gramáticas" (PDF) . Oficina 10ª Internacional sobre Analisando Technologies (IWPT), ACL-SIGPARSE : 109-120. Arquivado do original (PDF) em 2011-05-27.
- ^ Geada, R .; R. Hafez; P. Callaghan (janeiro de 2008). Analisador Combinadores para ambíguas Gramáticas Esquerda recursiva (PDF) . 10º Simpósio Internacional sobre Aspectos Práticos da declarativas Línguas (AFVD), ACM-SIGPLAN . Lecture Notes in Computer Science. 4902 . pp. 167-181. doi : 10,1007 / 978-3-540-77442-6_12 . ISBN 978-3-540-77441-9.

