Esiste una diversa risoluzione del problema "penzoloni" diverso da "match più vicino"?


9

I seguenti regali di grammatica context-free un "penzoloni altro" tipo di ambiguità (immaginate che a acronimo di if expr thene b sta per elsee c sta per qualche altro tipo di istruzione o blocco):

SaSbS|aS|c
Ad esempio,aacbcpuò essere analizzato come(a(acbc))o come(a(ac)bc)(questa è la parola ambigua più semplice / più breve per questa grammatica).

Il modo "standard" per risolvere questa ambiguità "penzolante altro" impone all'istruzione "else" ( b ) di accoppiarsi con il "if-then" ( a ) più vicino / più interno . Questo può essere realizzato come segue: Questa grammatica non è ambigua. Nell'esempio sopra, forza l'analisi(a(acbc)).

SaTbS|aS|cTaTbT|c
(a(acbc))

Domanda: esiste un altro modo naturale per risolvere l'ambiguità che costringerebbe l' analisi di a a c b c ? In altre parole, sto cercando una grammatica che generi la stessa lingua delle due precedenti, che sia inequivocabile e che analizzi a a c b c come ( a ( a c ) b c ) .(a(ac)bc)aacbcaacbc(a(ac)bc)

Nota: il mio primo tentativo è stato il seguente: che risolve l'ambiguità diaacbccome richiesto - ma questa grammatica è ancora ambigua:aacbacbcpuò essere analizzata come(a(ac)b(acbc))o come(a(acb(ac))bc).

SaSbS|aU|cUaU|c
aacbcaacbacbc(a(ac)b(acbc))(a(acb(ac))bc)

1
E nel tuo ultimo esempio, quale delle due analisi possibili consideri "naturale", o corretta, e perché?
rici,

@rici Sì, questa è una domanda difficile! E non lo so. Sarò felice con una grammatica inequivocabile che produce l'analisi di . Quello che mi interessa di più è che a a a ... a a a c b c b c ... b c (con più a 's di b ' s) corrisponde alla k -esima b con la k -th a (e lascia il più interno di un 's senza pari). aacbacbcaaaaaacbcbcbcabkbkaa
Gro-Tsen

Risposte:


7

Questo problema è un analogo esatto del problema della corrispondenza delle parentesi in un'espressione in cui alcune parentesi chiuse sono state omesse. Qui un "if" (o nella grammatica rappresentativa) è una parentesi aperta e un "else" ( b ) è una parentesi stretta. (Dalla sequenza di a e b s è possibile inserire meccanicamente c s posizionandone uno prima di ogni bababcb e uno alla fine). Poiché si adatta meglio al mio cervello tra parentesi, scrivo come se quello fosse il problema attuale.

La tradizionale risoluzione "match più vicino" penzolante altro corrisponde a ciascuna chiusura con l'apertura più recente non ancora eguagliata. Ciò significa che non esiste mai un'apertura (o una chiusura) senza eguali tra un'apertura abbinata e la sua chiusura corrispondente.

Un'alternativa possibile sarebbe quella di abbinare ciascuna chiusura alla prima apertura ineguagliabile possibile. "Fattibile" qui significa che l'apertura potrebbe essere abbinata senza violare l'annidamento tra parentesi (es. Il primo in ( ) ( ) non può corrispondere fattibilmente all'ultimo ) ).(()())

Questa corrispondenza deve essere eseguita all'esterno, in modo da non tentare una corrispondenza per una chiusura fino a quando tutte le coppie che la racchiudono non sono state abbinate. Questo fatto rende impossibile produrre un'analisi con un algoritmo di sguardo limitato, poiché l'analisi deve lavorare verso l'interno da entrambe le estremità, dopo aver diviso la stringa in segmenti completamente abbinati (perché quelli limitano effettivamente l'intervallo di potenziali corrispondenze).

Tuttavia, il fatto che non esista un parser online da sinistra a destra non implica che non vi sia CFG inequivocabile. (Evidentemente: una lingua palindromica deve essere analizzata da entrambe le estremità verso il centro, ma è facile scrivere una grammatica non ambigua).

Per produrre una grammatica per il problema di parentesi "più lontano-match", ho fatto affidamento sul fatto che un'apertura senza pari non può essere seguita da un'apertura corrispondente. Se lo fosse, la proprietà della corrispondenza più lontana non si applicherebbe perché l'apertura senza pari avrebbe potuto corrispondere alla chiusura dell'apertura corrispondente, quindi il fatto che sia senza pari viola la proprietà della corrispondenza più lontana.

Quindi, ecco la grammatica leggermente goffa:

SU|MUT|aUbT|aUbc|aMbUMaMbM|cTaT|ac

è il simbolo iniziale; M sono dichiarazioni pienamente corrispondenti; U sono sicuramente dichiarazioni abbinate (il che significa che comprendono almeno un ineguagliabile una , per cui non possono essere vuote) e T è una "coda" consiste solo di ineguagliabile un s. Il fatto sopra relativo alle aperture senza pari può essere letto direttamente dalla grammatica: tutte le aperture senza pari sono derivate da T , una T può apparire solo alla fine di una U e una U può essere seguita solo da una TSMUaTaTTUUT .

Il clunkiness viene dall'impedire a di abbinare la stringa vuota. Ciò impedisce un sacco di ciò che considero ambiguità spurie: sono spurie nel senso che l'abbinamento delle aperture e delle chiusure è lo stesso in tutte le analisi alternative. Se U è autorizzato a essere nullable, verrà derivata anche una stringa completamente bilanciata. Poiché S è, in effetti, M U , ciò porta a un'ambiguità in cui si potrebbe considerare una S completamente bilanciata come una serie di M seguita da una U vuota , o una M in meno seguita da una U completamente bilanciata .UUSMUSMUMU

Probabilmente c'è una soluzione migliore di quella che ho scelto. Ma questo sembra funzionare e gioca bene con il parser GLR di Bison che ho usato per testarlo; quel parser si lamenta di analisi ambigue a meno che non si scriva un codice aggiuntivo per gestire l'ambiguità, ed ero troppo pigro per farlo. L'ho provato con stringhe fino a 20 open + chiuse e sembra che abbia prodotto un'analisi inequivocabile per ogni sequenza nidificata correttamente, senza produrre analisi per sequenze nidificate in modo errato.


Congratulazioni per aver raggiunto ciò che avevo concluso era probabilmente impossibile! Ho verificato sperimentalmente che per parole di lunghezza ≤16 questa grammatica è davvero inequivocabile e genera le stesse parole di quelle nella mia domanda. Ora devo capire in dettaglio come funziona!
Gro-Tsen,

@ Gro-Tsen: spero che il secondo paragrafo aiuti a spiegarlo. La grammatica è molto più semplice con le ambiguità spurie lasciate in: ( M come nella mia soluzione, T a TSun'SBT|un'MBSM ) ed è quello che mi è venuto in mente quando stavo pensando al problema. Mi ci è voluto un po 'di tempo per convincermi che era necessario rendere U non annullabile per evitare analisi ambigue (anche se, come ho detto, l'ambiguità è relativa), e un po' più a lungo per aggirare il mio disgusto per la strada Ho scelto di applicarlo. Scommetto che c'è una presentazione più elegante. Tun'T|cU
rici,

0

Prendi a + b + c + d + e e abcde. Esistono due modi ovvi in ​​cui una grammatica potrebbe analizzarli, ma esiste un modo che usiamo.

Nel caso dell '"altro penzolante", non è proprio così che la gente lo guarda. Invece la sintassi viene interpretata come "if", seguita da zero, uno o più "else if", seguito da un "else" facoltativo.


Nota che "se ... allora ... altrimenti se ... allora ... altrimenti se ... allora ... altro ..." corrisponde a un'cBun'cBun'cBcnella mia notazione: questo è analizzato in modo inequivocabile dalla mia grammatica iniziale (e le varianti che do sono d'accordo), quindi non sto chiedendo un'analisi alternativa di questo.
Gro-Tsen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.