• Non ci sono risultati.

Parsing Bottom-up

N/A
N/A
Protected

Academic year: 2021

Condividi "Parsing Bottom-up"

Copied!
40
0
0

Testo completo

(1)

Automi e Linguaggi Formali

Parsing Bottom-up

(2)

Idea del parsing bottom-up

Costruisce l’albero sintattico iniziando dalle foglie e salendo verso la radice

Esempio

E ! T + E |T

T ! int ⇤ T |int|(E )

(3)

Idea del parsing bottom-up

Esempio

Il parsing bottom-up riduce una stringa al simbolo iniziale invertendo le produzioni:

stringa produzione

int ⇤ int + int T ! int

int ⇤ T + int T ! int ⇤ T

T + int T ! int

T + T E ! T

T + E E ! T + E

(4)

Osservazione

Leggiamo le produzioni in ordine inverso (dal basso verso l’alto rispetto all’albero di parsing) E’ una derivazione da destra (letta in ordine inverso, da destra a sinistra)

Esempio

(5)

Esempio

int ⇤ int + int int ⇤ T + int T + int T + T T + E E E T int ⇤ T int + E T int

(6)

Costruzione dell’albero

(7)

Costruzione dell’albero

int ⇤ int + int

int ⇤ T + int int

T

(8)

Costruzione dell’albero

int ⇤ int + int int ⇤ T + int T + int

T

int ⇤ T

(9)

Costruzione dell’albero

int ⇤ int + int int ⇤ T + int T + int T + T T int ⇤ T int + T int

(10)

Costruzione dell’albero

int ⇤ int + int int ⇤ T + int T + int T + T T + E T int ⇤ T int + E T int

(11)

Costruzione dell’albero

int ⇤ int + int int ⇤ T + int T + int T + T T + E E E T int ⇤ T int + E T int

(12)

Un algoritmo per il parsing bottom-up

Sia I la stringa in input repeat

seleziona una sottostringa non vuota di I dove X ! `e una produzione

se non c’`e alcun , torna indietro rimpiazza con X in I

until I = S (simbolo iniziale) o tutte le possibilit`a sono state provate

(13)

Maniglie

Decisioni da prendere durante il parsing bottom-up:

quale sottostringa ridurre che produzione usare

Maniglia (handle): sottostringa tale che X ! `e una produzione che corrisponde ad un passo in una derivazione da destra della stringa in input

Nota: la sottostringa pi`u a sinistra che coincide con la parte destra di una produzione non `e sempre una maniglia

(14)

Dove riduciamo ?

Sia ↵ ! la stringa corrente durante un parsing bottom-up

Assumiamo che la prossima riduzione sia fatta usando la produzione X !

Allora ! `e una stringa di terminali, perch´e ↵X ! ! ↵ ! `e un passo di una derivazione da destra

(15)

Notazione

Idea: Dividere la stringa in due sottostringhe la sottostringa di destra deve essere ancora esaminata (una stringa di terminali)

la sottostringa di sinistra ha terminali e non-terminali (`e inserita in una pila)

Il punto di divisione `e marcato dal simbolo | il simbolo | non `e parte della stringa Inizialmente, tutto l’input `e non esaminato:

(16)

Operazioni di Shift e Reduce

Il parsing bottom-up usa solo due tipi di azioni (non banali):

Shift (scorri) Reduce (riduci)

(17)

Shift

Muove | di un posto verso destra

Sposta un terminale nella stringa di sinistra legge un terminale e lo inserisce sulla pila

(18)

Reduce

Applica una produzione inversa nella parte finale della stringa di sinistra

Rimpiazza una stringa di terminali in cima alla pila con la parte sinistra di una

produzione

Se A ! xy `e una produzione, allora: Cbxy|ijk ) CbA|ijk

(19)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift

int| ⇤ int + int shift int⇤ |int + int shift

int⇤ int| + int reduce T ! int int⇤ T | + int reduce T ! int ⇤ T

T| + int shift T +|int shift

T + int| reduce T ! int T + T| reduce E ! T T + E| reduce E ! T + E

(20)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift int| ⇤ int + int shift

int⇤ |int + int shift

int⇤ int| + int reduce T ! int int⇤ T | + int reduce T ! int ⇤ T

T| + int shift T +|int shift

T + int| reduce T ! int T + T| reduce E ! T T + E| reduce E ! T + E

(21)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift int| ⇤ int + int shift int⇤ |int + int shift

int⇤ int| + int reduce T ! int int⇤ T | + int reduce T ! int ⇤ T

T| + int shift T +|int shift

T + int| reduce T ! int T + T| reduce E ! T T + E| reduce E ! T + E

(22)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift int| ⇤ int + int shift int⇤ |int + int shift

int⇤ int| + int reduce T ! int

int⇤ T | + int reduce T ! int ⇤ T T| + int shift

T +|int shift

T + int| reduce T ! int T + T| reduce E ! T T + E| reduce E ! T + E

(23)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift int| ⇤ int + int shift int⇤ |int + int shift

int⇤ int| + int reduce T ! int int⇤ T | + int reduce T ! int ⇤ T

T| + int shift T +|int shift

T + int| reduce T ! int T + T| reduce E ! T T + E| reduce E ! T + E

(24)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift int| ⇤ int + int shift int⇤ |int + int shift

int⇤ int| + int reduce T ! int int⇤ T | + int reduce T ! int ⇤ T

T| + int shift

T +|int shift

T + int| reduce T ! int T + T| reduce E ! T T + E| reduce E ! T + E

(25)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift int| ⇤ int + int shift int⇤ |int + int shift

int⇤ int| + int reduce T ! int int⇤ T | + int reduce T ! int ⇤ T

T| + int shift T +|int shift

T + int| reduce T ! int T + T| reduce E ! T T + E| reduce E ! T + E

(26)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift int| ⇤ int + int shift int⇤ |int + int shift

int⇤ int| + int reduce T ! int int⇤ T | + int reduce T ! int ⇤ T

T| + int shift T +|int shift

T + int| reduce T ! int

T + T| reduce E ! T T + E| reduce E ! T + E

(27)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift int| ⇤ int + int shift int⇤ |int + int shift

int⇤ int| + int reduce T ! int int⇤ T | + int reduce T ! int ⇤ T

T| + int shift T +|int shift

T + int| reduce T ! int T + T| reduce E ! T

T + E| reduce E ! T + E E|

(28)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift int| ⇤ int + int shift int⇤ |int + int shift

int⇤ int| + int reduce T ! int int⇤ T | + int reduce T ! int ⇤ T

T| + int shift T +|int shift

T + int| reduce T ! int T + T| reduce E ! T T + E| reduce E ! T + E

(29)

L’esempio con le due operazioni Shift-Reduce

|int ⇤ int + int shift int| ⇤ int + int shift int⇤ |int + int shift

int⇤ int| + int reduce T ! int int⇤ T | + int reduce T ! int ⇤ T

T| + int shift T +|int shift

T + int| reduce T ! int T + T| reduce E ! T T + E| reduce E ! T + E

(30)

La pila

La stringa di sinistra pu`o essere implementata con una pila

La cima della pila `e il simbolo |

Un’operazione di Shift inserisce un terminale in cima alla pila

Un’operazione di Reduce toglie 0 o pi`u simboli dalla pila (parti destre di produzioni) e aggiunge un non-terminale sulla pila (parti sinistre di produzioni)

(31)

Conflitti

Il parsing shift-reduce non funziona con tutte le grammatiche libere da contesto

Per alcune grammatiche, qualunque parser shift-reduce arriva a dei conflitti

Anche conoscendo tutta la pila e i prossimi k simboli in input

Conflitto shift-reduce: il parser non sa decidere se fare uno shift o una reduce

Conflitto reduce-reduce: il parser non sa quale riduzione fare

Grammatiche non LR(k) (o non LR) Una grammatica ambigua non `e LR

(32)

Parsing Shift-Reduce

Due azioni:

Shift

ABC|xyz ) ABCx|yz Reduce (con A ! xy) Cbxy|ijk ) CbA|ijk

(33)

Come decidere se applicare shift o reduce

Esempio

E ! T + E |T

T ! int ⇤ T |int|(E )

Consideriamo int| ⇤ int + int

Potremmo ridurre tramite T ! int arrivando a T| ⇤ int + int

Errore: non potremo arrivare al simbolo iniziale E

(34)

Maniglie

Intuizione: vogliamo ridurre solo se il risultato pu`o ancora essere ridotto fino al simbolo iniziale Prendiamo una derivazione da destra:

S )

rm ↵X ! rm) ↵ ! Allora ↵ `e una maniglia di ↵ !

In un parsing shift-reduce, le maniglie appaiono solo in cima alla pila, mai nel mezzo

(35)

Maniglie

Intuizione: vogliamo ridurre solo se il risultato pu`o ancora essere ridotto fino al simbolo iniziale Prendiamo una derivazione da destra:

S )

rm ↵X ! rm) ↵ ! Allora ↵ `e una maniglia di ↵ !

In un parsing shift-reduce, le maniglie appaiono solo in cima alla pila, mai nel mezzo

(36)

Maniglie

Intuizione: vogliamo ridurre solo se il risultato pu`o ancora essere ridotto fino al simbolo iniziale Prendiamo una derivazione da destra:

S )

rm ↵X ! rm) ↵ ! Allora ↵ `e una maniglia di ↵ !

In un parsing shift-reduce, le maniglie appaiono solo in cima alla pila, mai nel mezzo

(37)

Maniglie solo in cima alla pila

Induzione informale sul numero di passi di riduzione: All’inizio `e vero, e la pila `e vuota

Dopo aver ridotto una maniglia

Il nonterminale pi`u a destra `e in cima alla pila

La prossima maniglia deve essere alla destra del nonterminale pi`u a destra, perch´e `e una derivazione da destra

La sequenza di mosse shift raggiunge la prossima maniglia

(38)

Sommario sulle maniglie

In un parsing shift-reduce, le maniglie appaiono sempre in cima alla pila

Le maniglie non sono mai alla sinistra del nonterminale pi`u a destra

Quindi non dobbiamo mai muovere verso sinistra il simbolo |

Gli algoritmi di parsing bottom-up si basano sul riconoscimento delle maniglie

(39)

Riconoscere le maniglie

Non esistono algoritmi efficienti per riconoscere le maniglie

Soluzione: usare delle euristiche che cercano di indovinare quali pile sono delle maniglie

Per alcune grammatiche, le euristiche indovinano sempre correttamente

Per le euristiche che useremo, si tratta delle grammatiche SRL

(40)

Grammatiche e conflitti

generano conflitti generano conflitti SLR CFG CFG non-ambigue Tutte le CFG

Riferimenti

Documenti correlati

Indicare l'importo del fondo crediti di dubbia esigibilità risultante nel prospetto del risultato di amministrazione allegato al consuntivo dell'esercizio N-2,

Questa evoluzione da un lato permette una maggior libertà di composizione delle fonti, ma dall’altro impone alle start-up la stessa attenzione nella scelta che viene richiesta

L’apparecchio si sta riscaldando per fare cafè o per erogare acqua calda: quando le spie erogazione 1 o 2 tazze e la spia erogazione acqua calda smettono di

 A A parser generator parser generator is a program that reads is a program that reads a grammar and produces a parser. a grammar and produces

La rappresentazione grafica che corrisponde ad una suddivisione in intervalli dello spazio campionario di una variabile aleatoria continua è un istogramma a

Corso di Laurea in Ingegneria dell’Informazione Prova scritta di Geometria e Algebra. 17

[r]

[r]