Esse problema é um análogo exato do problema de correspondência entre parênteses em uma expressão na qual alguns dos parênteses próximos foram omitidos. Aqui, um "se" (ou na gramática representativa) é um parêntese aberto e um "outro" ( b ) é um parêntese próximo. (A partir da sequência de a e b s, você pode inserir c s mecanicamente colocando um antes de cada b e um no final.) Como se encaixa melhor no meu cérebro entre parênteses, escrevo como se esse fosse o problema em questão.ababcb
A resolução tradicional de "correspondência mais próxima" do pendente corresponde a cada fechamento com a abertura mais recente ainda sem precedentes. Isso significa que nunca existe uma abertura incomparável (ou fechada, nesse caso) entre uma abertura correspondente e seu fechamento correspondente.
Uma alternativa possível seria combinar cada fechamento com o primeiro aberto possível inigualável. "Possível" aqui significa que o espaço aberto pode ser correspondido sem violar o aninhamento entre parênteses (por exemplo, o primeiro em ( ) ( ) não pode corresponder ao último ) ).(()())
Essa correspondência deve ser realizada de fora para dentro, para que não seja tentada uma correspondência até que todos os pares anexos tenham sido correspondidos. Esse fato torna impossível produzir uma análise com um algoritmo de contorno limitado, uma vez que a análise precisa trabalhar para dentro de ambas as extremidades, depois de dividir a sequência em segmentos completamente correspondentes (porque eles limitam efetivamente o intervalo de correspondências potenciais).
No entanto, o fato de não existir um analisador online da esquerda para a direita não implica que não haja CFG inequívoco. (Evidentemente: uma linguagem palindrômica deve ser analisada de ambos os lados até o meio, mas é fácil escrever uma gramática inequívoca).
Para produzir uma gramática para o problema de parênteses de "correspondência mais distante", confiei no fato de que uma abertura não correspondida não pode ser seguida por uma abertura correspondente. Se fosse, a propriedade de correspondência mais distante não se aplicaria porque a abertura não correspondida poderia corresponder ao fechamento da abertura correspondida, portanto, o fato de não corresponder viola a propriedade de correspondência mais distante.
Então aqui está a gramática um pouco desajeitada:
SUMT→U|M→T|aUbT|aUbc|aMbU→aMbM|c→aT|ac
é o símbolo inicial; M são declarações totalmente correspondentes; U são definitivamente declarações incomparáveis (o que significa que incluem pelo menos uma inigualável um , de modo que não pode estar vazio) e T é uma "cauda" consistindo apenas de inigualável um s. O fato acima sobre aberto incomparável pode ser lida directamente a partir da gramática: toda inigualável abre são derivados de T , a T só pode aparecer no final de um U , e um U só pode ser seguido por um T .SMUaTaTTUUT
A clunkiness vem de impedir que corresponda à string vazia. Isso evita um monte do que considero ambiguidades espúrias: são espúrias no sentido de que a correspondência entre abrir e fechar é a mesma em todas as análises alternativas. Se U for permitido ser nulo, ele também derivará uma sequência completamente equilibrada. Como S é, na verdade, M ∗ U , isso leva a uma ambiguidade na qual você pode considerar um S completamente equilibrado como uma série de M seguida por um U vazio ou menos M seguida por um U completamente equilibrado .UUSM∗USMUMU
Provavelmente, há uma solução melhor do que a que eu escolhi. Mas este parece funcionar e funciona bem com o analisador GLR de Bison, que eu costumava testá-lo; esse analisador reclama de análises ambíguas, a menos que você escreva um código extra para lidar com a ambiguidade, e fiquei com preguiça de fazer isso. Testei-o com seqüências de até 20 fechos + abertos, e parece ter produzido uma análise inequívoca para cada sequência aninhada corretamente, sem produzir análises para sequências aninhadas incorretamente.