Existe uma resolução diferente para o problema do “outro pendente” que não seja “correspondência mais próxima”?

9

Os seguintes presentes gramática livre de contexto uma "pendurado outra" tipo ambigüidade (imaginar que a significa if expr thene b significa elsee c está para algum outro tipo de instrução ou bloco):

SaSbS|aS|c
Por exemplo,aacbcpode ser analisado como(a(acbc))ou como(a(ac)bc)(esta é a palavra ambígua mais simples / mais curta para essa gramática).

A maneira "padrão" de resolver essa ambiguidade "dangling else" força a instrução "else" ( b ) a parear com o "se-então" mais próximo / mais interno ( a ). Isso pode ser realizado da seguinte maneira:

SaTbS|aS|cTaTbT|c
Esta gramática é inequívoca. No exemplo acima, força aanálise(a(acbc)).

Pergunta: Existe outra maneira natural de resolver a ambiguidade que forçaria a análise de a a c b c ? Em outras palavras, eu estou procurando uma gramática que gera a mesma língua que os dois acima, que é inequívoca, e que analisa um a c b c como ( um ( a c ) b c ) .(a(ac)bc)aacbcaacbc(a(ac)bc)

Observação: Minha primeira tentativa foi a seguinte: que resolve a ambiguidade deaacbcconforme necessário - mas essa gramática ainda é ambígua:aacbacbcpode ser analisada como(a(ac)b(acbc))ou como(a(acb(ac))bc).

SaSbS|aU|cUaU|c
aacbcaacbacbc(a(ac)b(acbc))(a(acb(ac))bc)
Gro-Tsen
fonte
11
E no seu último exemplo, qual das duas análises possíveis você considera "natural" ou correta, e por quê?
Richard
@rici Sim, esta é uma pergunta complicada !, e eu não sei. Ficarei feliz com uma gramática inequívoca que produz a análise de . O que eu mais importa é que um a um ... um a um c b c b c ... b c (com mais um é que b 's) corresponde ao k -ésimo última b com o k -ésimo um (e deixa o mais interna de um 's incomparável). aacbacbcaaaaaacbcbcbcabkbkaa
Gro-Tsen

Respostas:

7

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:

SU|MUT|aUbT|aUbc|aMbUMaMbM|cTaT|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 .UUSMUSMUMU

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.

rici
fonte
Parabéns por conseguir o que eu concluí que era provavelmente impossível! Eu verifiquei experimentalmente que, para palavras de tamanho ≤ 16, esta gramática é realmente inequívoca e gera as mesmas palavras que as da minha pergunta. Agora eu tenho que entender em detalhes como isso funciona!
Gro-Tsen
@ Gro-Tsen: Espero que o segundo parágrafo ajude a explicar. A gramática é muito mais simples, com as ambiguidades espúrias deixadas em: ( M como na minha solução, T a TSaSbT|aMbSM ) e foi o que descobri quando estava pensando no problema. Demorei um pouco para me convencer de que era necessário fazer U ser nulo para evitar análises ambíguas (embora, como eu disse, a ambiguidade seja relativa), e um pouco mais de tempo para contornar meu desgosto pelo caminho. Eu escolhi impor isso. Aposto que há uma apresentação mais elegante. TaT|cU
Richard
0

Tome a + b + c + d + e abcde. Existem duas maneiras óbvias de como uma gramática pode analisá-las, mas há uma maneira que usamos.

No caso do "outro pendente", não é assim que as pessoas encaram. Em vez disso, a sintaxe é interpretada como "se", seguida por zero, um ou mais "else if", seguida por um "else" opcional.

gnasher729
fonte
acbacbacbc