Vai al contenuto

Grammatiche ambigue

Da Wikiversità, l'apprendimento libero.
lezione
lezione
Grammatiche ambigue
Tipo di risorsa Tipo: lezione
Materia di appartenenza Materia: Linguaggi formali e automi
Avanzamento Avanzamento: lezione completa al 100%

Una grammatica è detta ambigua se genera stringhe uguali tramite almeno due derivazioni differenti (quindi due alberi di derivazione diversi). Per meglio specificare, questa ambiguità è detta ambiguità sintattica. Solitamente una grammatica ambigua risulta più sintetica, ma presenta problemi spiegati successivamente.

Definizioni

[modifica]
Esempio di albero che deriva una proposizione ambigua

Il grado di ambiguità di una proposizione su un linguaggio è il numero di alberi di derivazione distinti che producono sulla grammatica (eventualmente infiniti).

Il grado di ambiguità di una grammatica è il massimo tra i gradi di ambiguità delle proposizioni che compongono il linguaggio .

Il problema di decidere se una grammatica è ambigua o no, è un problema indecidibile: non esiste un algoritmo che termini in un numero finito di passi con una risposta è decidibile/non è decidibile. L'assenza di ambiguità può essere però mostrata attraverso ragionamenti induttivi, permettendo così di analizzare un numero finiti di casi. Viceversa la presenza di ambiguità può essere dimostrata mostrando un caso d'esempio (detto witness).

Tipi di ambiguità

[modifica]

Nelle seguenti sezioni presentiamo alcune tipologie di ambiguità spesso ricorrenti e ne mostriamo un'idea di risoluzione per eliminare l'ambiguità delle stesse.

Ambiguità da ricorsione bilaterale

[modifica]

Una grammatica nella forma è ambigua. Esempio:

può essere generato in due modi:

La grammatica dell'esempio sopra può essere riscritta in formato non ambiguo nei seguenti modi:

Ambiguità dall'unione di linguaggi

[modifica]

Siano due linguaggi che condividono alcune proposizioni, cioè , allora la grammatica per il linguaggio è ambigua perché ammette due distinte derivazioni .

Ovviamente l'insieme delle proposizioni non ambigue è . Questa situazione è facilmente risolvibile imponendo a priori che .

Esempio:

Ambiguità dalla concatenazione di linguaggi

[modifica]

Similmente all'unione, la concatenazione può causare ambiguità. Questo avviene quando il suffisso di qualche preposizione del primo linguaggio è prefisso di qualche preposizione del secondo.

Formalmente: t.c. con , e . In questo caso la grammatica è ambigua per le preposizioni .

L'enunciato sopra è facilmente dimostrabile, due sono le possibili derivazioni:

Un classico esempio sono la concatenazione di due linguaggi di Dyck che condividono una coppia di simboli. Per risolvere il problema è possibile inserire un nuovo simbolo terminale che agisca da separatore nell'assioma, ad esempio:

Ambiguità in frasi condizionali

[modifica]

Questa ambiguità nasce dalla programmazione di compilatori. Si prenda per esempio il classico problema di annidiare clausole if-then di un linguaggio (questo problema è chiamato Dangling else):

Non rientra in questo problema le clausole EXP e ISTR, che possiamo considerare anche terminali. Sia ora data la seguente stringa generata dalla grammatica di cui sopra:

Questa grammatica a quale sequenza di generazione corrisponde? Vediamo come possono essere applicate la parentesi graffe in stile linguaggio C:

if EXP then {
    if EXP then {
        ISTR
    } else {
        ISTR
    }
}

ma potrebbe anche essere interpretato come:

if EXP then {
    if EXP then {
        ISTR
    }
} else {
    ISTR
}

Queste due sequenze dimostrano l'ambiguità del linguaggio/grammatica.

Soluzioni

[modifica]

Proponiamo qui due possibili soluzioni:

  • introdurre un terminale endif:
  • forzare gli annidiati ad avere else:

Ambiguità in regexp

[modifica]

Molte espressioni regolari sono ambigue. Si prenda un esempio banale:

la sua grammatica () è evidentemente ambigua.

La soluzione all'esempio sopra è eliminare la ridondanza di a*:

Ambiguità per perdita di ordine

[modifica]

Un'altra ambiguità molto comune avviene quando una stringa può essere generata utilizzando come punto di partenza due termini di una stessa regola. Spieghiamo meglio con un esempio:

Il problema di questa regola è che tutte le stringhe nella forma con sono ambigue. Si prenda per esempio aabbb, essa può essere generata sia a partire da che a partire da .

Per risolvere queste ambiguità si divide la regola imponendo così un ordine alla derivazione:

Si noti come la regola aXb non è stata inserita nella ricorsione perché non necessaria.

Altri progetti

[modifica]