Modulo13 - Dipartimento di Ingegneria dell`Informazione

Transcript

Modulo13 - Dipartimento di Ingegneria dell`Informazione
Regole euristiche
L’approccio di traguardare un certo numero di simboli per prendere una decisione in merito alla
sostituzione della parte destra impone una trasformazione della grammatica mediante regole
euristiche.
1. Fattorizzazione sinistra per far sì che non si abbia un prefisso comune in due o più parti destre
! di regole associate allo stesso simbolo non terminale.
A " y v| y w
A " y A’
A’ " v | w
2. Eliminazione della ricorsione sinistra per evitare la generazione di cicli infiniti di !
generazione all’applicazione della derivazione canonica a sinistra
! E ! E + T ! E + T +T ! E + T + T + T !..................
Eliminazione della ricorsione sinistra
E " E + T | E - T | -T | T
T" T * F | F!
F" (E) | i
Una regola del tipo Y " Yx implica necessariamente l’esistenza di una regola
Y "v dove Y non è un prefisso di v. Ciò per far sì che il linguaggio generato sia non vuoto.
si ha allora:
Y " Yx!
Y"v
Y " v Y’
Y’ " x Y’
Y’ " #
E’ facile vedere come i due schemi generino lo stesso linguaggio
Y ! Yx !Y x x! Y x x x ! v x x x
Y ! vY’ !v x Y’ ! v x x Y’ ! v x x x
Esempio
Nella grammatica vista in precedenza esistono tre regole ricorsive a sinistra. Si ha perciò
E"E+T!
E "T
!!
!
!
!
T"T*F!
!!
T "F
!!
!
!!
!
!
E
! " E -T !
E
!! " -T !
!!
!
!!
!
pertanto:
!
!!
E
!! " E + T | E - T | -T | T !
T" T * F | F!
!
F" (E) | i !
!E " T E’
!E’ " + T E’!
! E’ " #
!
!
T " FT’
T’ " * F T’
T’ " #
E " - T E’
E’ " - T E’
E’ " #
E " T E’ | - T E’
E’ " + T E’ | - T E’ | #
T " F T’
T’ " *F T’ | #
F " (E) | i
Si osservi come la ricorsione sinistra sia stata cambiata in ricorsione destra
Grammatiche LL(1)
Una grammatica si dice LL(1) se la scelta per quale simbolo non terminale da espandere dipende
unicamente dal prossimo simbolo della stringa da riconoscere.
Per ricavare informazioni collegate ai simboli terminali che saranno presenti nelle stringhe si
opera una sorta di preprocessing della grammatica calcolando una volta per tutte le informazioni
necessarie.
Lo scopo di questo preprocessing è quello di ricavare due insiemi di simboli terminali
denominati FIRST e FOLLOW, costruite nel seguente modo.
1. Costruzione dell’insieme dei FIRST - data una generica stringa X $ V* l’insieme FIRST (X)
! comprende tutti i simboli terminali che sono prefissi di una qualsiasi stringa derivabile da X.
!!
FIRST (X) = { t | t $ VT e X !* t v con v $ V*}
2. Costruzione dell’insieme dei FOLLOW - dato un simbolo non terminale Y l’insieme dei !
FOLLOW (Y) comprende tutti i simboli terminali che possono seguire immediatamente Y
!
FOLLOW(Y) = { t | t $ VT e S!+ u Y t v con u, v $ V* }
Definizione dell’insieme dei FIRST
1. Se t $ VT allora FIRST (t) = {t}
2. Se X$ VN allora FIRST (X) = { t | t $ VT, X !+ t u, con u $ V* }
! per cui se siamo in presenza della regola
X " x | x ...... | x
1 2
n
! il FIRST di X è definito come FIRST (X) = %1n FIRST (x )
i
3. Se y = y y ,.....,y con y $ V
1 2
n
i
(a) Se y1 !+ # allora FIRST (y) = FIRST (y1)
+ # allora FIRST (y) = % k+1FIRST (y )
(b) Se y !+ # con i = 1,2,...k < n e y
1
i
i
k+1 !
n
+
(c) Se y ! # con i= 1,...,n allora FIRST (y) = %1 FIRST (y )
i
i
Costruzione dell’insieme dei FIRST
!E " T E’ | - T E’
E’ " + T E’ | - T E’ | #
!T " F T’
T’ " *F T’ | #
F " (E) | i
L’insieme dei FIRST (X) comprende tutti i simboli terminali che siano prefissi in una
stringa qualsiasi che sia derivabile da X.
si ha:
FIRST (E) = {-, (, i }!
FIRST (E’) = {+, -}
FIRST (T) = { (, i }
FIRST (T’) = { * }
FIRST (F) = { (, i }
per esempio
E ! - T E’
E ! T E’ ! F T’ E’ ! ( E ) T’ E’
E ! T E’ ! F T’ E’ ! i T’ E’
Costruzione dell’insieme dei FIRST cont.
Si costruisce un grafo i cui nodi sono rappresentati da tutti
i simboli terminali e non terminali della grammatica
Sia X, Y, W $ VN
t $ VT
u, v $ V*
gli archi del grafo sono costruiti secondo le seguenti due regole
R1 - per ogni regola della grammatica avente la struttura X " t u
&
si traccia l’arco X " t
E " T E’ | - T E’
E’ " + T E’ | - T E’ | #
!T " F T’
T’ " *F T’ | #
F " (E) | i
R2 - per ogni regola della grammatica avente la struttura X " Y u
&
si traccia l’arco X " Y
Ogni nodo relativo ad un simbolo terminale
R1 +
raggiungibile tramite un cammino a partire
R1
E
E’
da un simbolo non terminale farà parte dei
R1
FIRST di quel non terminale pertanto:
R2
-
T
F
(
R2 R1
T’
R1
)
i
R1
*
FIRST (E) = { -, (, i }!
FIRST (E’) = { +, - }
FIRST (T) = { (, i }
FIRST (T’) = { * }
FIRST (F) = { (, i }
1. Si osservi come il carattere ) non fa parte di alcun FIRST non essendo raggiunto da nessun non terminale
2. Si osservi che il grafo è aciclico in quanto non sono presenti regole ricorsive a sinistra
Costruzione dell’insieme dei Follow
E " T E’ | - T E’
E’ " + T E’ | - T E’ | #
T " F T’
T’ " *F T’ | #
F " (E) | i
Per evitare che alcuni insiemi siano vuoti si aggiunge per default il simbolo speciale $ che
demarca la fine della stringa da esaminare
Siccome l’insieme dei FOLLOW(Y) comprende tutti i simboli terminali t che possono seguire
immediatamente Y ovvero S !+ u Y t v si ha:
FOLLOW (E) = { $, )}
FOLLOW (E’) = { $, )}
FOLLOW (T) = { $, ),- , +}
FOLLOW (T’) = { $, ). -, +}
FOLLOW (F) = { $, ). -, +, *}
per esempio:
E ! T E’ ! F T’ E’ ! F * F T’E’ !F*FT’ ! F*F
! ( E ) *F ! (T E’) * F ! ( T ) *F !.... !
Costruzione dell’insieme dei Follow cont.
E " T E’ | - T E’
E’ " + T E’ | - T E’ | #
T " F T’
T’ " *F T’ | #
F " (E) | i
Si considera il grafo dell’insieme dei FIRST prima costruito, si
aggiungono ulteriori nodi per i soli simboli non terminali (questi ultimi
vengono indicati con un doppio rettangolo sul grafo e con X nelle regole
seguenti).
R1 -Si traccia l’arco S " $ per il simbolo iniziale S
R2 -Per ogni regola W " u X t v si traccia l’arco X " t
R2
R3 -Per ogni regola W " u X si traccia l’arco X " W
E
R4 -Per ogni regola W " u X Y1 , Y2 ..... Yn
con Y1 , Y2 ..... Yn !+ # Si tracciano gli archi
X "W , X" Y1 .... X" Yn
R3
E’
R4
)
R1
$
R4
Tutti i simboli terminali raggiungibili a partire da un simbolo
non terminale X fanno parte del FOLLOW di X, pertanto:
T
FOLLOW (E) = { $, )}
FOLLOW (E’) = { $, )}
FOLLOW (T) = { $, ),- , +}
FOLLOW (T’) = { $, ). -, +}
FOLLOW (F) = { $, ). -, +, *}
T’
R4
E’
R3
R4
Si osservi come per motivi grafici non è stata indicata una parte del
grafo dei FIRST in quanto non funzionale per il risultato finale.
T’
R4
F
+
R4
*
Condizioni LL(1)
Una grammatica si dice LL(1) se per ogni regola
!!
X " x1 | x2 | ...... | xn
xi $ V*
sono soddisfatte le seguenti condizioni
1. FIRST (xi) sono a due a due disgiunti
2. Esiste al più un solo xi !* # e se esiste deve verificarsi
!!
FIRST(X) ' FOLLOW (X) = (
Condizioni LL(1) cont.
1. FIRST (xi) sono a due a due disgiunti
!
ciò significa che dato un non terminale X non devono esistere due derivazioni
!
S !* u X v ! u ) v !* u z v
!
S !* u X v’ ! u )’ v’ !* u z’ v’
in cui ) * )’ e i primi caratteri di z v e z’v’ coincidono cioè
!!
FIRST (zv) = FIRST (z’v’)
oppure
z v = z’v’ = #
Es. la regola ricorsiva a sinistra E " E + T | T viola la condizione 1.
!
!
E ! E+T!T+T!* i +i
E ! E+T!E+ T+T!* i + i + i
mentre invece con
E " T E’
E’" +T E’ | #
Infatti
FIRST (i+i ) = FIRST (i+i+i) e nella
sequenza si ha che ) * )’
!!
si avrebbe
!
E ! TE’!T+ TE’!T+T!* i +i
!
E ! TE’!T+ TE’!T+T+TE’!* i + i + i
anche in questo caso FIRST (zv) = FIRST (z’v’) ma in ogni momento ) = )’
Condizioni LL(1) cont.
2. Esiste al più un solo x !* # e se esiste deve verificarsi FIRST(X) ' FOLLOW (X) = (
i
Es.
! S " if E then S S’ | a | b
!
! S’" else S | #
dove a, b sono espressioni aritmetiche o booleane
p, q sono espressioni booleane
& E"p|q
siccome: ! FIRST(S) = {if, a, b}, FIRST (S’) = {else}, FIRST (E) ={ p, q }
!!
FOLLOW(S) = {else, $}, FOLLOW(S’) ={else, $} , FOLLOW(E) ={then}
si ha che S’! #, ma gli insiemi FIRST(S’) ' FOLLOW(S’) *( per cui la grammatica è ambigua
Esercizio 1
data l’espressione if p then if q then a else b costruire i due alberi sintattici relativi e dire quale
albero corrisponde all’interpretazione corretta.
Esercizio 2
Scrivere una grammatica non ambigua equivalente a quella data.