ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di...

30
ANALISI SINTATTICA LUCIDI DI F. D'AMORE E A. MARCHETTI SPACCAMELA AUTOMI PUSHDOWN controllo tabella input pila $ u t w v x y z $ Nov 2012 FI2 - #fi2sapienza 2

Transcript of ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di...

Page 1: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

ANALISI SINTATTICA

LUCIDI DI F. D'AMORE E

A. MARCHETTI SPACCAMELA

AUTOMI PUSHDOWN

controllo

tabella

input

pila

$ u t w

vxy

…z$

Nov

201

2 FI

2 - #

fi2sa

pien

za

2

Page 2: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

ARGOMENTI Il compito dell'analisi sintattica

Generazione automatica

Trattamento degli errori

Grammatiche libere dal contesto

Grammatiche ambigue

Analisi Top-Down vs. Analisi Bottom-Up

Una semplice analisi Top-Down

Nov

201

2 FI

2 - #

fi2sa

pien

za

3

FASI DI COMPILAZIONE Programma sorgente (stringa di caratteri)

Fin. Assembly

Analisi lessicale

Analisi sintattica (parsing)

Analisi semantica e traduzione

Tokens

Albero derivazione

Front-End

Ottimizzazione codice

Nov

201

2 FI

2 - #

fi2sa

pien

za

4

Page 3: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

TOKEN Un token è una porzione di input, categorizzata

input = stringa su alfabeto Unicode

alfabeto Java ! Unicode

scanning = riconoscimento (tramite ASFD) di un token

tokenization = suddivisione dell'input in token

Nov

201

2 FI

2 - #

fi2sa

pien

za

5

esempio Wikipedia

ESEMPIO DI GRAMMATICA TIPO 2

Nov

201

2 FI

2 - #

fi2sa

pien

za

6

1 S ! S ; S 2 S ! id := E 3 S ! print ( L ) 4 E ! id 5 E ! num 6 E ! E + E 7 E ! (S, E) 8 L ! E 9 L ! L, E

Token: S id E num .= print ( ) , +

S : statement (istruzione) id: identificatore E: espressione num: numero

Page 4: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

ESEMPIO DI DERIVAZIONE

Nov

201

2 FI

2 - #

fi2sa

pien

za

7

1 S ! S ; S 2 S ! id := E 3 S ! print (L) 4 E ! id 5 E ! num 6 E ! E + E 7 E ! (S, E) 8 L ! E 9 L ! L, E

S S ; S

S ; id := E

id := E ; id := E

id := num ; id := E

id := num ; id := E + E

id := num ; id := E + num

id := num ; id :=num + num

a 56 b 77 16

ESEMPIO ALBERO DERIVAZIONE

Nov

201

2 FI

2 - #

fi2sa

pien

za

8

S

S ; S

S ; id := E

id := E ; id := E

id := num ; id := E

id := num ; id := E + E

id := num ; id := E + num

id := num ; id :=num + num

; s s

s

id := E id := E

num E + E

num num

Page 5: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

GRAMMATICHE AMBIGUE Una grammatica è ambigua quando per una stessa stringa che appartiene al linguaggio definito esistono due diversi alberi di derivazione

Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

•  Semantica non chiara

•  Complessità analisi (due alberi derivazione)

Nov

201

2 FI

2 - #

fi2sa

pien

za

9

GRAMMATICHE NON AMBIGUE PER ESPRESSIONI ARITMETICHE

Grammatica ambigua e possibile disambiguazione

1  E ! E + T 2  E ! T 5  T ! T * F 6  T ! F 5 F ! id 6 F ! (E)

1 E ! E + E 2 E ! E * E 3 E ! id 4 E ! (E)

1  E ! E * T 2  E ! T 5  T ! F + T 6  T ! F 5 F ! id 6 F ! (E)

Nov

201

2 FI

2 - #

fi2sa

pien

za

10

Page 6: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

PERCHÉ GRAMMATICHE CF PER I LINGUAGGI DI PROGRAMMAZIONE ?

Le grammatiche di tipo 2 permettono di rappresentare la struttura gerarchica dei programmi

Sono più semplici delle grammatiche di tipo 1 e questo permette di avere parser efficienti

Vedremo in realtà che a tale scopo useremo ulteriori restrizioni

Nov

201

2 FI

2 - #

fi2sa

pien

za

11

ANALISI SINTATTICA (PARSING) INPUT

Sequenza di tokens

OUTPUT

Albero di derivazione

Riporta errori di sintassi

Crea tabella dei simboli, che contiene i diversi identificatori usati nel programma

Nov

201

2 FI

2 - #

fi2sa

pien

za

12

Page 7: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

PROPRIETÀ DEI PREFISSI Per ogni sequenza di token iniziale (prefisso) t1, t2, …, tk che l’analisi individua come legale (cioè che potrebbe fornire una stringa del linguaggio)

• devono esistere tokens tk+1, tk+2, …, tn tali che t1, t2, …, tnè un programma sintatticamente corretto

Equivalentemente

Se consideriamo un token come un singolo carattere, per ogni parola prefisso x che l’analisi considera legale

• esiste parola suffisso w tale che x w è un programma valido

Nov

201

2 FI

2 - #

fi2sa

pien

za

13

ANALISI SINTATTICA (1) Bottom-up (dal basso all’alto)

• Costrusci l’albero dalle foglie •  Avanza nell’input (shift) o deriva un non terminale

(reduce) •  Accetta quando input è finito e hai ottenuto assioma •  Ricostruisce in effetti l'albero attraverso una sua visita in

post-order

remaining input

Nov

201

2 FI

2 - #

fi2sa

pien

za

14

Page 8: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

ANALISI SINTATTICA (2) Top-Down (dall’alto al basso)

•  Inizia con l’assioma • Ripetutamente scegli un simbolo non terminale A

dell’albero finora ottenuto e applica una produzione ad A • Successo quando le foglie dell’albero rappresentano la

stringa di input • Albero ricostruito in pre-ordine

A

Nov

201

2 FI

2 - #

fi2sa

pien

za

15

ANALISI TOP-DOWN Supponi di aver completato parte di una derivazione

S ⇒* wA" e che wxy sia input

Passo ripetuto

Scegli una produzione su A A ::= #1 #2 … #n

che è congruente con input (la parte x non ancora ottenuta)

Per motivi di efficienza il passo deve essere deterministico

Nov

201

2 FI

2 - #

fi2sa

pien

za

16

A

Page 9: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

ANALISI TOP-DOWN: PARSER A DISCESA RICORSIVA

Un vantaggio dei parser top-down è che sono più semplici da implementare

Idea fondamentale: scrivere una funzione (procedura, metodo o sottoprogramma) in corrispondenza ad ogni simbolo non terminale

Ognuna di queste funzioni è responsabile di accoppiare il non-terminale con il resto dell’input

Nov

201

2 FI

2 - #

fi2sa

pien

za

17

ANALISI TOP-DOWN: PARSER A DISCESA RICORSIVA Se ci sono due produzioni del tipo

A ! "1 "2 … "n | #1 #2 … #m

bisogna provare entrambi le possibilità

Algoritmo ricorsivo contiene funzione A che tenta dapprima di usare la produzione A ! "1 "2 … "n. Se ottiene successo, allora A termina con successo, altrimenti tenta di usare la produzione A ! #1 #2 … #m. Se ottiene successo, allora A termina con successo, altrimenti termina con fallimento.

Tentare di usare una produzione significa consumare porzioni di input (terminali nella parte destra) e chiamare funzioni associate a non terminali.

Nov

201

2 FI

2 - #

fi2sa

pien

za

18

Page 10: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

ANALISI TOP-DOWN: PARSER A DISCESA RICORSIVA Tentare di usare una produzione significa consumare porzioni di input (terminali nella parte destra) e chiamare funzioni associate a non terminali.

Esempio: A ! aBcD

Abbiamo successo se e solo se •  il prossimo carattere in input è 'a',

•  la chiamata B restituisce successo,

•  il carattere successivo da leggere è 'c' e

•  la chiamata D restituisce successo

N.B. Produzioni del tipo A ! A" sono un problema

Nov

201

2 FI

2 - #

fi2sa

pien

za

19

int A(...) { /* par.: porzione di input da leggere */! /* prova la prima possibilità A ! "1 "2 … "n */! if ("1(...)) {! if (! "2()) Error(“Missing "2”);! if (! "3()) Error(“Missing "3”);! …! if (! "n()) Error(Missing "n”);! return SUCCESSO;! }! /* prova la seconda alternativa A ! #1 #2 … #mm*/! if (#1(...)) {! if (! #2()) Error(“Missing #2”);! if (! #3()) Error(“Missing #3”);! …! if (! #m()) Error(Missing #m”);! return SUCCESSO ;! }! return ERRORE;!}!

Nov

201

2 FI

2 - #

fi2sa

pien

za

20

Se ci sono due produzioni del tipo A ! "1 "2 … "n | #1 #2 … #m

Page 11: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

PARSER PREDITTIVI Provare tutte le possibili produzioni porta a programmi lenti

Supponi di dover espandere il non terminale A e di avere due produzioni del tipo

A ! "

A ! # Dobbiamo saper scegliere la produzione giusta sulla base dell’input ancora da esaminare

Se siamo in grado di fare questo otteniamo un parser predittivo che non ha bisogno di simulare il non determinismo

Nov

201

2 FI

2 - #

fi2sa

pien

za

21

ESEMPIO I linguaggi di programmazione sono spesso adatti al parsing predittivo Esempio stmt ::= id = exp ; | ! return exp ; | ! if ( exp ) stmt | ! while ( exp ) stmt !Se la prima parte dell’input da esaminare inizia con IF PARENTESI-SIN ID … allora dovremmo espandere stmt come un if-statement (terza produzione)

Nov

201

2 FI

2 - #

fi2sa

pien

za

22

Page 12: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

LL(K) PARSING •  parsing predittivo top-down, spesso a discesa ricorsiva

•  analizza l'input da sinistra (Left) a destra e costruisce una derivazione sinistra (Leftmost) della frase

•  usa il lookahead per scegliere la produzione

•  lookahead k significa che l'osservazione dei prossimi k token da leggere permette di decidere quale regola usare

•  LL parsing con lookahead k viene denotato LL(k)

•  in pratica: è rarissimo usare k > 1

•  i linguaggi CF per i quali è possibile effettuare parsing LL(1) sono un sottoinsieme proprio dei CF deterministici

Nov

201

2 FI

2 - #

fi2sa

pien

za

23

GRAMMATICHE LL(1) N

ov 2

012

FI2

- #fi2

sapi

enza

24

•  Data una produzione A ::= ", definiamo FIRST(") come l'insieme dei simboli terminali che possono essere all'inizio di "

•  Una grammatica è LL(1) se, per ogni simbolo non terminale A, e per ogni produzioni A ::= " e A ::= #, allora

FIRST(") " FIRST(#) = Ø

•  Se una grammatica è LL(1) allora possiamo costruire un parser predittivo esaminando un unico simbolo!

•  Infatti in questo caso dato A ! " | # possiamo decidere se applicare la prima o la seconda produzione esaminando se il simbolo di input in esame appartiene a FIRST(") o a FIRST(#)

•  In alternativa al termine FIRST è anche usato come sinonimo il termine STARTERS

NOTA: nel caso " ⇒* # sono necessarie delle precisazioni e la def. va completata; v. discussione su FOLLOW

Page 13: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

PARSING PER GRAMMATICHE LL(1) L’analisi di grammatiche LL(1)

• Spesso si realizza il parser iterativamente, usando una pila inizializzata con l'assioma

• Esamina l’input da sinistra a destra • Quando in cima alla pila abbiamo un simbolo non

terminale decide la produzione da applicare esaminando un simbolo dell’input

La possibilità di esaminare solo un simbolo è sufficiente nella maggioranza dei linguaggi di programmazione

Nov

201

2 FI

2 - #

fi2sa

pien

za

25

ESEMPIO: GRAMM. LL(1) PER ESPRESSIONI ARITMETICHE CON PARENTESI Consideriamo il caso (banale) di espressioni aritmetiche completamente parentetizzate:

espressione ! digit | ‘(‘espressione operatore espressione ‘)’

operatore ! ‘+’ | ‘*’ digit ! ‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ | ‘8’ | ‘9’

Esempio: ((3+5)*2) appartiene al linguaggio

3+5*2 o (3+5)*2 NON appartengono al linguaggio

Questa grammatica è LL(1)

Nov

201

2 FI

2 - #

fi2sa

pien

za

26

Page 14: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

ESEMPIO: GRAMMATICA NON LL(1)

S ! A c | B d

A ! a

B ! a

" First(")

a {a} c {c} d {d} A {a} B {a} S {a} Ac {a} Bd {a}

Nov

201

2 FI

2 - #

fi2sa

pien

za

27

PARSER TOP-DOWN EFFICIENTI •  Basati su automi

pushdown Deterministici

•  Riportano un errore appena l’input non è un prefisso di un programma valido

•  Non applicabili a tutte le grammatiche di tipo 2

generatore del parser

parser

Nov

201

2 FI

2 - #

fi2sa

pien

za

28

grammatica CF

grammatica ambigua

tokens albero di derivazione

Page 15: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

APPROCCIO IMPERATIVO •  Si può basare il parser su una tabella di parsing avente

|VN| linee e |VT| colonne

•  Ciascuna linea è associata a un non terminale, ciascuna colonna a un token

•  Nella casella (A, t) si inserisce la produzione A $ " se t $ SELECT (A $ ")

•  Caselle vuote corrispondono a errori sintattici

Nov

201

2 FI

2 - #

fi2sa

pien

za

29

UN SEMPLICE ESEMPIO

E $ ( E ) | id

( ) ID $ E E $ (E) E $ id

Nov

201

2 FI

2 - #

fi2sa

pien

za

30

Page 16: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

PARSER TOP-DOWN EFFICIENTI

•  Data una grammatica per stabilire se è LL(1) dobbiamo calcolare gli insiemi First()

•  Questa operazione è complicata nel caso di produzioni del tipo

A $ % (produzioni vuote) &

expr ::= term + expr ¦ term

(produzioni con ricorsione)

•  ll calcolo degli insiemi First nel caso generale è discusso nel seguito

generatore del parser

parser

Nov

201

2 FI

2 - #

fi2sa

pien

za

31

grammatica CF

grammatica ambigua

albero di derivazione

FIRST-SET Definizione

Data una grammatica CF G = (VT, VN, S, P) e una stringa (forma di frase) " ∈ V*, definiamo

FIRST(") = { t | (t ∈ VT " ⇒* t%) (t = # " ⇒* #) }

ove % ∈ V*

Calcolo di FIRST("), dapprima per terminali ed #

•  FIRST(a) = { a }, per ciascun terminale a

•  FIRST(#) = { # }

Nov

201

2 FI

2 - #

fi2sa

pien

za

32

Page 17: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

FIRST-SET PER NON TERMINALI Per ciascun non terminale A, calcoliamo FIRST(A) inizializzandolo all'insieme vuoto e poi considerando le produzioni su A Per ciascuna produzione A ! B1B2…Bk, ove Bi ∈ V, FIRST(A) = FIRST(A) ∪ (FIRST(B1) \ { # }) if(# ∈ FIRST(B1)) then FIRST(A) = FIRST(A) ∪ (FIRST(B2) \ { # }) if(# ∈ FIRST(B2)) then FIRST(A) = FIRST(A) ∪ (FIRST(B3) \ { # }) … if(# ∈ FIRST(Bk-1)) then FIRST(A) = FIRST(A) ∪ (FIRST(Bk) \ { # }) if(# ∈ FIRST(Bk)) then FIRST(A) = FIRST(A) ∪ { # } (stop al primo test che fallisce)

Nov

201

2 FI

2 - #

fi2sa

pien

za

33

ESEMPIO calcolare i FIRST-SET per i non terminali della seguente grammatica

<exp> $ <term> <exp'>

<exp&> $ ' <term> <exp&> | #

<term> $ <factor> <term&> <term&> $ / <factor> <term&> | #

<factor> $ INTLITERAL | ( <exp> )

Nov

201

2 FI

2 - #

fi2sa

pien

za

34

Page 18: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

FIRST-SET PER PARTI DESTRE DELLE PRODUZIONI

Calcolo di FIRST(") simile al calcolo di FIRST(A)

supp. " = B1B2…Bk, ove Bi ∈ V; FIRST(") = Ø

FIRST(") = FIRST(") ∪ (FIRST(B1) \ { # })

if(# ∈ FIRST(B1)) then FIRST(") = FIRST(") ∪ (FIRST(B2) \ { # }) if(# ∈ FIRST(B2)) then FIRST(") = FIRST(") ∪ (FIRST(B3) \ { # })

if(# ∈ FIRST(Bk-1)) then FIRST(") = FIRST(") ∪ (FIRST(Bk) \ { # })

if(# ∈ FIRST(Bk)) then FIRST(") = FIRST(") ∪ { # }

(stop al primo test che fallisce)

Nov

201

2 FI

2 - #

fi2sa

pien

za

35

LL(1) PARSER: PRIMO TENTATIVO 1.  Costruisci i FIRST-SET

2.  Se grammatica non LL(1) errore

3.  Procedi costruendo un parser predittivo a discesa ricorsiva

•  un metodo per ciascun non terminale A •  per ogni token t $ FIRST(") usa la regola A $ "

Problema: se # ∈ FIRST(") si possono "perdere" predizioni.

In pratica: il parser dovrebbe poter usare la produzione A $ " se # ∈ FIRST(") e il prossimo carattere in input appartiene all'insieme dei simboli che potrebbero seguire A

Nov

201

2 FI

2 - #

fi2sa

pien

za

36

Page 19: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

FOLLOW-SET Definizione Data una grammatica CF G = (VT, VN, S, P) e un non terminale A ∈ VN, definiamo FOLLOW(A) = { t | (t ∈ VT S ⇒+ "At%) (t = $ S ⇒+ (A) } ove (, % ∈ V* e $ denota la fine dell'input (talvolta si usa EOF in luogo di $)

Nov

201

2 FI

2 - #

fi2sa

pien

za

37

CALCOLO DI FOLLOW-SET

inizializzazione: FOLLOW(S) = { $ }, FOLLOW(A) = Ø per A ! S

per calcolare FOLLOW(B), B ∈ VN, individua le produzioni ove B compare nella parte destra

•  per ciascuna produzione X $ (B% FOLLOW(B) = FOLLOW(B) ∪ (FIRST(%) \ { # } )

•  se # ∈ FIRST(%) FOLLOW(B) = FOLLOW(B) ∪ FOLLOW(X)

•  per ciascuna produzione X $ (B FOLLOW(B) = FOLLOW(B) ∪ FOLLOW(X)

N.B. I FOLLOW-SET si calcolano solo per i non terminali

Nov

201

2 FI

2 - #

fi2sa

pien

za

38

Page 20: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

DEF. GR CF LL(1) Per ogni produzione A $ (, definiamo SELECT(A $ () come

•  FIRST(() U FOLLOW(A), se # ∈ FIRST(() [( si può annullare]

•  FIRST((), se # FIRST(() [( non si può annullare]

Definizione di grammatica CF LL(1)

Una grammatica CF è LL(1) se, per ogni coppia di produzioni sullo stesso non terminale A $ ( e A $ #,

SELECT(A $ ( ) " SELECT(A $ #) = Ø

Nov

201

2 FI

2 - #

fi2sa

pien

za

39

ESEMPIO "STATEMENTS"

GR LL(1)

stmt ::= id = exp ; | return exp ; | if ( exp ) stmt | while ( exp ) stmt

METODO

// parse stmt ::= id=exp; | …

void stmt( ) {

switch(nextToken) {

RETURN: returnStmt(); break;

IF: ifStmt(); break;

WHILE: whileStmt(); break;

ID: assignStmt(); break;

}

}

Nov

201

2 FI

2 - #

fi2sa

pien

za

40

Page 21: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

ESEMPIO (CONT)

WHILE // parse while (exp) stmt void whileStmt() {

// skip “while (” getNextToken();

getNextToken(); // parse condition

exp(); // skip “)”

getNextToken(); // parse stmt stmt();

}

RETURN

// parse return exp ; void returnStmt() {

// skip “return”

getNextToken();

// parse expression

exp();

// skip “;”

getNextToken();

}

Nov

201

2 FI

2 - #

fi2sa

pien

za

41

POSSIBILI PROBLEMI • Ricorsioni sinistre

•  es., E ! T| E + T | …

• Parti destre di produzioni sullo stesso non terminale aventi un prefisso comune

•  es., A ! aBC | aCD | …

Rendono le grammatiche non LL(1)!

Nov

201

2 FI

2 - #

fi2sa

pien

za

42

Page 22: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

RICORSIONE SINISTRA

PRODUZIONI

expr ::= expr + term

¦ term

CODICE (ERRATO!)

// parse expr ::= …

void expr() {

expr();

if (current token is PLUS) {

getNextToken();

term();

}

}

Nov

201

2 FI

2 - #

fi2sa

pien

za

43

TENTATIVO DI SOLUZIONE sostituire la ricorsione sinistra con una destra

expr ::= term + expr ¦ term

prefisso comune! (non LL(1))

Nov

201

2 FI

2 - #

fi2sa

pien

za

44

Page 23: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

RISOLUZIONE DI RICORSIONI SINISTRE Uso di ricorsione destra + nuovo non terminale

da expr ::= expr + term | term

a

expr ::= term exprtail exprtail ::= + term exprtail | )

codificabile direttamente!

Nov

201

2 FI

2 - #

fi2sa

pien

za

45

RISOLUZIONE DI RICORSIONI SINISTRE Produzioni del tipo A $ A" | %, ove % non inizia con A, costruiscono stringhe del tipo %""…" Sono generabili da A $ %A' A' $ "A' | #

Più in generale A $ A"1 | A"2 | … | A"r | %1 | %2 | … | %s

si risolvono con A $ %1A' | %2A' | … | %sA' A' $ "1A' | "2A' | … | "rA'| #

Nov

201

2 FI

2 - #

fi2sa

pien

za

46

Page 24: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

CODICE PER LE ESPRESSIONI (1)

// parse

// expr ::= term { + term }*

void expr() {

term();

while (next symbol is PLUS)

{

getNextToken();

term()

}

}

// parse

// term ::= factor { * factor }*

void term() {

factor();

while (next symbol is TIMES)

{

getNextToken();

factor()

}

}

Nov

201

2 FI

2 - #

fi2sa

pien

za

47

CODICE PER LE ESPRESSIONI (2)

// parse

// factor ::= int | id | ( expr )

void factor() {

switch(nextToken) {

case INT:

process int constant;

getNextToken();

break;

case ID: process identifier; getNextToken(); break; case LPAREN: getNextToken(); expr(); getNextToken(); } }

Nov

201

2 FI

2 - #

fi2sa

pien

za

48

Page 25: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

PREFISSI COMUNI Se esistono due produzioni sullo stesso non terminale con un prefisso comune

A $ " % | " *

si può usare la fattorizzazione

A $ " A'

A' $ % | *

Nov

201

2 FI

2 - #

fi2sa

pien

za

49

ESEMPIO ISTRUZIONE IF grammatica originale

ifStmt ::= if ( expr ) stmt | if ( expr ) stmt else stmt

grammatica fattorizzata

ifStmt ::= if ( expr ) stmt ifTail ifTail ::= else stmt | )

Nov

201

2 FI

2 - #

fi2sa

pien

za

50

Page 26: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

PARSING DI ISTRUZIONI IF

può essere più semplice codificare direttamente la regola "else assegnato all'ultimo if aperto"

// parse

// if (expr) stmt [ else stmt ]

void ifStmt() {

getNextToken();

getNextToken();

expr();

getNextToken();

stmt();

if (next symbol is ELSE) {

getNextToken();

stmt();

}

}

Nov

201

2 FI

2 - #

fi2sa

pien

za

51

LL(1) PARSING DEMO

appl

et h

ttp://

ag-k

aste

ns.u

ni-

pade

rbor

n.de

/lehr

e/m

ater

ial/u

ebi/

pars

dem

o/ll1

fram

e.ht

ml

Nov

201

2 FI

2 - #

fi2sa

pien

za

52

Page 27: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

PARSER PREDITTIVO PER ESPRESSIONI ARITMETICHE

1  E ! E + T 2  E ! T 5  T ! T * F 6  T ! F 5 F ! id 6 F ! (E)

Nov

201

2 FI

2 - #

fi2sa

pien

za

53

CALCOLO DEI FIRST-SET PER GRAMMATICA ESPRESSIONI

1  E ! E + T 2  E ! T 5  T ! T * F 6  T ! F 5 F ! id 6 F ! (E)

Modified First Sets First(F) = { id } First(F) = { id, ( } First(T) = { id, ( } First(E) = { id, ( } First(E+T) = { id, ( } First(T*F) = { id, ( }

Rule Select 1 { id, ( } 2 { id, ( } 3 { id, ( } 4 { id, ( } 5 { id } 6 { ( }

Nov

201

2 FI

2 - #

fi2sa

pien

za

54

Page 28: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

SELECT-SET PER GRAMMATICA ESPRESSIONI MODIFICATA

1  E ! T E’ 2  E’ ! % 3  E’ !+ T E’ 4  T ! F T’ 5  T’ ! % 6  T’ ! * F T’ 7  F ! id 8  F ! (E)

First-Sets First(F) = {id, (}

First(T) = {id, (}

First(E)={id, (}

First(E’) = {+}

First(T’) = {*}

First(T E’)= {id, (}

First(%) = {}

First(+ T E’) = {+}

First(F T) = {id, ( }

First(* F T’) = {*}

First(id) = {id}

First(( E )) = {(}

Rule Select 1 {id, (} 2 {$, )} 3 {+} 4 {id, (} 5 { +, ), $} 6 {*} 7 {id} 8 {(}

Follow-Sets Follow(E) = {$, )}

Follow(E’) = {$, )}

Follow(T) = {+, ), $}

Follow(T’)={+, ), $}

Follow(F) = {*, +, ), $}

Nov

201

2 FI

2 - #

fi2sa

pien

za

55

LL VS LR •  LL(1): si prende decisione sulla base di singolo non

terminale e prossimo token da leggere

•  LR(1): la decisione è basata sull'intero contesto sinistro (in pila) e sul prossimo token in input

•  LR(1) è più "potente" di LL(1), poiché permette di analizzare un insieme più grande di grammatiche (tutte le CF deterministiche)

•  Sono disponibili tool per generare automaticamente parser basati su tabelle di parsing, sia per LL che per LR

•  Ottimo tool per LR: bison •  Celebri tool per LL: ANTLR e JavaCC

Nov

201

2 FI

2 - #

fi2sa

pien

za

56

Page 29: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

TRATTAMENTO ERRORI SINTATTICI •  Riporta e localizza l’errore

•  Diagnosi dell’errore

•  Correzione dell’errore

•  Recupero del processo di analisi dall’errore per proseguire correttamente (e scoprire nuovi errori)

• Difficile: si possono individuare nuovi errori strani e non effettivi

Nov

201

2 FI

2 - #

fi2sa

pien

za

57

ESEMPIO N

ov 2

012

FI2

- #fi2

sapi

enza

58

a := a * ( b + c * d ;

Il simbolo “;” funziona da delimitatore e permette di continuare l’analisi

Page 30: ANALISI SINTATTICA - Dipartimento di Ingegneria ...fiii/materiale_common/modelli/... · alberi di derivazione Le grammatiche ambigue non sono adatte per i linguaggi di programmazione

CONCLUSIONI •  Grammatiche CF adatte a definire i linguaggi di

programmazione

•  Le ambiguità di una grammatica si possono spesso eliminare

•  Parser predittivi top-down sono scelta naturale e più semplice

• Funzionano con grammatiche in cui introduciamo altri vincoli

• Sono efficienti • Permettono il trattamento degli errori

Nov

201

2 FI

2 - #

fi2sa

pien

za

59