Grammatiche ambigue

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.

lezione
lezione
Grammatiche ambigue
Tipo di risorsa Tipo: lezione
Materia di appartenenza Materia: Linguaggi formali e automi
Avanzamento Avanzamento: lezione completa al 100%

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