Você está na página 1de 78

Automi e Linguaggi Formali

G. Michele Pinna
Univ. Cagliari

Anno Accademico 2010

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

1 / 64

Parsing

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

2 / 64

Analisi sintattica
Quando abbiamo un programma scritto in un linguaggio di program` scritto correttamazione dobbiamo prima controllare se il programma e mente e, contemporaneamente, tradurlo in modo che sia eseguibile un esempio: consideriamo unespressione regolare (il programma), ` il linguaggio associato il risultato dellesecuzione del programma e allespressione regolare cosa facciamo? ` corretta - analizziamo lespressione per scoprire che e - contemporaneamente associamo allespressione o una nuova espressione (sintassi astratta) oppure opportune direttive per eseguirla ` un esecutore (che a noi ora non interessa) - ci sara

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

3 / 64

Lo schema
token

programma sorgente

analizzatore lessicale

parser
next

parse tree

il resto del front end

rappresentazione intermedia

tabella dei simboli

` tutto deterministico! Analizzatore lessicale: linguaggi regolare, e Parser: piu ` complesso: vediamo come fare

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

4 / 64

Analisi sintattica
Un compilatore deve produrre codice oggetto e deve anche controllare che il programma in input sia scritto secondo le regole della sua sintassi Lanalisi lessicale controlla che i token siano scritti bene, e genera una stringa di token (i token sono, nel linguaggio di programmazione, tutte le sequenze di caratteri delimitate da spazi o a capo) Lanalisi sintattica prende la stringa di token - non tutte le stringhe di token sono programmi validi ` derivabili dalla gramma- dobbiamo riconoscere quelle buone, cioe tica che descrive le regole della sintassi del linguaggio ` valida, creiamo un albero di parsing (sintassi Se la stringa di token e astratta) Ovviamente partiamo da grammatiche non ambigue (abbiamo visto ` quando possibile) come eliminare le ambiguita,
G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 5 / 64

` Ripasso: eliminare le ambiguita


Introduciamo nuove variabili per forzare il corretto parsing dellespressione Consideriamo la grammatica che ha le due produzioni C if B then C ,
(ora non ci interessa cosa genera B ).

C if B then C else C

` ambigua: nella frase La grammatica e if E1 then if E2 then S1 else S2 non sappiamo a quale if si riferisce lelse, ed abbiamo due derivazioni leftmost diverse. La trasformiamo in C C1 | C2 C 1 if B then C 2 else C 2 C 2 if B then C 1 else C 2, C 2 if B then C

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

6 / 64

Parsing top-down
Costruisce un albero di parsing per una stringa, iniziando dalla radice e creando i nodi in ordine depth-rst (dato un nodo, prima lui e poi i gli da destra a sinistra, ricorsivamente) Trova la derivazione leftmost per una stringa Ad ogni passo, una produzione viene usata per trasformare una variabile Una volta scelta la produzione, bisogna individuare i simboli terminali della parte destra della produzione nella stringa in input if E1 then if E2 then S1 else S2 la derivo come C C 1 if B then C 2 else C 2 if B then if B then C else C 2 e poi i vari C , C 1 e C 2, ed i B , diventeranno espressioni booleane e comandi...

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

7 / 64

Parsing top-down: ricorsivo discendente


Introduciamo una procedura per ogni variabile Si inizia con la procedura per il simbolo iniziale Terminazione con successo se si scorre tutta la stringa in input Pseudocodice non deterministico per una variabile A:
1 2

si sceglie una produzione per il simbolo di variabile: A X1 X2 Xk per ogni 1 i k ` una variabile chiamo la procedura (una delle) associata (e) - se Xi e ` un terminale ed e ` uguale al simbolo corrente, passa al prossimo - se Xi e simbolo della stringa - altrimenti errore

la produzione (procedura) scelta potrebbe non essere quella giusta - bisogna permettere il backtracking - errore vuol solo dire che bisogna tornare al passo 1 per scegliere unaltra produzione (procedura) per A, - se non ce ne siano piu ` fallisce - anche il puntatore al simbolo corrente deve tornare indietro

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

8 / 64

Esempio
Consideriamo la grammatica S cAd , A ab | a e la parola cad : c a b S ha solo una produzione (procedura), quindi usiamo quella, e il puntatore scorre anche c : Creo un albero con la sola radice S ed un puntatore allinizio della stringa: S c a d

c A d Se usiamo la prima produzione per A abbiamo S c A d

a b ` diverso dal prossimo simbolo della stringa (d ). Torniamo indietro e proviamo la seconda il puntatore scorre anche a, ma b e produzione per A: S c A d

a ` uguale al possimo simbolo nella stringa. Abbiamo (il puntatore torna indietro alla c e poi scorre a). Il puntatore legge d che e creato un albero di parsing G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 9 / 64

Problemi
La grammatica potrebbe avere delle produzioni A A , quindi richiamerebbe sempre se stessa e potrebbe dare luogo ad una catena innita ` leftmost)... (ricordiamo che la derivazione e Usiamo quanto visto per la forma normale di Greibach:
Lemma 2 consideriamo una grammatica G = (V, , P , S ) in cui tutti i simboli sono utili. Consideriamo tutte le produzioni A A1 | A2 | . . . | Ak e siano tutte le altre produzioni A 1 | 2 | . . . | n che riscrivono A. Deniamo G = (V {B }, , P , S ), con B V e P ottenuto rimpiazzando tutte le produzioni che riscrivono A con le seguenti: A 1 | 2 | . . . | n e A 1 B | 2 B | . . . | n B e per la nuova variabile B si introducono le produzioni B 1 | 2 | . . . | k e B 1 B | 2 B | . . . | k B . Allora L(G ) = L(G )

` essere eliminata la ricorsione sinistra puo

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

10 / 64

Grammatiche LL(k )
` detta LL(k ) se nel parsing di una parola visita Una grammatica G e linput da sinistra a destra (la prima L) e simula una derivazione leftmost (la seconda). Inne il k sta per far avanzare di k posizioni il puntatore (chiamato di lookahead) per capire quale produzione usare (e lo si capisce deterministicamente)

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

11 / 64

Grammatiche LL(k )
` detta LL(k ) se nel parsing di una parola visita Una grammatica G e linput da sinistra a destra (la prima L) e simula una derivazione leftmost (la seconda). Inne il k sta per far avanzare di k posizioni il puntatore (chiamato di lookahead) per capire quale produzione usare (e lo si capisce deterministicamente) Il puntatore di lookahead lo uso per predirre...

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

11 / 64

Grammatiche LL(k ) e Parser predittivi


` detta LL(k ) se nel parsing di una parola visita Una grammatica G e linput da sinistra a destra (la prima L) e simula una derivazione leftmost (la seconda). Inne il k sta per far avanzare di k posizioni il puntatore (chiamato di lookahead) per capire quale produzione usare (e lo si capisce deterministicamente) Il puntatore di lookahead lo uso per predirre... Sono come i parser discendenti ricorsivi ma possono predire quale produzione usare guardando ad alcuni prossimi token (poi vedremo come) eliminano il bisogno di tornare indietro (backtracking) Funzionano con grammatiche LL(k ) In pratica, si usano grammatiche LL(1)

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

11 / 64

Come fare le predizioni?


Cosideriamo E T + E | T e T a | a T | (E ) (sono le espressioni aritmetiche non ambigue) ` facile perche ` tra le due produzioni di T a e la predizione non e T a T iniziano per a non sappiamo quale usare... (e E T + E o E T hanno lo stesso problema...) proviamo a mettere assieme il pressi comuni delle produzioni... la grammatica diventa E TX , X +E | , T aY | (E ) e Y T | Introduciamo due funzioni per capire quale produzione usare:
FOLLOW FIRST

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

12 / 64

FIRST
` linsieme di terminali che stanno allinizio di stringhe deriFIRST() e ` una qualunque stringa di simboli terminali e non vabili da , dove e Se allora

FIRST ()

Come la uso? Assumiamo di avere A | . Se FIRST () FIRST ( ) = allora basta guardare il prossimo simbolo in input. Se sta in FIRST () allora prendo A , se sta in FIRST ( ) prendo A

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

13 / 64

FIRST

e FOLLOW

` linsieme di terminali che stanno allinizio di stringhe deriFIRST() e ` una qualunque stringa di simboli terminali e non vabili da , dove e Se allora

FIRST ()

Come la uso? Assumiamo di avere A | . Se FIRST () FIRST ( ) = allora basta guardare il prossimo simbolo in input. Se sta in FIRST () allora prendo A , se sta in FIRST ( ) prendo A ` linsieme di terminali che possono apparire alla destra di FOLLOW (A) e A in una forma sentenziale (una derivazione da S ) Quindi esiste una derivazione S Aa se a

FOLLOW (A)

` il simbolo piu Se A e ` a destra in qualche forma sentenziale, mettiamo $ in FOLLOW (A)

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

13 / 64

Calcolare FIRST di un simbolo


Calcoliamo FIRST (X ) ` un terminale allora FIRST (X ) = {X } se X e ` una produzione allora se X e
FIRST (X )

` una produzione allora ` una variabile e X Y1 Y2 Yk e se X e - se a FIRST (Yi ) e FIRST (Y1 ) FIRST (Yi 1 ) allora a FIRST (X ) - se FIRST (Y1 ) FIRST (Yk ) allora FIRST (X ) ` che sta in FIRST (Y1 ) sta anche in FIRST (X ), - tutto cio quindi se da Y1 non si deriva la parola vuota, allora FIRST (X ) = FIRST (Y1 ), altrimento aggiungiamo FIRST (Y2 ) e cos` via

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

14 / 64

Calcolare FIRST di una stringa


Per calcolare se
FIRST (X1 . . . Xn ): FIRST (X1 . . . Xn )

mettiamo in
FIRST (X2 )

tutti i simboli di FIRST (X1 ) tranne

FIRST (X1 )

contiene allora mettiamo anche tutti i simboli di tranne

se FIRST (X1 ) FIRST (X2 ) contiene allora mettiamo anche tutti i simboli di FIRST (X3 ) tranne .... iteriamo no a n, se necessario se FIRST (X1 ) FIRST (Xn ) contiene , allora mettiamo anche in FIRST (X1 . . . Xn )

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

15 / 64

Calcolare FOLLOW
FOLLOW (S )

contiene $

se abbiamo la produzione A B allora mettiamo in FOLLOW (B ) tutto ` che sta in FIRST ( ) tranne cio se abbiamo le produzione A B o A B e ` che sta in FOLLOW (A) mettiamo in FOLLOW (B ) tutto cio
FIRST ( )

allora

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

16 / 64

Esempio: FIRST
Consideriamo la seguente grammatica: E TA, A +TA | , T FB , B FB | e F (E ) | id Allora: = {+, } (ho le produzioni A +TA | e chiaramente + FIRST(+TA))
FIRST (A) FIRST (B )

= {, } (ho le produzioni B FB | e chiaramente

FIRST (FB ))

= {(, id } (ho le produzioni F (E ) | id e chiaramente ( FIRST ((E )), mentre id lo metto dato che FIRST(id ) = {id })
FIRST (F ) FIRST (T )
FIRST (T )

= {(, id } (ho la produzione T FB e chiaramente = FIRST (F ))

FIRST (E )

= {(, id } (ho la produzione E TA e chiaramente FIRST (E ) = FIRST (T ))

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

17 / 64

Esempio: FOLLOW
Consideriamo la seguente grammatica: E TA, A +TA | , T FB , B FB | e F (E ) | id Allora:
FOLLOW(E )

` = {), $} (ho la produzione F (E ) e $ lo metto dato che E e

il simbolo iniziale)
FOLLOW(A) = {), $} (ho le produzioni A +TA e E TA, quindi devo ` che sta in FOLLOW(E ), dato che mettere in FOLLOW(A) tutto cio FIRST (A) contiene ) FOLLOW(T ) = {+, ), $} (ho le produzioni E TA, A +TA, quindi devo ` il simbolo mettere tutto quello che sta in FIRST(A) = {+, } e $ perche ` coinvolto) iniziale e FOLLOW(B ) = {+, ), $} (ho le produzioni T FB , B FB , quindi devo mettere $ e tutto quello che sta in FOLLOW(T ) = {+, ), }) FOLLOW(F ) = {+, , ), $} (ho le produzioni T FB , B FB , quindi devo ` {}, poi devo mettere mettere anche FIRST (B ) meno , cioe FOLLOW(T ) = {+, ), $} dato che sta in FIRST (B ) )

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

18 / 64

Grammatiche LL(1)
Sono grammatiche tali che: Se G ha due produzioni A e A allora = (da e non si possono derivare ` uno tra e stringhe che iniziano con lo stesso terminale e al piu ` derivare la stringa vuota) puo se FIRST () allora FIRST ( ) e FOLLOW ( ) sono disgiunti: , non deriva alcuna stringa che inizia con un terminale in FOLLOW ( ) se FIRST ( ) allora FIRST () e FOLLOW () sono disgiunti: , non deriva alcuna stringa che inizia con un terminale in FOLLOW ()
FIRST () FIRST ( )

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

19 / 64

Tavola per il parser predittivo


Costruiamo una tabella M per trovare quale produzione usare una riga per ogni variabile e una colonna per ogni terminale o $ Intuizione: la produzione A viene scelta se il prossimo simbolo di input a sta in FIRST (). Se allora la scelgo se a FOLLOW (A) per ogni A per ogni a FIRST () mettiamo A in M[A, a] se FIRST (), mettiamo A in M[A, b ] per ogni b FOLLOW (A), con b terminale se
FIRST ()

e$

FOLLOW (A)

allora mettiamo A in M[A, $]

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

20 / 64

Esempio
E TA, A +TA | , T FB , B FB | e F (E ) | id vediamo la riga per E : M[E , id ] contiene E TA dato che id
FIRST (TA) FIRST (TA)

M[E , +] non contiene nulla, dato che + non contiene neanche

= {(, id } e

M[E , ] non contiene nulla, dato che FIRST (TA) = {(, id } e non contiene neanche M[E , (] contiene E TA, dato che (
FIRST (TA) FIRST (TA)

M[E , )] non contiene nulla, dato che ) contiene neanche

= {(, id } e non

M[E , $] non contiene nulla, dato che $ FIRST (TA) = {(, id } e non contiene neanche
G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 21 / 64

Esempio: completiamo la M
E TA, A +TA | , T FB , B FB | e F (E ) | id

E A T B F

id E TA T FB

+ A +TA

( E TA T FB

A A B FB F (E ) B B

B F id

e usiamola per id + id
E TA FBA id BA guardando la colonna di id , e consumiamo id ` il simbolo successivo B guardando M[B , +], che e A +TA guardando M[A, +], e consumiamo +

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

22 / 64

Esempio: continuazione
E TA, A +TA | , T FB , B FB | e F (E ) | id id E TA T FB B F id B FB F (E ) + A +TA T FB B B ( E TA ) $

E A T B F

A A

e usiamola per id + id
T FB guardando la colonna di id , F id guardando M[F , id ], e lo consumiamo, e, visto che siamo in fondo, guardiamo la colonna $. Troviamo B eA mettiamo tutto assieme:
E TA FBA idBA idA id + TA id + FBA id + idBA id + idA id + id

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

23 / 64

Funziona solo con le grammatiche LL(1)


` ricorsiva sinistra o ambigua, la tabella ha caselle Se la grammatica e con piu ` produzioni... ` ambigua. La tabella e ` S iEtSA | a, A eS | , E b e a S A E Sa A , A eS E b b i e s iEtSB A $

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

24 / 64

Parsing Bottom-Up

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

25 / 64

Idea del parsing bottom-up


Nel parsing top-down cerco di costruire un albero sintattico a partire dalla radice, in quello bottom-up cerco di costruire lalbero sintattico iniziando dalle foglie e salendo verso la radice Prendiamo la grammatica: E T + E | T , T int T | int | (E ) e deriviamo int + int int ` la derivazione rightmost e: E T + E T + T T + int T T + int int int + int int e cerchiamo ti trovarla partendo dallultima derivazione...

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

26 / 64

Idea del parsing bottom-up: esempio


Partiamo da E T + E | T , T int T | int | (E ) e dalla stringa int + int int

int

int

int

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

27 / 64

Idea del parsing bottom-up: esempio


Partiamo da E T + E | T , T int T | int | (E ) e dalla stringa int + int int

int T + int int applicando T int T

int

int

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

27 / 64

Idea del parsing bottom-up: esempio


Partiamo da E T + E | T , T int T | int | (E ) e dalla stringa int + int int

int T + int int T + int T applicando applicando T int T int T

int

int

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

27 / 64

Idea del parsing bottom-up: esempio


Partiamo da E T + E | T , T int T | int | (E ) e dalla stringa int + int int

int T + int int T + int T T +T applicando applicando applicando T int T int T int T T

int

int

T T

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

27 / 64

Idea del parsing bottom-up: esempio


Partiamo da E T + E | T , T int T | int | (E ) e dalla stringa int + int int

int T + int int T + int T T +T T +E applicando applicando applicando applicando T int T int T int T T T T

int

int

T T E

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

27 / 64

Idea del parsing bottom-up: esempio


Partiamo da E T + E | T , T int T | int | (E ) e dalla stringa int + int int

int T + int int T + int T T +T T +E E applicando applicando applicando applicando applicando T int T int T int T T T T int T

int

int

T T E E

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

27 / 64

Un algoritmo
Un algoritmo per il parsing bottom-up Sia w la stringa in input
1 2 3 4

prendi una sottostringa non vuota di w cerca una produzione X rimpiazza con X in w ` una produzione, torna se non ci fosse alcun tale che X e indietro ripeti no a che non si raggiunge il simbolo S oppure non sono ` state provate tutte le possibilita

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

28 / 64

Maniglie
Durante il parsing bottom-up bisogna capire: Quale sottostringa ridurre Che produzione usare

` una sottostringa tale che X e ` una proLa maniglia (handle) e duzione che corrisponde ad un passo in una derivazione rightmost della stringa in input
Attenzione: la sottostringa piu ` a sinistra che coincide con la parte destra di ` sempre una maniglia una produzione non e

Dove ridurre: sia la stringa corrente durante un parsing bottom-up ` una stringa e la riduzione successiva sia fatta usando X . Allora e ` rightmost) di soli teminali (la derivazione e

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

29 / 64

Dove ridurre
Come trovo dove ridurre? Dividere la stringa in due sottostringhe:
1

La sottostringa di destra deve essere ancora esaminata (una stringa di terminali) ` messa su La sottostringa di sinistra ha terminali e non terminali (e una pila) ` marcato da un |, (e il simbolo | non e ` parte Il punto di divisione e della stringa)

` non esaminato: |x1 x2 . . . xn Inizialmente, tutto linput e

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

30 / 64

Shift e Reduce (parsing shift-reduce)


Il parsing bottom-up usa due operazioni: Shift (scorri) e Reduce (riduci) Muove | di un posto verso destra e sposta un terminale nella stringa di sinistra (legge un terminale e lo mette sulla pila)
SHIFT:

ABC |xyz ABCx |yz Applica una produzione inversa nella parte nale della stringa di sinistra (rimpiazza una stringa di terminali in cima alla pila con la parte sinistra di una produzione) ` una produzione, allora CBxy |ijk CBA|ijk Se A xy e Come decidere quando fare shift o reduce?
REDUCE :

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

31 / 64

Esempio
E T + E | T , T int T | int | (E ) Consideriamo int | int + int . Se decidessimo di usare T int per ottenere T | int + int non riusciremmo poi ad arrivare ad E .... ` ancora essere ridotto no al Vogliamo ridurre solo se il risultato puo simbolo iniziale: ` prendiamo una derivazione da destra S X , allora e una maniglia di In un parsing shift-reduce, le maniglie appaiono solo in cima alla pila, mai nel mezzo:
` certamente vero: pila e ` vuota - allinizio e ` in cima alla pila e la prossima - Dopo aver ridotto una maniglia il non terminale piu ` a destra e maniglia deve essere alla destra del non terminale piu ` a destra, dato che stiamo considerando derivazioni rightmost - La sequenza di mosse shift raggiunge la prossima maniglia
G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 32 / 64

Schema del parsing


In un parsing shift-reduce, le maniglie appaiono sempre in cima alla pila Le maniglie non si trovano mai alla sinistra del non terminale piu `a destra quindi non dobbiamo mai muovere verso sinistra il simbolo | Gli algoritmi di parsing bottom-up si basano sul riconoscimento delle maniglie, ma:
Non ci sono algoritmi efcienti per riconoscere le maniglie usare delle euristiche che cercano di indovinare quali pile sono delle maniglie le euristiche funzionano bene per alcune grammatiche (SRL)

` LR semplice)... vediamo prima il parsing LR(k ) (SLR e


G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 33 / 64

LR(k )
L: scorre linput da sinistra a destra R: segue una derivazione a destra al contrario ` numero di simboli in input da guardare per prendere una ke decisione (il solito lookahead) LR(1) legge anticipatamente 1 simbolo in input per capire cosa fare ` generale: funziona per quasi tutti i costrutti che possono essere e descritti da grammatiche context free ` essere implementato efcientemente non fa backtracking, e puo trova gli errori sintattici appena possibile in uno scan da sinistra a destra dellinput ` essere applicato ad un insieme di linguaggi che contiene i puo linguaggi LL
G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 34 / 64

Pressi
` ovvio come trovare le maniglie: Sappiamo che non e ` un Ad ogni passo il parser vede solo la pila, non lintero input. e ` ` presso valido se e tale che | e uno stato di un parser shift-reduce
1 2 3

un presso valido non va oltre la ne destra di una maniglia ` un presso valido dato che e ` un presso della maniglia e ` ci sono pressi validi sulla pila, non sono stati visti errori di nche parsing

` un linguaggio regoPer ogni grammatica, linsieme dei pressi validi e lare Mostreremo come costruire FA che accettano pressi validi

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

35 / 64

Item
` una produzione con un . nella sua parte destra (se ho X Un item e ho un unico item: X .) gli item per T (E ) sono: T .(E ) | (.E ) | (E .) | (E ). Un item indica quanto abbiamo visto di una produzione no al punto A .XYZ indica che speriamo di vedere nellinput una stringa derivabile da XYZ ` visto una stringa derivabile da A X .YZ indica che abbiamo gia X e che speriamo di vedere una derivabile da YZ nellinput ` visto una stringa derivabile da A XYZ . indica che abbiamo gie XYZ e che potrebbe essere il momento di ridurre XYZ ad A Sono spesso chiamati item LR(0)

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

36 / 64

Dagli item ad una automa a stati niti


Alcuni item sono usati per costruire un DFA che viene usato per prendere decisioni durante il parsing (automa LR(0)) Ogni stato dellautoma LR(0) rappresenta un insieme di item canonici LR(0) Data una grammatica e due funzioni item canonici LR(0)
CLOSURE CLOSURE

GOTO ,

costruiamo gli

serve a trovare gli stati dellautoma

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

37 / 64

CLOSURE
consideriamo una grammatica G = (V, , P , S ), aggiungiamo S S con S nuovo non terminale, che serve a dire al parser quando fermarsi (quando riduce tramite questa produzione) ` un insieme di item per una grammatica, e ` un CLOSURE (I ), dove I e insieme tale che
1 2

` un sottoinsieme di CLOSURE (I ) Ie Se A .B sta in CLOSURE (I ).


CLOSURE (I )

e B P allora B . sta

` ntantoche ` non si puo ` aggiungere piu Applichiamo questa proprieta ` niente a CLOSURE (I ) A .B CLOSURE (I ) se pensiamo di poter vedere in futuro una ` un sottostringa derivabile da B come input, e questa sottostringa avra presso derivabile da B , per cui dobbiamo aggiungere gli item B . per tutte le B P
G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 38 / 64

Esempio
la solita grammatica E T + E | T , T int T | int | (E ) Consideriamo linput (int ) ` uno stato in un parsing shift-reduce (E |) e ` un presso della parte destra di T (E ) (E e ` ridotto dopo il prossimo shift Sara litem T (E .) dice che nora abbiamo visto (E di questa produzione e speriamo di vedere )
` che la pila ha solo alcune parti Il problema nel riconoscere pressi validi e della parte destra di una produzione (se avesse una parte destra completa, potremmo ridurre), ma Queste parti sono sempre pressi della parte destra di una produzione

I = {S .E }, allora
CLOSURE(I )

= {S .E , E .E + T , E .T , T .int T , T .int , T .(E )}


Automi e Linguaggi Formali Anno Accademico 2010 39 / 64

G. Michele Pinna (Univ. Cagliari)

Pressi
` avere molti pressi di parti destre di produzioni: siano La pila puo pref1 , pref2 , . . . , prefn Sia prefi un presso della parte destra di Xi i , allora ` prima o poi ridotto a Xi prefi verra la parte mancante di i 1 inizia con Xi ` un Xi 1 prefi 1 Xi per qualche ci sara ` ridotto alla parte ricorsivamente, prefk +1 . . . prefn prima o poi verra mancante di k ` uno stato in un parsing Consideriamo la stringa (int int ): (int |int ) e shift-reduce e: 1 ` un presso della parte destra di T (E ) ( e
2 3

` un presso della parte destra di E T e ` un presso della parte destra di T int T int e
Automi e Linguaggi Formali Anno Accademico 2010 40 / 64

G. Michele Pinna (Univ. Cagliari)

Esempio
La pila di items T (.E ) E .T T int .T dice:
1 2 3

Abbiamo visto ( di T (E ) Abbiamo visto di E T Abbiamo visto int di T int T

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

41 / 64

GOTO
La funzione GOTO la usiamo per denire le transizioni dellautoma Dato I insieme di items e X simbolo non terminale della grammatica, GOTO (I , X ) = CLOSURE (I ) dove I = {A X . | A .X I }
quindi se gli stati sono
CLOSURE(I )

con I insieme di items ottenuti dalle produzione, la

` (CLOSURE(I ), X ) = GOTO(CLOSUREI , X ). Lautoma deve transizione nellautoma sara ` ovvio quale e ` il suo alfabeto: V riconoscere pressi quindi e

la solita grammatica E T + E | T , T int T | int | (E )


GOTO ({T

` .(E )}, () = CLOSURE ({T (.E )}) che e

{T (.E ), E .T + E , E .T , T .int T , T .int , T .(E )}

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

42 / 64

Collezione canonica di insiemi di item LR(0)


1

data una grammatica G = (V, , P , S ), aggiungere un simbolo S e una produzione S S alla grammatica C = CLOSURE ({S .S })
1

per ogni insieme di item I C e per ogni simbolo X V, se GOTO(I , X ) C allora aggiungi GOTO (I , X ) a C no a che non viene aggiunto piu ` niente a C

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

43 / 64

DFA LR(0)
1

data una grammatica G = (V, , P , S ), aggiungere un simbolo S e una produzione S S alla grammatica C = CLOSURE ({S .S })
1

per ogni insieme di item I C e per ogni simbolo X V, se GOTO(I , X ) C allora aggiungi GOTO (I , X ) a C no a che non viene aggiunto piu ` niente a C

stati: insiemi di item dalla collezione canonica Transizioni: funzione GOTO stato iniziale:
CLOSURE ({S

.S })

Altri stati: ottenuti applicando GOTO e poi facendo la chiusura Tutti gli stati sono nali

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

43 / 64

Come usare lautoma nel parsing shift-reduce?


Nota: Ogni stato corrisponde ad un simbolo della grammatica: quello delle transizioni che portano a lui Mettiamo gli stati raggiunti in una pila (ultimo stato in cima) Supponiamo che la stringa di simboli della grammatica porti lautoma dallo stato iniziale ad uno stato j ` una transizione da j shift sul prossimo simbolo in input a se ce etichettata a, e aggiungiamo il prossimo stato sulla pila Altrimenti, riduciamo:
Gli item nello stato j ci diranno quale produzione usare: A Eliminiamo tanti stati dalla pila quanti sono i simboli di Seguiamo una transizione etichettata A Mettiamo il nuovo stato sulla pila

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

44 / 64

Implementazione: idea dellalgoritmo


Un algoritmo per il parsing bottom-up. Sia w la stringa in input
1 2 3 4 5

prendi una sottostringa non vuota di w cerca una produzione X rimpiazza con X in w ` una produzione, torna indietro se non ci fosse alcun tale che X e ripeti no a che non si raggiunge il simbolo S oppure non sono state ` provate tutte le possibilita

bisogna capire quale sottostringa ridurre e che produzione usare ` la maniglia (handle), che e ` una sottostringa La sottostringa da ridurre e ` una produzione che corrisponde ad un passo in tale che X e ` una derivazione rightmost della stringa in input: S X ( e ` la derivazione e ` rightmost). una stringa di soli teminali, perche

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

45 / 64

Dove ridurre (rimuovere le maniglie)


Come trovo dove ridurre? idea: dividere la stringa in due sottostringhe
1

La sottostringa di destra deve essere ancora esaminata (una stringa di terminali) ` messa su La sottostringa di sinistra ha terminali e non terminali (e una pila) ` marcato da un |, (e il simbolo | non e ` parte Il punto di divisione e della stringa)

` contenere non Intuizione: Se ho | signica che S e puo terminali. ` non esaminato: |x1 x2 . . . xn Inizialmente, tutto linput e

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

46 / 64

Schema del parsing


In un parsing shift-reduce, le maniglie appaiono sempre in cima alla pila Le maniglie non si trovano mai alla sinistra del non terminale piu `a destra quindi non dobbiamo mai muovere verso sinistra il simbolo | ad ogni passo il parser vede solo la pila, e non lintero input. ` un presso valido se e ` tale che | e ` uno stato di un parser e shift-reduce un presso valido non va oltre la ne destra di una maniglia ` un Per ogni grammatica context free, linsieme dei pressi validi e linguaggio regolare possiamo associare un automa a stati niti

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

47 / 64

Identicare gli stati dellautoma: CLOSURE


Sia G = (V, , P , S ) una grammatica context free, allora ` un insieme tale che I I (G), e
1 2

CLOSURE(I ),

dove

CLOSURE(I )

` un non terminale allora B . Se A .B sta in CLOSURE (I ) e B e sta CLOSURE(I ) per ogni B . I .

` un insieme di item I tali Ogni stato dellautoma LR(0) che vogliamo costruire e che CLOSURE (I ) = I

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

48 / 64

Come deniamo le transizioni dellautoma: GOTO


Sia G = (V, , P , S ) una grammatica context free, allora ` un insieme tale che I I (G), e
1 2

CLOSURE(I ),

dove

CLOSURE(I )

` un non terminale allora B . Se A .B sta in CLOSURE (I ) e B e sta CLOSURE(I ) per ogni B . I .

` un insieme di item I tali Ogni stato dellautoma LR(0) che vogliamo costruire e che CLOSURE (I ) = I La funzione GOTO la usiamo per denire le transizioni dellautoma: dato I ` insieme di items e X V , allora GOTO(I , X ) = CLOSURE (I ) dove I e linsieme di item {A X . | A .X I }

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

48 / 64

DFA LR(0)
Sia G = (V, , P , S ) una grammatica context free, allora ` un insieme tale che I I (G), e
1 2

CLOSURE(I ),

dove

CLOSURE(I )

` un non terminale allora B . Se A .B sta in CLOSURE (I ) e B e sta CLOSURE(I ) per ogni B . I .

` un insieme di item I tali Ogni stato dellautoma LR(0) che vogliamo costruire e che CLOSURE (I ) = I La funzione GOTO la usiamo per denire le transizioni dellautoma: dato I ` insieme di items e X V , allora GOTO(I , X ) = CLOSURE (I ) dove I e linsieme di item {A X . | A .X I } Aumentiamo la grammatica ottenendo G = (V {S }, , P {S S }, S ). Sia Q {CLOSURE (I ) | I I (G )} tale che ogni per ogni q Q vale che q = e esistono q Q , X V tali che GOTO(q , X ) = q , allora LR(0) = (Q {}, V , GOTO, CLOSURE ({S .S }), Q )
G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 48 / 64

Esempio
Ovviamente mettiamo solo gli stati raggiungibili dellautoma. Consideriamo la grammatica G = ({S }, {a, b }, {S aSb , S ab }, S ). Allora I (G ) = {S .S , S S ., S .aSb , S a.Sb , S aS .b , S aSb ., S .ab, S a.b, S ab .}
CLOSURE({S
# # # # # # # # # # #

.S }) = {S .S , S .aSb , S .ab } = q0 e
= = = = = = = = = = =
CLOSURE ({S CLOSURE ({S CLOSURE () GOTO (q1 , a)

GOTO (q0 , S ) GOTO (q0 , a) GOTO (q0 , b ) GOTO (q1 , S ) GOTO (q2 , S ) GOTO (q2 , a) GOTO (q2 , b ) GOTO (q3 , S ) GOTO (q3 , b ) GOTO (q4 , S ) GOTO (q5 , S )

S .} ) = { S S .}

a.Sb, S a.b}) = {S a.Sb, S a.b, S .aSb, S .ab} = =


GOTO (q1 , b )

CLOSURE ()

CLOSURE ({S CLOSURE ({S CLOSURE ({S GOTO (q3 , a) CLOSURE ({S GOTO (q4 , a) GOTO (q5 , a)

aS .b}) = {S aS .b} a.Sb, S a.b}) = {S a.Sb, S a.b, S .aSb, S .ab} ab.}) = {S ab.}

= = =

CLOSURE ()

= = =
CLOSURE () CLOSURE ()

aSb.}) = {S aSb.}
GOTO (q4 , b ) GOTO (q5 , b )

= =

Chiamiamo q0 = {S .S }, q1 = {S S .}, q2 = {S a.Sb , S a.b , S .aSb , S .ab }, q3 = {S aS .b }, q4 = {S ab .} e q5 = {S aSb .}


G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 49 / 64

LR(0) di G = ({S }, {a, b}, {S aSb, S ab}, S )

q1
S Start a a S

q3
b

q0

q2
b

q5

q4 Quali sono le parole accettate dallautoma? , S , an b , an Sb con n 1, che sono tutti pressi di an Sb n per un qualche n 0...

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

50 / 64

LR(0) di G = ({S }, {a, b}, {S aSb, S ab}, S )

S S.

S aS .b

S S a

Start

S .S S .aSb S .ab

S a.Sb S a .b S .aSb S .ab


b

S aSb.

S ab.

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

50 / 64

Come usare lautoma nel parsing shift-reduce


Mettiamo gli stati raggiunti dallautoma che vede il presso in una pila (ultimo stato in cima) Supponiamo che la stringa di simboli della grammatica porti lautoma dallo stato iniziale ad uno stato j ` una transizione da j shift sul prossimo simbolo in input a se ce etichettata a, e aggiungiamo il prossimo stato sulla pila Altrimenti, riduciamo:
Gli item nello stato j ci diranno quale produzione usare: A Eliminiamo tanti stati dalla pila quanti sono i simboli di Seguiamo una transizione etichettata A Mettiamo il nuovo stato sulla pila

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

51 / 64

Esempio

q1
S

a a

q3
S b

Consideriamo

Start

q0

q2
b

q5 q4

e aabb

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

52 / 64

Esempio

q1
S

a a

q3
S b

Consideriamo

Start

q0

q2
b

q5 q4

e aabb

Mettiamo sulla pila q0 , vediamo a e mettiamo q2 , ora vediamo un altro a e mettiamo un altro q2 sulla pila, vediamo un b e mettiamo q4 sulla pila... posso fare la prima riduzione dato che q4 = {S ab.}. Quindi leviamo q4 e q2 e dato che GOTO(q2 , S ) = q3 mettiamo q3 sulla pila che ora contiene q0 , q2 e ` b, e q3 . Ora lautoma si trova nello stato q3 e linput che rimane da leggere e GOTO (q3 , b) = q5 = {S aSb.}. Riduciamo, leviamo q5 , q3 e q2 dalla pila, quindi siamo in q0 e con S si va in q1 = {S S .}. Abbiamo nito...

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

52 / 64

Esempio

q1
S

a a

q3
S b

Consideriamo

Start

q0

q2
b

q5 q4

e aabb

Da S aabb abbiamo prima ridotto usando S ab , ottenendo aSb che poi abbiamo ridotto usando S aSb

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

52 / 64

Formalizzazione del parsing che usa LR(0)


Assumiamo che la pila contenga , che il prossimo simbolo da leggere sia t e che il DFA sia nello stato q . Reduce usando X se q contiene X . Shift se q contiene X .t (e quindi abbiamo una transizione da q ad uno stato che contiene X t . per farlo deniamo la tabella action[q , a], dove la action[qi , a] contiene lazione che deve effettuare il parser tra Shift j , Reduce X , accept e error .

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

53 / 64

Esempio
` nella seguente condizione |t , LR(0) si trova nello stato qi , Il parser e ` in cima alla pila degli stati, e action[i , t ] contiene Shift j , allora che e vado nello stato qj di LR(0) (che metto nella pila degli stati) e metto t ` t | sulla pila, quindi lo stato del parser sara ` nella seguente condizione |t , LR(0) si trova nello stato Il parser e qi e action[i , t ] contiene Reduce X , allora metto X sulla pila al posto di , e vado nello stato qj di LR(0) che determino levando dalla pila degli stati esattamente | | elementi e metto lo stato che ottendo ` lo stato in cima alla pila degli stati dopo aver da GOTO (q , X ), dove q e ` X |t levato | | elementi, quindi lo stato del parser sara ` nella seguente condizione S |, LR(0) si trova nello stato qi e Il parser e action[i , ] contiene accept, allora accetto ` nella seguente condizione |t , LR(0) si trova nello stato qi Il parser e e action[i , t ] contiene error, allora non accetto
G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 54 / 64

Come riempire action[i , t ]


Per prima cosa osserviamo che non abbiamo bisogno di mantenere la ` lo stato del parser, la pila degli stati dellautoma LR(0): infatti, se | e pila degli stati la ottengo riconoscendo usando LR(0). Poi modichiamo leggermente la nozione di stato del parser: | $ (aggiungiamo un delimitatore alla ne...)
action[i , a], con a , contiene Shift j se GOTO(qi , a) = qj . Osserviamo che se GOTO(qi , a) = qj allora qi contiene un item A .a e qj litem A a. action[i , a], con a , contiene Reduce X se qi contiene un item A . action[i , $] contiene accept se qi contiene S S . in tutti gli altri casi, action[i , a] contiene error

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

55 / 64

Esempio
Vediamo la tabella action per la grammatica vista prima: a b $ Shift 2 error error error error accept Shift 2 Shift 4 error error Shift 5 error error Reduce S ab error error Reduce S aSb error

0 1 2 3 4 5

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

56 / 64

Tabella goto[i , A]
quando facciamo le riduzioni dobbiamo anche trovare lo stato corretto in cui mettere lautoma. Mentre la tabella action la costruiamo per i terminali, la tabella goto la costruiamo per i non terminali (che corrispondono a delle azioni Reduce goto[4, S ] = 3. Il parser si trova in questa situazione: an b|b n1 $ e action[4, b ] contiene Reduce S ab , quindi rimuovo ab da an b, ag...) (q0 , an1 S ) = q3 (uso la giungo S e determino lo stato. GOTO goto[5, S ] = 3. Il parser si trova in questa situazione: an Sb|b n1 $ e action[5, b ] contiene Reduce S aSb , quindi rimuovo aSb da an Sb, ...) (q0 , an1 S ) = q3 (uso la aggiungo S e determino lo stato. GOTO tutte le altre caselle sono vuote

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

57 / 64

Ricapitoliamo
Vogliamo costruire un parser bottom-up (shift-reduce):
1 2

prendo la grammatica G ` il simbolo iniziale aggiungo la nuova produzione S S , dove S e di G denisco lautoma LR(0) (e quindi determino gli stati fatti da item canonici) denisco le tabelle action e goto come visto prima
ho anche una pila dove accumulo simboli (e dove faccio push e pop di simboli) ho linput da scandire da sinistra a destra, con un simbolo terminatore sulla destra

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

58 / 64

Conitti
` avere dei problemi, legati a situazioni in questo schema di parsing puo cui non si sa decidere: Conitto shift/reduce: Lo stato qi contiene gli item X .a e X . Conitto reduce/reduce: Lo stato qi contiene gli item X . e X . ` SLR se non ci sono conitti (S sta per simple) Una grammatica e

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

59 / 64

Come cercare di eliminare i conitti


Quando abbiamo fatto le riduzioni non ci siamo preoccupati affatto di quali possano essere le prossime maniglie. Lo faccio: action[i , a], con a , contiene Reduce X se qi contiene un item A . e a FOLLOW (X ) (ricordiamo che FOLLOW (X ) contiene cosa posso derivare a destra di X ...)

Quindi ora faccio una riduzione solo nel caso in cui dopo quella posso ` un esempio delle euristiche) continuare a ridurre (questo e

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

60 / 64

Esempio
Consideriamo S S + S | S S | (S ) | int
q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 = = = = = = = = = = =

(la solita grammatica ambigua)

{S .S , S .S + S , S .S S , S .(S ), S int } {S S .} {S int .} {S (.S ), S .S + S , S .S S , S .(S ), S int } {S S . + S , S S . S } {S S + .S , S .S + S , S .S S , S .(S ), S int } {S S .S , S S .S , S .S + S , S .S S , S .(S ), S int } {S S + S ., S S . + S , S S . S } {S S S ., S S . + S , S S . S } {S (S .)} {S (S ).}

lo stato q7 (e q8 ) contiene sia S S + S . che da un reduce, e S S . S che da un shift... mettiamo le precedenze trasformando la grammatica in non ambigua
G. Michele Pinna (Univ. Cagliari) Automi e Linguaggi Formali Anno Accademico 2010 61 / 64

Alcune conclusioni
Il parser LR lo denisco usando la nozione di presso i pressi sono riconosciuti da un automa tramite lautoma costruisco le tabelle action e goto per il parsing SLR: la tabella action la costruiamo usando FOLLOW Posso fare meglio, ma prima:
1 2

` anche LR ogni grammatica LL e ` non ambigua e il linguaggio e ` accettato ogni grammatica LR(0) e da un automa deterministico il parsing LR funziona anche con grammatiche ambigue

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

62 / 64

Item LR(1) e parser LALR


Cambiamo gli item e come calcoliamo gli item canonici. Gli item sono ` un terminale o $. ora [A ., a] dove ora a e I1 (G) ora li ottengo cos` : dato [A .B , a] I1 (G) e data la produzione B , aggiungo [B ., b ] per ogni terminale in FIRST ( a)
CLOSURE

` sempre la chiusura di un insieme di item e

` linsieme di item I della forma [A X ., a] tali che litem e [A .X , a] sta in I


GOTO (I , X )

` un parser in cui la costruzione della tabella action Un parser SLR(1) e non genera conitti ` unottimizzazione del parser SLR(1) un parser LALR e

G. Michele Pinna (Univ. Cagliari)

Automi e Linguaggi Formali

Anno Accademico 2010

63 / 64

Esercizi
1

Considerate la grammatica S B , B aBc | C , C bCc | . Trovate ` LL(1)? il FIRST ed il FOLLOW di ogni simbolo. La grammatica e fate il parsing top down delle seguenti parole aabbcccc , aabbbcccc e abbbbccccc dicendo dove eventualmente fallisce della grammatica S E , E E + T | T , T id | (E ), dite quali sono gli item LR(0) e costruite lautoma per riconoscere le maniglie. Non ` gia ` aumentata) avete bisogno di aumentare la grammatica (e costruite le tabelle action e goto per la grammatica vista prima, usando il FOLLOW fate il parsing bottom up di x + (y + x ) (x e y sono generate da id ) della grammatica S E , E E + T | T , T T F | F , F id | (E ), dite quali sono gli item LR(0) e costruite lautoma per riconoscere le ` gia ` maniglie. Non avete bisogno di aumentare la grammatica (e aumentata) fate il parsing bottom up di (x (y + z )) (x , y e z sono generate da id )
Automi e Linguaggi Formali Anno Accademico 2010 64 / 64

5 6

G. Michele Pinna (Univ. Cagliari)

Você também pode gostar