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:
SUMT→U|M→T|aUbT|aUbc|aMbU→aMbM|c→aT|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 .UUSM∗USMUMU
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.