Para uma dada linguagem livre de contexto G, chamamos um não-terminal anulável se , ou seja, podemos derivar a string vazia de depois de aplicar um número finito de produções.
Existe um algoritmo simples para determinar quais não-terminais de uma gramática são anuláveis, como pode ser encontrado aqui :
Começamos considerando todos os não-terminais como não anuláveis. todos os como anuláveis se houver uma produção . Em seguida, passamos por todas as outras produções excluindo produções com um terminal nelas e marcamos como nulo se todos os forem nulos. Continuamos fazendo esse loop até terminar um loop sem marcar nenhum termo-terminal como nulo.
Meu problema com esse algoritmo é que ele tem um tempo de execução : o pior caso é, por exemplo, , , , ..., , .A n → ϵ
Existe um algoritmo para esse problema com um tempo de execução melhor que ?
fonte
Respostas:
Não se pode implementar esse algoritmo em tempo linear da seguinte maneira? (Aviso: eu não li isso com muito cuidado, é provável que haja erros.)
No que se segue, sempre que digo "produção", quero incluir apenas aqueles que não incluem terminais. Construir uma lista, para cada não-terminal, das produções em que aparece. Para cada produção deixar c i contar quantos não-terminais distintos no lado direito estão atualmente marcados não anulável. Deixe Q denotar uma fila de não terminais que foram marcados como nulos, mas ainda não processados. Inicialize todos c i para o número de não terminais distintos no lado direito da produção i . Inicialize todos os não terminais para não anuláveis. Para cada Z não terminal gerado pela produção i com c i =Eu cEu Q cEu Eu Z Eu adicione Z a Q e marque Z como nulo.cEu= 0 Z Q Z
Enquanto não estiver vazio, remova um X não terminal arbitrário de Q e processe-o da seguinte maneira. Para cada produção jQ X Q j que está, diminua c j . Se um c J torna-se zero, verificar para ver se o correspondente não terminal Y tenha sido marcado nulo já. Se não, marcar Y anulável e adicionar Y para Q .X cj cj Y Y Y Q
fonte