Sei sulla pagina 1di 98

Esercizi di Linguaggi e Traduttori

Stefano Paraboschi, Pierluigi San Pietro

Dipartimento di Elettronica e Informazione


Politecnico di Milano

Contents

1 Denizione di grammatiche
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
1.10

Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizi proposti

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

2 Automi, linguaggi, espressioni regolari


2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8

Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizi proposti

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

3 Eliminazione ambiguita
3.1
3.2
3.3
3.4
3.5
3.6

Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizi proposti

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

4 Analisi discendente deterministica


4.1
4.2
4.3
4.4
4.5
4.6
4.7

Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizi proposti

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

2
3
4
5
6
9
9
11
11
12

13
13
14
14
17
19
21
24
24

25
25
27
28
29
33
33

34
34
37
39
43
45
46
49

5 Analisi sintattica ascendente


5.1
5.2
5.3
5.4
5.5

Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizi proposti

.
.
.
.
.

6 Traduzioni sintattiche
6.1
6.2
6.3
6.4
6.5

Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizi proposti

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

7 Grammatiche ad attributi
7.1
7.2
7.3
7.4
7.5
7.6
7.7
7.8
7.9
7.10
7.11

Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizio . . . . .
Esercizi proposti

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

50
50
55
59
62
64

65

65
67
70
71
72

72
72
74
75
79
79
81
83
85
86
92
94

1 Denizione di grammatiche
1.1 Esercizio
Scrivere la grammatica che de nisce il linguaggio L delle stringhe di alfabeto fa bg
in cui il numero di a e uguale al numero di b.

Soluzione 1.1

Sia x 2 L, con x 6= . Allora x pu o avere come primo carattere una a (cio e x = ay)
oppure una b (x = by). Nel caso in cui x = ay, nel susso y ci deve essere una b
in pi u delle a. Certamente deve esistere una b in y che divide y in due parti, u e v,
ciascuna delle quali contiene lo stesso numero di a e di b, cio e: x = ay = aubv, con
u v 2 L. Se x = by, allo stesso modo si ha che x = buav. Da queste considerazioni si
deriva facilmente la seguente grammatica:

G : S ! aSbS j bSaS j 
G e ambigua, come si comprende esaminado gli alberi di derivazione possibili per
la stringa abab.
La grammatica e gi a molto semplice e sembra dicilmente sempli cabile in modo
ulteriore, perlomeno rispetto al numero delle produzioni e dei simboli non terminali
utilizzati.
La grammatica non pu o essere sempli cata nemmeno rispetto al numero massimo
di non terminali presenti nelle parti destre delle produzioni: si pu o dimostrare infatti
che nessuna grammatica lineare e in grado di descrivere L (ricordiamo che una grammatica e detta lineare quando vi e al pi u un solo non terminale nelle parti destre delle
produzioni).
La grammatica data ha il vantaggio di essere compatta. Per costruire una grammatica LL(1) per lo stesso linguaggio si pu o far riferimento al modo di operare di un
riconoscitore a pila per il medesimo linguaggio. Il riconoscitore operer a confrontando
il carattere letto col carattere presente in cima alla pila. Se il carattere in cima alla
pila e diverso da quello letto, sulla pila verr a eseguita un'azione di pop, altrimenti (se
la pila e vuota o il carattere in cima alla pila e lo stesso) il carattere verr a posto in
cima alla pila. Il riconoscitore e un riconoscitore a pila vuota.
Dalla descrizione del riconoscitore e possibile costruire la seguente grammatica in
cui vengono rappresentati anche gli insiemi guida:
8
>< S ! aBS fag j bAS fbg j f.g
G = > A ! afag j bAAfbg
: B ! bfbg j aBB fag
0

1.2 Esercizio
Si de nisca una grammatica per il linguaggio D delle parentesi in cui il numero totale
delle parentesi aperte e dispari.
Esempi: (), ()()(), (()())()() sono in D, mentre ()(), (())()() non sono in D.

Soluzione 1.2

Il linguaggio D e noncontestuale, poich e si pu o ottenere per intersezione del linguaggio delle parentesi con il linguaggio regolare costituito da qualunque stringa in
f( )g in cui il numero di ( e dispari. Si potrebbe ottenere D applicando la classica
costruzione usata per dimostrare la chiusura dei noncontestuali per intersezione con
i regolari. La costruzione e tuttavia assai complessa e conviene quindi analizzare il
problema nel modo seguente.
Sia P il linguaggio, analogo a D, in cui il numero totale delle parentesi aperte
e pari. Le frasi di D possono allora essere caratterizzate induttivamente nel modo
seguente:
1. () 2 D
2. se p 2 P allora aggiungendo a p una coppia di parentesi esterne si ottiene una
frase di D: (p) 2 D
3. se p 2 P e d 2 D, allora dp e pd sono in D, poich e il numero delle parentesi
aperte in entrambi i casi e dispari.
Analogamente, si possono caratterizzare le frasi di P :
1.  2 P 
2. se d 2 D allora aggiungendo a d una coppia di parentesi esterne si ottiene una
frase di P : (d) 2 P 
3. se p1 p2 2 P e d1 d2 2 D, allora p1 p2 e d1d2 sono in P , poich e il numero delle
parentesi aperte in entrambi i casi e pari.
Si pu o convincersi (oppure dimostrare) che queste caratterizzazioni esauriscono
tutte le possibili stringhe di D e P . E a questo punto immediato ricavare una grammatica per D, in cui il nonterminale D rappresenta l'assioma:


! (P ) j PD j DP
G= D
P !  j (D) j PP j DD

La produzione D ! () e stata eliminata perch e inutile.


Si osservi che la seguente grammatica G , pi u semplice di G, non genera il linguaggio corretto:
0

n
G = S ! () j ((S )) j (S )S j S (S )
0

Infatti, G non riesce a generare stringhe, come ad esempio ()()(), costituite da un


numero dispari  3 di sottostringhe di D.
0

1.3 Esercizio
Si scriva la grammatica che caratterizza il linguaggio delle stringhe di alfabeto fa b cg
che non sono costituite da una stringa di a e b separata da una marca di centro c
dalla sua copia riessa :

L = :fucuR : u 2 fa bg g


Soluzione 1.3

Costruiamo dapprima la grammatica che riconosce il complemento del linguaggio


cercato, ovvero il linguaggio delle palindromi con marca di centro:

n
G = S ! aSa j bSb j c

Il complemento di un linguaggio libero non e in generale libero. In questo caso


per o il passaggio dal linguaggio al suo complemento risulta possibile. Osserviamo
che vi sono tre casi possibili in cui una stringa x 2 L, ciascuno corrispondente a una
dierente "violazione" rispetto al linguaggio delle palindromi:
1. in x non vi e nessuna c in posizione mediana (questo include anche il caso in
cui in x non vi sono c)
2. in x vi e almeno una c in posizione non mediana (questo include anche il caso
in cui vi siano due o pi u c)
3. in x vi sono almeno due caratteri distinti in posizione simmetrica.
La seguente grammatica G genera L.
0

8>
< S ! QSQ j  j a j b j QRc j cRQ j aRb j bRa
G = > R ! QR j 
: Q!ajbjc
Dal nonterminale Q si generano i caratteri a, b, e c, mentre da R si genera qualunque stringa in fa b cg . Per generare una frase a partire da S, occorre dapprima
applicare zero, una o pi u volte la produzione S ! QSQ, e poi applicare una delle
altre produzioni sulla forma di frase del tipo uSv, con j u j = j v j. Le produzioni
S !  j a j b permettono di generare le frasi corrispondenti al caso (1), le produzioni
S ! QRc j cRQ considerano il caso (2) (inserisono una c in posizione non centrale, e
0

completano la frase con una stringa di lunghezza qualunque,  1, a sinistra o destra


della c), mentre S ! aRb j bRa corrispondono al caso (3).
La grammatica e ambigua, in quanto una stringa in cui sono veri cate due o pi u
condizioni pu o essere generata in vari modi.
La seguente grammatica G" e invece non ambigua, in quanto riconosce la prima
condizione che si veri ca nella stringa (procedendo dall'esterno verso l'interno)
8
>< 1 : S ! aSa j bSb j A
G" = > 2 : A ! a j b j aBb j aBc j bBa j bBc j cBa j cBb j cBc j 
: 3 : B ! aB j bB j cB j 
L'alternativa (1) genera il linguaggio delle stringhe simmetriche di a e b con centro
A. La grammatica impone che venga utilizzata la produzione S ! A, la quale
introduce attraverso la (2) una "violazione" rispetto al linguaggio delle palindromi
con marca di centro. Le alternative (2) contengono tutte le possibili violazioni rispetto
al linguaggio delle palindromi. Dopo che il non terminale A e stato utilizzato, una
qualsiasi stringa composta di a, b e c pu o essere generata dalle alternative (3).
1.4 Esercizio
Scrivere una grammatica che individui il seguente linguaggio:

L1 = :fucu : u 2 fa bg g


Soluzione 1.4

Il linguaggio che si vuole de nire e rappresentato dall'insieme di stringhe che


veri cano almeno una delle seguenti tre condizioni:
 non vi e nessuna c in posizione mediana
 vi e almeno una c in posizione non mediana
 esiste almeno una posizione i della sottostringa prima della marca di centro
in cui vi sia il carattere a e nella posizione i dopo la marca di centro vi sia il
carattere b (o viceversa). La gura 1 rappresenta la situazione.
La seguente grammatica ambigua risolve il problema.
8
> S!W jX jZ
>> W ! QWQ j a j b j 
>> X ! QXQ j Rc j cR
><
AbR j BaR
G = > ZA !
>> ! QAQ j aRc
>> B ! QBQ j bRc
>> R ! QR j Q
: Q!ajbjc
6

Figure 1: Stringhe appartenenti a L1


Analizziamo il signi cato dei vari non terminali. Il non terminale Q pu o essere
sostituito dall'espressione regolare (a j b j c), mentre il non-terminale R rappresenta
l'espressione regolare (a j b j c)+. Da W si genera l'insieme delle stringhe in cui in
posizione mediana non compare il carattere c. Da X si genera l'insieme delle stringhe
in cui compare almeno una c in posizione non mediana. Il caso rimasto (un solo
carattere c che divide in due parti di lunghezza identica la stringa) e trattato dal non
terminale Z . Visto che interessa che le due stringhe siano dierenti, basta imporre che
in una posizione i vi sia un carattere a da una parte e un carattere b dall'altra. Queste
stringhe sono in eetti generate dal non terminale Z , il quale distingue i due sottocasi
in cui si ha un a nella prima parte e un b nella seconda (prima produzione) e il caso
contrario gestito dalla seconda produzione. La gura 2 rappresenta sinteticamente
l'albero sintattico corrispondente ad un esempio del primo caso. La grammatica e
ambigua, in quanto ad esempio da Z si possono derivare anche stringhe generabili a
partire da X .
Si pu o osservare come il linguaggio :L1 non risulti libero: questo dimostra come
la classe dei linguaggi liberi non sia chiusa rispetto all'operazione di complemento.
1.5 Esercizio
Scrivere una grammatica per il seguente linguaggio:

L2 = :fuu : u 2 fa bg g


Soluzione 1.5

Il linguaggio da de nire e quello delle stringhe di alfabeto fa bg che non possono


essere decomposte in due stringhe identiche che si ripetono. Le stringhe di lunghezza
dispari faranno parte di questo linguaggio. Possiamo associare all'assioma una prima
produzione che genera le stringhe di alfabeto fa bg di lunghezza dispari:

8
>< S ! D
G = > D ! QQD j Q
: Q!ajb

Si tratta ora di generare le stringhe di lunghezza pari in cui la sequenza dei primi
n=2 caratteri e diversa dalla sequenza degli ultimi n=2 caratteri. Questo corrisponde
7

S
Z
A
Q

b
Q

A
Q

R
Q

A
Q

R
Q

R
Q

Figure 2: Albero sintattico per una stringa di L1

S
A
Q

A
Q

B
Q

Figure 3: Albero sintattico per una stringa di L2


ad imporre che esista almeno un valore i 1  i  n=2, per cui il carattere in posizione
ii sia diverso dal carattere in posizione i + n=2, cioe c(i) 6= c(i + n=2).
L'espediente che si usa consiste nell'osservare che se si prendono due stringhe
S1 di lunghezza dispari n1 ed S2 di lunghezza dispari n2 e si costruisce la stringa
S = S1  S2 di lunghezza n = n1 + n2 , la distanza tra i due elementi centrali e pari a
d = (n1 ; 1)=2 + (n2 ; 1)=2 + 1 = n=2.
Le stringhe di lunghezza pari del linguaggio cercato si potranno perci o costruire
accostando una stringa di lunghezza 2i ; 1 con al centro il carattere a ad una stringa
di lunghezza n ; 2i +1 con al centro il carattere b. Scriviamo la grammatica completa:

8
>> S ! AB j BA j D
>< D ! QQD j Q
G = > A ! QAQ j a
>> B ! QBQ j b
: Q!ajb

In gura 3 e rappresentata una stringa di lunghezza pari del linguaggio con il


corrispondente albero sintattico. La stringa , correttamente, non e inclusa in L(G).
Il metodo qui descritto per generare L pu o essere applicato anche al linguaggio L1
dell'esercizio 1.4, permettendo di ottenere una grammatica di dimensioni inferiori a
quella presentata nella sua soluzione. Si lascia la costruzione di questa grammatica
per esercizio al lettore.

1.6 Esercizio
Si de nisca una grammatica per il seguente linguaggio:

L = :fuuR j u 2 fa bg g


Soluzione 1.6

Si osservi dapprima che tutte le stringhe di lunghezza dispari sono in L. Le


stringhe di lunghezza pari che sono in L contengono almeno una violazione rispetto al
linguaggio delle palindromi senza marca di centro: sono del tipo uaw1w2 buR o del tipo
ubw1w2auR , dove u w1 w2 2 fa bg e j w1 j=j w2 j. Di fatto, la sottostringa w1w2 e
una qualunque stringa di lunghezza pari. Se denotiamo allora con P un nonterminale
da cui si genera qualunque stringa di lunghezza pari, e con D un nonterminale da
cui si genera qualunque stringa di lunghezza dispari, una grammatica (in forma b.n.f.
estesa) per L pu o essere ricavata immediatamente:


8>
< S ! aSa j bSb j aPb j bPa j D
G = > P ! ((a
b)(a
b))
: D ! (a
b)P


Le due produzioni S ! aSa j bSb permettono di generare uSuR, mentre le produzioni S !j aPb j bPa introducono una violazione rispetto al linguaggio delle palindromi, consentendo di generare ad esempio uaPbuR, da cui si ricava una qualunque
frase del tipo uaw1w2bu.
La grammatica, scritta in forma non BNF estesa, non e ambigua.
Alla grammatica pu o essere data una forma ancora pi u compatta eliminando la
dierente gestione delle stringhe di lunghezza pari e lunghezza dispari: una stringa di
lunghezza dispari e infatti rappresentabile come uauR, ubuR, uawbuR o ubwauR (w e
una qualunque stringa di lunghezza dispari). Il risultato, in forma b.n.f. estesa, e:

n
G = S ! aSa j bSb j a(a
b) b j b(a
b) a j a j b


1.7 Esercizio
Si descriva una grammatica lineare a destra che genera il linguaggio

L = (a(ab
bb) (aa
c))+


Soluzione 1.7

Per de nire una grammatica conviene costruire prima il riconoscitore a stati niti
non-deterministico (rappresentato in gura 4, da cui e ricavabile l'insieme delle regole
della grammatica BNF.
10

a,b

a
D

Figure 4: Automa riconoscitore di L


Dall'analisi del riconoscitore si ricava la grammatica. Il linguaggio e rappresentato
dalle stringhe di caratteri che si possono ottenere partendo dallo stato A. Nella
grammatica comparir a la seguente produzione:

S!A
Le stringhe che vengono riconosciute nello stato A sono uguali alle stringhe che
vengono ottenute partendo dallo stato B precedute dal terminale a. Questa osservazione ci porta a scrivere la seconda regola della grammatica:
A ! aB
A sua volta le stringhe riconosciute a partire dallo stato B corrispondono alle
stringhe ottenute partendo dallo stato C precedute da a o b, oltre che le stringhe
accettate partendo dallo stato D precedute da a e le stringhe accettate partendo da
E precedute da c. Cos :
B ! aC j bC j aD j cE
Si pu o applicare lo stesso procedimento anche agli stati C e D ottenendo altre
due produzioni (in corrispondenza degli altri due non terminali C e D). E e invece
uno stato nale dell'automa riconoscitore. Una delle possibile stringhe riconosciute a
partire da E e la stringa vuota, che dovr a entrare a far parte delle alternative.
In conclusione si ottiene la seguente grammatica:

11

8 S!A
>>
>> A ! aB
< ! aC j bC j aD j cE
G=> B
> C ! bB
>>: D ! aE
E!Aj
La grammatica risulta del tipo 3 della classi cazione di Chomsky, ovvero lineare
a destra.
1.8 Esercizio
Rappresentare mediante una grammatica BNF-estesa le espressioni aritmetiche con
parentesi grae, quadre e tonde, ricordando che le parentesi grae possono contenere sia espressioni con parentesi quadre che tonde, mentre le parentesi quadre e
tonde possono contenere solo espressioni con parentesi tonde. Si rappresenti anche
la tradizionale gerachia tra gli operatori di addizione, sottrazione, moltiplicazione e
divisione.

Soluzione 1.8

Una soluzione possibile e la seguente:


Espr0 ! Add0 ( '+' Add0 j '-' Add0 )
Add0 ! Fatt0 ( '*' Fatt0 j '/' Fatt0)
Fatt0 ! Term j 'f' Espr1 'g' j '' Espr2 ']' j '(' Espr3 ')'


Espr1 ! Add1 ( '+' Add1 j '-' Add1 )


Add1 ! Fatt1 ( '*' Fatt1 j '/' Fatt1)
Fatt1 ! Term j '' Espr2 ']' j '(' Espr3 ')'


Espr2 ! Add2 ( '+' Add2 j '-' Add2 )


Add2 ! Fatt2 ( '*' Fatt2 j '/' Fatt2)
Fatt2 ! Term j '(' Espr3 ')'

Espr3 ! Add3 ( '+' Add3 j '-' Add3 )


Add3 ! Fatt3 ( '*' Fatt3 j '/' Fatt3)
Fatt3 ! Term j '(' Espr3 ')'

1.9 Esercizio
Il linguaggio L1 = fanbm anbm g non e noncontestuale. Provare che anche L2 = fuu j
u 2 fa bg g non e noncontestuale.


12

Soluzione 1.9

Se L2 fosse noncontestuale, anche L2 \ a b a b sarebbe noncontestuale, grazie alla


nota propriet a di chiusura dei linguaggi noncontestuali per intersezione con i linguaggi
regolari. Ma questo linguaggio e proprio L1 : assurdo.


1.10

Esercizi proposti

1.10.1 Esercizio

Si progetti una sintassi G per il linguaggio L di alfabeto ! = fa d ( ) g delle liste


a pi u livelli cos  de nite:
 una lista e sempre racchiusa tra le parentesi e contiene un numero pari non nullo
di componenti, separati dal delimitatore 'd'
 un componente e 'a' oppure una lista.
Ad es.:
(ada)
((ad(ada)dada)dadada)
Sono scorrette:
((ad(adada)da)dadada)
perch e la lista sottolineata ha un numero dispari di componenti.
0

0 0

1.10.2 Esercizio

E noto il linguaggio di Dyck di alfabeto fa cg, ovvero il linguaggio delle stringhe ben
parentetizzate, intendendo a come parentesi aperta e c come chiusa. Si consideri il
linguaggio L ottenuto da Dyck cancellando una sola lettera c in qualsiasi punto della
stringa.
Ad esempio ad L appartengono le frasi

aaacc . aacac .
ottenute dalla frase ben parentetizzata aacacc ..
Si scriva una sintassi G per L e se ne esamini l'ambiguit a.

1.10.3 Esercizio

L'operazione di mischia (k) mescola due stringhe x e y di alfabeto ! in tutti i modi


possibili, sempre rispettando l'ordinamento dei caratteri di ognuna delle stringhe.
Essa e cos  de nita:
13

x k y = fx1 y1x2 y2 : : : xn yn j x = x1 x2 : : : xn ^ y = y1y2 : : : yn n  1 xi yi 2 ! g




Ad es.: ab k c = fabc acb cabg ab k cd = fabcd acdb cdab cadb : : :g


La mischia di due linguaggi e l'insieme delle mischie delle loro stringhe:

L = L k L = fx k y j x 2 L y 2 L g
Si costruisca una grammatica G per il linguaggio L = L k L dove L = cd e
L = fanbn j n  0g.
Ad es. si hanno le frasi: c cd cdab cadb cadadbdbddd : : :
0

00

00

00

00

2 Automi, linguaggi, espressioni regolari


2.1 Esercizio
Per ciascuno dei seguenti linguaggi, de niti a parole, si trovi una espressione regolare
corrispondente:

1. Tutte le stringhe in f0 1g in cui ogni 0 ha un 1 immediatamente a destra.


2. Tutte le stringhe in f0 1g costituite esclusivamente da un numero pari ( 0)
di caratteri 0.
3. Tutte le stringhe in f0 1g che non hanno tre 0 consecutivi.
4. Tutte le stringhe in f0 1g in cui ogni coppia di 0 adiacenti compare prima di
una qualsiasi coppia di 1 adiacenti.
5. Tutte le stringhe in f0 1g in cui il numero di 0 e uguale al numero degli 1, e
nessun pre sso ha due 0 in piu degli 1 o due 1 in piu degli 0.


Soluzione 2.1
1.
2.
3.
4.
5.

(1
01)
(00)+
(1
01
001) (0
00
)
(1
)(0+1) 0 (1+0) 1
(10
01)+


14


a
0

2
a

Figure 5: Automa non-deterministico A1


2.2 Esercizio
E noto che il linguaggio L1 = fanbn j n  0g non e regolare. Dimostrare che anche
L2 = fanbncm dm j n m  0g non e regolare.

Soluzione 2.2

Per assurdo, sia L2 regolare. Allora, poiche i linguaggi regolari sono chiusi rispetto
all'intersezione, anche L2 \ (a b ) sarebbe regolare. Ma questo linguaggio e proprio
L1 . L'ipotesi che L2 sia regolare e pertanto scorretta.


2.3 Esercizio
Si calcoli l'espressione regolare del linguaggio de nito dall'automa A1 in gura 5, e si
trasformi l'automa in uno equivalente deterministico. Si minimizzi l'automa ottenuto.

Soluzione 2.3
Determinazione dell'espressione regolare

Per la determinazione dell'espressione regolare operiamo costruendo dapprima la


grammatica lineare a destra corrispondente all'automa, quindi calcolando l'espressione regolare a partire dalla grammatica risolvendo le equazioni corrispondenti.
La grammatica corrispondente all'automa e la seguente:

8>
>> S ! aA j aC
< A ! aB j bD
!Aj
>> BC !
S j bD
>:
D!Bj

Da questa grammatica e possibile derivare il seguente insieme di equazioni nelle


variabili A B C D ed S . Ogni variabile rappresenta un linguaggio regolare.
15

8
>> S = aA
aC
>< A = aB
bD

>> BC == SA

bD
>:
D =B

Si dimostra che questo tipo di equazioni, ricavati da una grammatica lineare destra, ammettono sempre una e una sola soluzione nello spazio dei linguaggi regolari.
La soluzione per il non terminale S rappresenta proprio il linguaggio cercato. Il procedimento da seguire per risolvere questi sistemi consiste nel ridurre, tramite sostituzioni
successive, il sistema a una o pi u equazioni del tipo:

X = 
X
dove  e una espressione regolare nei simboli terminali e nonterminali (diversi da
X stesso) e  e una espressione regolare nei soli simboli terminali. Questo tipo di
equazioni, infatti, e immediatamente risolubile ponendo

X :=  


. Gli eventuali simboli nonterminali in  sono facilmente eliminabili con ulteriori


sostituzioni successive.
Risolvendo il sistema dato nell'ordine D B A C ed in ne S si ottiene:

D=B
B =A

A = (a
b)A
a
b ) A = (a
b) (a
b) = (a
b)+
C = S
b(A
) = S
b(a
b)+
) = S
b(a
b)
S = a(a
b)+
aS
b(a
b)
) S = a (a(a
b)+
ab(a
b) ) = a+ (a
b) ((a
b)
b) =
= a+ (a
b)+ = a(a
b)+


L'espressione regolare cercata e quella ottenuta in corrispondenza dell'assioma del


linguaggio S , ovvero a(a
b)+. Si pu o ora veri care la correttezza della soluzione
analizzando l'automa originale.

Trasformazione nell'automa deterministico

Il risultato della trasformazione nell'automa deterministico e rappresentato in gura 6.

Minimizzazione dell'automa

L'automa pu o essere minimizzato applicando il classico procedimento di calcolo


delle classi di equivalenza degli stati.
Costruiamo la tabella di equivalenza:
16

b
0,1,3

1,2,4

0,1,2,3

1,2

Figure 6: Automa deterministico corrispondente

17

= {(0)}

={(0,1,3)}

a,b

= {(0,1,2,3),(1,2,4),(1,2)}

a,b

Figure 7: Automa deterministico minimo


0,1,3
0,1,2,3
1,2,4
1,2

X
X X
X X
X X
0 0,1,3 0,1,2,3 1,2,4
Quasi tutta la tabella viene riempita al primo passo, quando gli stati nali vengono
distinti dagli stati non nali. Gli stati f0g e f0 1 3g vengono poi distinti al passo
successivo, dopodiche la tabella non cambia.
Si distinguono perci o 3 classi di equivalenza negli stati. Si potr a derivare l'automa
minimo costituito da 3 stati, rappresentato in gura 7.
Si poteva facilmente ricavare l'automa deterministico minimo dall'espressione regolare ottenuta per S , a(a
b)+ .
2.4 Esercizio
Scrivere una espressione regolare per il linguaggio L:
 ! = fa bg
 L = linguaggio riconosciuto dall'automa nella gura 8, di cui si riporta qui
anche una rappresentazione tabellare:

18

a
q0

q1
a
a

b
a
a,b
q2

q3
b

Figure 8: Automa riconoscitore di L


Stato a
b
q0 q1 q3 q2
q1
q0
q2 q2 q1 q3
q3
q2 q2 q3
Stati nali q0 e q3.

Soluzione 2.4

Dall'automa di pu o derivare la grammatica BNF lineare a destra equivalente.


Si introduce un simbolo per ogni stato dell'automa riconoscitore, e l'assioma della
grammatica corrisponder a al simbolo dello stato iniziale. Ogni stato nale potr a
trasformarsi nella stringa .
Otteniamo:
8 S ! aA j aC j bB j 
>>
< A ! aS
>>: B ! aA j aB j bC
C ! aB j bB j bC j 
Questo insieme pu o essere trasformato nel seguente insieme di equazioni su variabili che rappresentano linguaggi regolari:
8
>> S = aA
aC
bB

< A = aS
>> B = aA
aB
bC
: C = (a
b)B
bC

19

Si sostituisce A:
8 A = aS
>>
< B = a2 S
aB
bC
>> C = (a
b)B
bC

: S = a2S
aC
bB

Si sostituisce B :
8 A = aS
>><
B = a (a2S
bC )
>> C = (a
b)a a2S
(a
b)a bC
bC

: S = a2S
aC
ba a2S
ba bC



Si sostituisce C :
8 A = aS
>>
< B = a (a2S
bC )
>> C = ((a
b)a b
b) ((a
b)a a2 S
)
: S = (a2
ba a2 )S
(a
ba b)((a
b)a b
b) ((a
b)a a2 S
((a
b)a b
b)
)


Si ottiene come risultato l'espressione regolare:

L = S = ((a2
ba a2 )
(a
ba b)((a
b)a b
b) ((a
b)a a2) (((a
b)a b
b)
)


2.5 Esercizio
Costruire il riconoscitore a stati niti del complemento di

L = (a(ab
bb) (aa
c))+


Soluzione 2.5

Il riconoscitore non deterministico del linguaggio L e rappresentato in gura 4.


Costruiamo dapprima il riconoscitore deterministico del linguaggio L, rappresentato
in gura 9.
Il riconoscitore del complemento si ottiene aggiungendo uno stato pozzo nale
(P in gura) con un autoanello etichettato con tutti i simboli dell'alfabeto, tramutando tutti gli stati nali del riconoscitore in stati intermedi e gli stati intermedi in
stati nali, aggiungendo ad ogni stato un arco uscente diretto verso lo stato pozzo
etichettato con i simboli non accettati dallo stato. Il risultato dell'applicazione di
questi passi al riconoscitore di gura 4 restituisce il riconoscitore del complemento
rappresentato in gura 10.
20

a
b
a

a
D

Figure 9: Automa deterministico riconoscitore di L

a
c

a
A

a
D

a
b

c
C

b,c

a,c

b,c

a,b,c

Figure 10: Automa deterministico riconoscitore del complemento di L

21

a,b

e"
a

a,b,c

a,b

Figure 11: Automi non-deterministici per e ed e


0

00

2.6 Esercizio
Si costruisca, spiegando il procedimento seguito, l'automa deterministico minimo che
riconosce il linguaggio de nito dalla espressione regolare estesa con il complemento:

e = :((a
b) aa(a
b) )(cc(a
b
c) )


Soluzione 2.6

Identi chiamo i due componenti e = ((a


b) aa(a
b) ) ed e = (cc(a
b
c) )
dell'espressione regolare e = :e  e (si ricorda che l'operatore di negazione (:) ha la
precedenza rispetto all'operatore di concatenazione ()).
Si possono dapprima de nire gli automi per il riconoscimento delle espressioni
regolari e ed e ( gura 11).
Si osserva che l'automa riconoscitore di e e gi a deterministico. Si pu o rendere
deterministico anche l'automa riconoscitore di e con una semplice trasformazione,
ottenendo l'automa rappresentato in gura 12.
Otteniamo quindi l'automa per riconoscere il complemento di e . Per questo, tutti
gli stati non- nali divengono nali e viceversa, e per ogni simbolo non riconosciuto
in uno stato del riconoscitore si crea un arco etichettato con quel simbolo che porta
dallo stato ad uno stato pozzo nale. Il risultato dell'applicazione di questo metodo
all'automa e e rappresentato in gura 13.
La concatenazione tra due linguaggi si ottiene aggiungendo un arco  che collega
tutti gli stati nali del riconoscitore del primo linguaggio con lo stato iniziale del
riconoscitore del secondo linguaggio ( gura 14). Riducendo poi il non-determinismo
si ottiene l'automa deterministico cercato ( gura 15).
0

00

00

00

00

22

e
a

a,b

Figure 12: Automa deterministico per e

e
c
a

b
c
a,b,c

a
c

a,b

Figure 13: Automa deterministico per :e

23

e.e"

c
a

c
a,b,c
a

c
c

a,b

a,b,c

Figure 14: Automa non-deterministico per :e  e


0

e.e"

a,b
a
a,b

a,b,c

a,b

Figure 15: Automa deterministico per :e  e


0

24

00

00

a,c
a

a
a

b,c
b,c
b

a,c

a,b,c
b

Figure 16: Automa deterministico per L


2.7 Esercizio
Scrivere una espressione regolare per il linguaggio L:

! = fa b cg
L e l'insieme delle stringhe che contengono (almeno) una sottostringa cc tra ogni
coppia di aa e di bb (aa e bb sono consecutive).
Ad es. baacccbbb, aaccbbcbb, aaccbbba, bbaaacccbbaa sono corrette, mentre aacbb,
aaccbbaacbb non lo sono.

Soluzione 2.7

Potendo utilizzare l'operatore di complemento, l'espressione regolare risulta la


seguente:

L = :((a
b
c) aa(c
)bb(a
b
c) )
Disegnamo l'automa riconoscitore del linguaggio L ( gura 16).
L'espressione regolare che descriva l'automa senza complemento si pu o ottenere
utilizzando il procedimento gi a visto che a partire dall'automa riconoscitore crea
dapprima la grammatica, e poi traduce la grammatica in un sistema di equazioni
su variabili che rappresentano espressioni regolari. La soluzione per l'espressione
regolare corrispondente all'assioma della grammatica de nisce il linguaggio cercato.


2.8

Esercizi proposti

2.8.1 Esercizio

Si scriva una espressione regolare per il linguaggio L di alfabeto fa b c dg cos  de nito. Ogni frase e una lista di uno o pi u termini, separati da un separatore.
25

Un termine e qualsiasi parola (non nulla) di alfabeto fa bg in cui non appaia


la sottostringa aa. Un separatore e qualsiasi parola (non nulla) di alfabeto fc dg,
iniziante e terminante per d, in cui il numero di c interposti tra due d consecutivi sia
dispari.
Es. validi: ababb, ababdabb, bbdcccdabdcdcdbb
Non validi: cdd, abc, aabca, abdccdb
Si costruisca inoltre l'automa riconoscitore di L.

2.8.2 Esercizio

Si costruiscano gli automi riconoscitori minimi dei linguaggi:

L1 = (( j 00)1 )


L2 = ((:L1 )11)+

2.8.3 Esercizio

Si consideri il linguaggio L di alfabeto ! = fa b #g in cui ogni frase e una lista


di parole di alfabeto fa bg separate dal #. Ogni parola deve soddisfare a una delle
seguenti condizioni:
 il numero delle a e pari e quello delle b e dispari
 il numero delle a e dispari e quello delle b e pari
Esempi di frasi: abbaa abbba#bab#a mentre sono scorrette abbaa# bab#ab.
Si costruisca un automa riconoscitore deterministico per L.

3 Eliminazione ambiguita
3.1 Esercizio
Costruire una grammatica non ambigua per il linguaggio L delle espressioni ben
parentetizzate su un alfabeto costituito da una sola coppia di parentesi e dal simbolo
terminale b. Esempio di espressione corretta: b()((b)(bbb)()).

Soluzione 3.1

La grammatica pi u ovvia per L e la seguente:

n
G = S ! SS j (S ) j b j 

26

Figure 17: Due alberi di derivazione distinti per la frase bbb della grammatica G
dell'esercizio 3.1.
La grammatica e per o ambigua. Ad esempio, la stringa bbb pu o essere generata
con le due seguenti derivazioni destre distinte:

S ) SS ) Sb ) SSb ) Sbb ) bbb


S ) SS ) SSS ) SSb ) Sbb ) bbb
che corrispondono ai due alberi in gura 17.
L'ambiguit a e determinata dalla presenza della regola S ! SS , che e ricorsiva sia
a sinistra che a destra. Si pu o dimostrare che ogni grammatica in cui compare una
regola del tipo X ! XX , con  2 (!
V ) , in cui X e de nito (vale a dire che X
pu o generare almeno una stringa di terminali) e raggiungibile da S , e ambigua. Una
possibile soluzione in questo caso e quella di modi care la grammatica G in questo
modo:


n
G1 = S ! bS j (S )S j 

Dimostriamo per induzione sulla lunghezza n delle frasi di L che nessuna frase
generata dalla grammatica G1 e ambigua, nell'ipotesi che G1 generi correttamente il
linguaggio L.
Il passo base (n = 0) e ovvio in quanto l'unico modo di generare la stringa nulla
e applicare la produzione S ! . Il passo induttivo si dimostra in base all'ipotesi
induttiva, per la quale ogni frase di lunghezza inferiore a n e non ambigua. Sia x
una frase di lunghezza n. Le frasi possono cominciare o con il carattere "b" o con il
carattere "(". Se x e del tipo "by", dove y e una frase, allora per ipotesi induttiva y
27

e una frase non ambigua, in quanto di lunghezza minore di n, cio e esiste una unica
derivazione sinistra S ) y. Quindi anche x non e ambigua poiche l'unico modo
per derivarla e derivare bS con il passo S ) bS e poi continuare con la derivazione
precedente da S , ottenendo S ) bS ) by. Se invece x e del tipo "(z", il primo passo
di derivazione deve applicare la regola S ) (S )S . Allora z = v)w, con v e w derivate
da S. Ma per ipotesi induttiva sia v che w non sono frasi ambigue e perci o non lo e
anche x = (z. Non ci sono altri casi possibili e la dimostrazione e quindi conclusa.
Sarebbe ora necessario dimostrare che la nuova grammatica G1 e equivalente a G,
ma in questo caso ci si pu o accontentare di una "evidenza intuitiva".


3.2 Esercizio
Trovare una forma non ambigua per la seguente grammatica:

8
>< S ! EF
G1 = > E ! bE j cE j 
: F ! cF j dF j 

Soluzione 3.2

Il linguaggio generato dalla grammatica G1 e costituito dall'insieme delle stringhe


di fb c dg in cui nessuna d e a sinistra di una b, che pu o essere anche rappresentato
con l'espressione regolare: (b
c)  (c
d) .
G1 e ambigua in quanto le c che seguono una b e precedono la prima d possono
essere generate sia dal nonterminale E che dal nonterminale F . Ad esempio, la frase
cc pu o essere generata con due derivazioni sinistre distinte:


S ) EF ) cEF ) ccEF ) ccE ) cc


S ) EF ) F ) cF ) ccF ) cc
Una soluzione per risolvere l'ambiguit a pu o essere quella di considerare due insiemi
di produzioni distinti, il primo per generare solo stringhe di b e di c, il secondo per
generare una stringa di b e di c seguita da una d e da un stringa di c e di d. Una
grammatica non ambigua per L(G1) e:

8
>< S ! E j EdF
G2 = > E ! bE j cE j 
: F ! cF j dF j 

28

3.3 Esercizio
Si considerino i due linguaggi L1 = b d e L2 = fbn dn j n  0g. Si trovi
una
S
grammatica non ambigua in forma b.n.f. estesa per L = L1  L2 e una per L1 L2.


Soluzione 3.3

Si pu o facilmente veri care che, date due grammatiche G1 e G2 , se L1 = L(G1 )


e L2 = L(G2), con L1 \ L2 6= , e si applica a G1 e a G2 il procedimento usuale
per la costruzione dell'unione di due grammatiche, la grammatica risultante e sempre
ambigua, anche quando il linguaggio non lo e. Qualora invece G1 e G2 non siano
ambigue e L1 \ L2 = , la grammatica unione non e mai ambigua. Un problema
analogo accade con la concatenazione, cio e per il linguaggio L1  L2 , con L1 \ L2 6= ,
quando  2 L1 o  2 L2 . In questo caso, tuttavia, la condizione che i due linguaggi
siano disgiunti e necessaria ma non suciente per garantire la non ambiguita della
grammatica ottenuta per concatenazione.
Siano G1 e G2 due grammatiche in forma b.n.f. estesa per L1 e L2 rispettivamente:

n
G1 = S ! b d
n
G2 = S ! bSd j 
Si pu o ricavare immediatamente per concatenazione una grammatica in forma
b.n.f. estesa per L = L1  L2 , rinominando con E l'assioma di G2:
(
bdE
G3 = SE !
! bEd j 
G3 e ambigua, in quanto una frase del tipo bm dm pu o essere ricavata con due alberi
sintattici distinti, corrispondenti alle due derivazioni seguenti:


S ) bm dmE ) bm dm
S ) E ) bEd ) : : : ) bm Edm ) bm dm
Per eliminare l'ambiguit a occorre distinguere le derivazioni di bm dm da quelle di
n
m
b d , con n 6= m. Una grammatica non ambigua in forma b.n.f. estesa e la seguente,
in cui dal nonterminale E si derivano solo stringhe del tipo bm dm, con m > 0, mentre
dal nonterminale D si derivano solo stringhe del tipo bn dm, con n 6= m.
8>
j E j EE j D j  j b+ j d+
< S ! DE
G4 = > D ! b+E j Ed+
: E ! bEd j bd
Le produzioni per il nonterminale S si giusti cano subito notando che da S occorre
potere derivare stringhe del tipo bndnbm dm (S ! EE ) , del tipo bndm bk dk con n 6= m
29

(S ! DE ), del tipo bm dm, con m > 0 (S ! E ), del tipo bn dm con n 6= m (S ! D),


e in ne dei tipi b e d .
La de nizione di una grammatica non ambigua per L1 S L2 e ora immediata:


8
>< S ! E j D j  j b+ j d+
G5 = > D ! b+E j Ed+
: E ! bEd j bd
Tuttavia, essendo L2 incluso in L1 , in questo caso L1 S L2 e semplicemente L1 ,
cio e la grammatica G1 va bene anche per l'unione.
3.4 Esercizio
Costruire una grammatica non ambigua per le espressioni booleane, con la possibilit a
di parentesi, nelle variabili p q r e negli operatori not or and. La grammatica deve
rispettare la precedenza degli operatori, che hanno le seguenti priorit a: 3 per not, 2
per and, 1 per or. Si vuole inoltre che or sia associativo a destra, and sia associativo
a sinistra. Si dia anche una versione della grammatica in forma bnf estesa, che
mantenga, qualora possibile, la priorit a e l'associativit a degli operatori.

Soluzione 3.4

Consideriamo per ora solo la generazione di espressioni senza parentesi, che sono
comunque frasi del linguaggio in quanto le parentesi sono opzionali.
Una grammatica ambigua e che non rispetta le precedenze e l'associativit a pu o
essere ricavata immediatamente:

n
G0 = S ! S and S j S or S j not S j p j q j r

L'ambiguit a deriva dalle regole ricorsive a sinistra e a destra, che devono essere
eliminate. In questo caso, il modo pi u semplice per costruire una grammatica non
ambigua e quello di eliminare, ad esempio, le ricorsioni sinistre dalle regole ricorsive
a sinistra e a destra, introducendo opportuni simboli non terminali. Il risultato e la
seguente grammatica non ambigua (ma che ancora non rispetta le precedenze):

A or S j A and S j not S j A
G1 = SA !
!pjqjr
Le grammatiche per generare espressioni sono di solito chiamate "grammatiche ad
operatori", e possono essere cos  caratterizzate:
 alcuni terminali sono detti operatori
 alcuni non terminali sono detti oggetti
 ci pu o essere al pi u un operatore nella parte destra di ogni regola

30

and

or

or

and

A
q

S
A

r
p or q and r
(interpretato come p or (q and r))

p and q or r
(interpretato come p and (q or r))

Figure 18: Due alberi di derivazione per la grammatica G1 dell'esercizio 3.4. Nell'albero di sinistra and cede la precedenza a or, mentre in quello di destra or cede la
precedenza a and.
 gli operatori possono comparire solo in regole la cui parte sinistra e un oggetto
e in cui vi e almeno un oggetto nella parte destra.

Gli operatori di G1 sono i simboli not and or, mentre gli oggetti sono i nonterminali S e A.
La precedenza tra operatori pu o essere de nita, per un albero di derivazione di
una frase, in questo modo: l'operatore b cede la precedenza all'operatore a se c' e un
cammino verso l'alto nell'albero da a no al nodo che e immediatamente al di sopra
di b (cio e contiene l'oggetto da cui si e derivato b).
Intuitivamente, se un operatore ha la precedenza sull'altro, agisce sui propri operandi prima che il secondo operatore agisca sui propri operandi, in quanto si trova a
un livello piu basso nell'albero di derivazione.
L'ordine di precedenza degli operatori e un concetto di tipo semantico, in quanto
riguarda la valutazione delle espressioni. Poiche per o lo scopo delle grammatiche a
operatori e quello di fornire un ausilio agli analizzatori, tramite la costruzione dell'albero sintattico di una frase, e conveniente che la precedenza abbia un corrispondente
nella sintassi, in modo da sempli care l'elaborazione di tipo semantico.
La grammatica G1 implementa una precedenza da sinistra a destra: gli operatori
in una frase cedono la precedenza agli operatori che stanno alla loro destra. Si vedano
ad esempio gli alberi di gura 18.
Per implementare le priorit a pre ssate per ciascun operatore, richieste dal testo
dell'esercizio, occorre modi care la grammatica precedente, distinguendo un oggetto
per ogni operatore e de nendo le produzioni in ordine inverso rispetto alla priorit a.
L'operatore a priorit a inferiore, cioe l'or, e cos  generato sempre ai livelli pi u alti
dell'albero. In questo modo non pu o mai succedere che un or sia generato in un nodo
31

or

S
D

and

D
C

C
not C

p
A
q

A
r

p and q or not r
interpretata come (p and q) or (not r)

Figure 19: Albero di derivazione per la grammatica G3 dell'esercizio 3.4.


di un albero di derivazione che sta al di sotto di un qualunque nodo con un and.

8> S ! D or S j D
>< D ! C and D j C
G2 = > C ! not C j A
>:
A!pjqjr
Ad esempio, la frase p and q or not r ha l'albero di derivazione di gura 19.
Si dice che l'operatore a e associativo a sinistra in un albero di derivazione se
ogni a cede sempre la precedenza agli a che stanno alla sua sinistra. L'operatore a
e associativo a destra se ogni a cede sempre la precedenza agli a che stanno alla sua

destra.
La grammatica G2 non implementa la richiesta associativit a degli operatori. L'associativit a e infatti destra per tutti gli operatori, cio e la frase p and q and r e generata
come se fosse p and (q and r).
Per avere l'associativit a a sinistra per and e a destra per or basta introdurre la
regola D ! D and C al posto della regola D ! C and D.
Introduciamo ora le parentesi nelle espressioni, facendo attenzione a non rendere
ambigua la grammatica. Il metodo corretto e quello di aggiungere la regola A !
(S ), che consente di espandere i nodi a livello pi u basso (marcati con A) con una
espressione tra parentesi oltre che con le variabili p q r. Il risultato nale e la seguente
grammatica G3 , di cui alcuni esempi di derivazioni sono mostrati in gura 20.

32

or

D
D

C
A

or

and
C

and

S
A

A
p

and

C
r
A

p
r

p
D

and

p or q or r
interpretata come p or (q or r)

p and q and r
interpretata come (p and q) and r

p and (q and r)

Figure 20: Alberi di derivazione per la grammatica G3 dell'esercizio 3.4.

8> S ! D or S j D
>< D ! D and C j C
G3 = > C ! not C j A
>:
A ! p j q j r j (S )
La grammatica pu o essere riscritta nella seguente forma b.n.f. estesa:

8> S ! D (or D)
>< D ! C (and C )
G4 = > C ! not C j A
:> A ! p j q j r j ( S )


La precedenza fra operatori e mantenuta dalla G4. Si pu o ritenere che l'associativit a non abbia pi u molto senso, in quanto ad esempio una frase come porqorr viene
generata in questo modo: S ) DorDor )+ porqorr: gli or sono generati di fatto
alla stessa altezza nell'albero sintattico. Tuttavia, nella costruzione di analizzatori
semantici di tipo discendente per grammatiche di questo tipo, la generazione e la
33

valutazione avvengono da sinistra verso destra, cio e in un modo che realizza naturalmente una associativit a sinistra. In realt a, non e dicile modi care l'analizzatore
per ottenere una associativit a destra, ad esempio usando una pila per memorizzare i
valori associati ai terminali.
Si osservi in ne che per questo esercizio, dal punto di vista semantico, e irrilevante
quale sia la associativit a dell'operatore or, che era stata richiesta solo allo scopo di
de nire il concetto relativo per le grammatiche a operatori.
3.5 Esercizio
Rendere non ambigua la grammatica G:

8
>< S ! aSb j C
G = > C ! aD j 
: D ! bC

Soluzione 3.5

La grammatica individua il linguaggio (non regolare):


fan (ab) bn j n  0g
Per frasi del tipo anabbn vi e un'ambiguit a su quale derivazione e stata eettivamente seguita. Cos  alla stringa aabb corrispondono le due derivazioni S ! aSb !
aaSbb ! aaCbb ! aabb e S ! aSb ! aCb ! aaDb ! aabCb ! aabb.
Per evitare questo caso bisogna modi care la grammatica di partenza accedendo
alle produzioni dei non-terminali C e D solo quando si presenta eettivamente una
sequenza di ab innestati di lunghezza pari almeno a 2. Una soluzione e oerta dalla
seguente grammatica, in cui si sono anche sempli cate le produzioni da C e D:


aSb j aababCb j 
G = SC !
! abC j 
0

3.6

Esercizi proposti

3.6.1 Esercizio

Data la grammatica:

8 S ! aA j A j Bb j B
>>
< ! C j Bb
G=> B
! aCb j 
:> CA !
aA j C
si determini se G e ambigua e si descriva in termini insiemistici il linguaggio L(G).
34

3.6.2 Esercizio
Mostrare che le seguenti grammatiche sono ambigue e trovare per ciascuna una forma
non ambigua equivalente.

aST j 
G1 = ST !
! aT j a

aS j aSb j T
G2 = ST !
! aTa j a

8
>< S ! TUTU
G3 = > T ! aT j bT j 
: U ! bU j cU
8>
< S ! bS j Sd j EF
G4 = > E ! bEc j bc
: F ! cFd j cd

4 Analisi discendente deterministica


4.1 Esercizio
Si de niscano mediante una grammatica il linguaggio L = fanbpcq j n  0 ^ n = p + qg
e il linguaggio L1 = LR (linguaggio speculare).
Si veri chi se tale grammatiche risultino LL(1), e in caso aermativo se ne costruisca
l'analizzatore a discesa ricorsiva e l'automa a pila riconoscitore.

Soluzione 4.1

Una grammatica non ambigua G per L e la seguente:

aSc j T
G = ST !
! aTb j 
Una derivazione e ad esempio:

S ) aSc ) aaSc ) aaaTbcc ) aaabcc


.

Calcolo insiemi guida per L: G (A ! ) =

35

I () Sse  non genera 


I () S (A) se  ) 


con

I () = fa 2 ! j  ) a g


S (A) = fa 2 ! j S ) Aa g


Pertanto:
G (S ! aSc) = I (aSc) = fag

G (S ! T ) = I (T ) S (S ) = fag
fcg

I due insiemi guida non sono disgiunti e quindi la grammatica non e LL(1).
Ci si potrebbe domandare se una grammatica LL(1) possa esistere per L. La
risposta e negativa, anche se L e certamente un linguaggio deterministico ( e facile
costruire un automa a pila deterministico con tre soli stati che riconosce L). Infatti,
quando si legge una a la conoscenza del carattere successivo non basta per stabilire
la ripartizione delle b e delle c. E anzi facile intuire che la grammatica non e LL(k)
per nessun k.
Una grammatica per L1 = LR si ottiene immmediatamente da quella di L:

cSa j T
G1 = ST !
! bTa j 
Verichiamo che G1 e LL(1).
Calcolo insiemi guida per L1 :
G (S ! cSa) = I (cSa) = fcg

G (S ! T ) = I (T ) S (S ) = fbg
fag = fa bg
G (T ! bTa) = I (bTa) = fbg
G (T ! ) = S (T ) = fag

G1 e LL(1) in quanto gli insiemi guida delle produzioni con la stessa parte sinistra
sono disgiunti.
Costruiamo ora l'analizzatore a discesa ricorsiva per G1.

36

procedure S
if cc 2 fcg then cc:= PROSSIMO /* S ! cSa */
S
if cc 6= a then ERRORE else cc := PROSSIMO endif
elsif cc 2 fa bg then T /* S ! T */
else ERRORE
endif
end S
0

procedure T
if cc 2 fbg then cc:= PROSSIMO /* T ! bTa */
T
if cc 6= a then ERRORE else cc := PROSSIMO endif
elsif cc 2 fag then return /* T !  */
else ERRORE
endif
end T
0

Automa a pila deterministico LL(1), riconoscitore per L1


L'alfabeto della pila e costituito dall'unione dell'alfabeto terminale e nonterminale
della grammatica. S e il simbolo iniziale della pila. L'automa ad ogni mossa estrae il
simbolo in cima alla pila e, se esplicitamente speci cato, avanza la testina di lettura
del nastro di ingresso. L'automa riconosce a pila vuota, vale a dire quando non ci
sono pi u simboli sulla pila e sul nastro di ingresso. L'automa si arresta senza accettare
quando si trova in una con gurazione da cui nessuna mossa e possibile (ad esempio, T
sulla pila e c in ingresso). La mossa push() corrisponde a eseguire una pop dalla pila
non seguita da una push. La mossa avanza esegue una pop e consuma un simbolo in
ingresso, senza eseguire una push.
Cima
Carattere di ingresso
Pila
a
b
c
S push(T ) push(T ) push(aSc)
T
push() push(aTb)
a
avanza
b
avanza
c
avanza
Esempio di esecuzione sulla stringa ccbbaaaa:
(S ccbbaaaa) ` (aSc ccbbaaaa) ` (aS cbbaaaa) ` (aaSc cbbaaaa) `
(aaS bbaaaa) ` (aaT bbaaaa) ` (aaaTb bbaaaa) ` (aaaT baaaa) `
(aaaaTb baaaa) ` (aaaaT aaaa) ` (aaaa aaaa) ` (aaa aaa) `
(aa aa) ` (a a) ` ( ) accetta

37

4.2 Esercizio
Si calcolino gli insiemi guida per le produzioni della seguente grammatica:
8
>> S ! XY
>< X ! aT j TT
G = T ! b j TX j 
>> Y ! c j XY j ZX
>: Z ! dZ j e

Soluzione 4.2

Per potere eettuare il calcolo in modo sistematico sulla grammatica data, conviene dapprima de nire un insieme di regole generali, applicabili a qualunque grammatica libera.
Sia G una grammatica con tutti i nonterminali de niti e raggiungibili. De niamo
l'insieme degli inizi I (x) per un qualunque  2 (VN
VT ) .
Se x 2 VT , allora
I (x) = fxg
Se x = X , X 2 VN e X !  j  j : : : j ! sono tutte e sole le produzioni di x,
allora
I (X ) = I ()
: : :
I (! )
Se x = X1 : : : Xn, Xi 2 (VN
VT ), con 1  i  n, allora

I (X1 : : : Xn ) = fI (Xi ) j 1  i  n X1 : : : Xi 1 ) g
In questo modo e possibile costruire un sistema di equazioni, le cui incognite sono
gli insiemi degli inizi per ogni nonterminale.
Per la grammatica dell'esercizio, una volta notato che S X Y T sono tutti e soli i
nonterminali da cui si pu o derivare , si ottiene facilmente il seguente sistema, in cui
X sta per I (X ).
8
>> S = X
Y
>< X = a
T
>> TY == bc

TX

XY
Z
>:
Z =d
e
La soluzione di un sistema di questo tipo si pu o facilmente ottenere per sostituzioni
successive e applicando la legge di assorbimento: se vale l'equazione:
W =W
E
dove E e una qualunque espressione di unione di variabili e insiemi regolari, allora
vale l'equazione:
W =E


38

Si noti che in particolare se l'equazione e ridotta al caso degenere W = W , allora vale


l'equazione W = .
Ad esempio, nel sistema precedente si possono sostituire le espressioni X = a
T
e Z = d
e, ottenendo:

8
>> S = X
Y
>< X = a
T
>> TY == bc

TX

aY

Td=
be
a
>:
Z =d
e

da cui si ricava:
8
>> S = X
Y
>< X = a
T = a
b
>> TY == bc

aX
Y
d
e = a
b
c
d
e
>:
Z =d
e
da cui anche S = a
b
c
d
e.
Dal punto di vista teorico, l'esistenza della soluzione cercata e garantita dai classici teoremi di punto sso. La trasformazione individuata dal sistema e monotona e
continua nell'alfabeto terminale e quindi il sistema ammette un unico minimo punto
sso, che costituisce proprio la soluzione cercata. Dalla monotonia della trasformazione deriva immediatamente la validit a della legge di assorbimento e la garanzia
dell'esistenza della soluzione procedendo opportunamente per applicazioni successive
della sostituzione e dell'assorbimento.
Relazioni analoghe a quelle per gli insiemi degli inizi esistono anche per gli insiemi
dei seguiti. In particolare:
Se X 2 VN e Y1 ! 1 X1, Y2 ! 2 X2, : : :, Yn ! nXn sono tutte e sole le
produzioni di G in cui X compare nella parte destra, allora l'insieme S (X ) dei seguiti
e:

S (X ) = fI (i )g
fS (Yi ) j i ) g
Il risultato dell'applicazione di queste regole e un sistema di equazioni, dello stesso
tipo di quelle viste per calcolare l'insieme degli inizi. Il sistema pu o essere risolto in
base al metodo appena visto. L'insieme guida si pu o calcolare come al solito, una
volta veri cato anche quali nonterminali sono annullabili.
Ad esempio, per la grammatica data nel testo dell'esercizio il sistema e:

39

8
>> S (S ) =.
>< S (X ) = S (T )
S (Y )
I (Y )
>> SS ((TY )) == IS((XS ))
I (T )
S (X )
S (T )
>:
S (Z ) = I (X )
S (Y )
La soluzione del sistema pu o essere realizzata sfruttando i valori gi a calcolati per
gli insiemi degli inizi e sfruttando il fatto che S (S ) =. per ottenere che S (Y ) =.,
S (Z ) = a
b
., da cui, sostituendo S (X ) in S (T ) si ricava:
S (T ) = I (X )
I (T )
S (T )
S (Y )
I (Y )
S (T )
da cui per assorbimento si deduce che:
S (T ) = a
b
c
d
e
.= S (X )
E ora possibile ricavare gli insiemi guida delle varie produzioni, che riportiamo di
seguito.

8
>> S ! XY fa
b
c
d
e
.g
>< X ! aT fag j TT fa
b
c
d
e
.g
G = > T ! bfbg j TX fa
b
c
d
e
.g j fa
b
c
d
e
.g
>> Y ! cfcg j XY fa
b
c
d
e
.g j ZX fd eg
: Z ! dZ fdg j efeg

La grammatica non e pertanto LL(1).


4.3 Esercizio
Si de nisca mediante una grammatica BNF estesa un minilinguaggio di programmazione. Le caratteristiche del linguaggio sono le seguenti:
 Un programma inizia con la parola chiave prog e termina con la parola chiave
endprog
 un programma e costituito da una o pi u dichiarazioni di procedura
 ogni procedura e preceduta dalla parola chiave procedure, seguita da un nome
e da una dichiarazione di zero, uno o pi u parametri
 ogni procedura contiene anche un corpo, individuato dalla coppia begin : : : end
 non si possono annidare le dichiarazioni di procedura
 il corpo di una procedura pu o essere costituito da vari blocchi annidati

40

 un blocco inizia con un begin e termina con un end e pu o contenere, subito


dopo il begin, zero o pi u dichiarazioni di variabili
 ogni blocco pu o contenere delle istruzioni call, seguite dal nome di una procedura e da una lista di parametri attuali
 le variabili e i parametri formali possono essere solo di tipo integer o real
 si possono usare costanti numeriche come parametri attuali.

Esempio:
prog
procedure P1 (I1, I2: integer F3:real)
begin
XYZ: real
w,v:integer
call P2
begin
call P1(3, 5, 7.4)
end
end
procedure P2
begin
end
endprog

Si progetti almeno in parte l'analizzatore sintattico a discesa ricorsiva.

Soluzione 4.3

Una grammatica BNF estesa per il linguaggio e:

8>
+
>> program ! prog(procedureDeclaration" ") endprog
>> procedureDeclaration ! procedurepId(formalParameters j )"+ "block
>> formalParameters ! "("(fId(" "fId) " : "(integer j real)" ") ")"
>> block ! begin(varDeclaration j )(phrase" ") end
< varDeclaration ! (vId(" "vId) " : "(integer j real)" ")+
>> phrase ! (callpId(actualParameters j )) j block
>> actualParameters ! "("(aId(" "aId) )")"
>> aId ! identifier j constant
>> fId ! identifier
>: pId ! identifier
I simboli identifier e constant individuano rispettivamente i generici identi catori


alfanumerici e le costanti numeriche, ricavati da un opportuno analizzatore lessicale.


41

program
prog

procedureDeclaration

endprog

procedureDeclaration

pId

procedure

formalParameters

block

formalParameters
(

fId

fId

integer

real

Figure 21: Alcuni diagrammi sintattici corrispondenti alla grammatica dell'esercizio 4.3.

42

La gura 21 mostra i diagrammi sintattici corrispondenti ad alcune delle dichiarazioni BNF estese della grammatica.
Costruiamo ora le procedure sintattiche relative ai non terminali program e block.
La regola per program soddisfa la condizione di determinismo
LL(1) per la sintassi
T
BNF estesa, in Tquanto G (procedureDeclaration  ) S ((procedureDeclaration  )+)
= fprocedureg fendprogg = .
Se si suppone che la variabile cc contenga identi catori invece di un singolo carattere (come lecito aspettarsi se si usa un opportuno analizzatore lessicale), la procedura
sintattica per program e:
0 0

0 0

procedure program
if cc = prog then cc:=PROSSIMO else ERRORE endif
if cc 2 fprocedureg then repeat
procedureDeclaration
if cc 6=  then ERRORE
else cc := PROSSIMO
endif
until cc 62 fprocedureg
if cc 6= endprog then ERRORE
else cc := PROSSIMO
endif
else ERRORE
endif
end program
0

0 0

La regola per block soddisfa la condizione di determinismo LL(1) per la sintassi


BNF estesa, in quanto:
 per la sottoespressione (varDeclaration j ) si ha:
T
T
G (varDeclaration) G () = vId fend call beging = , poiche end cal begin
sono parole riservate che non possono essere usate per gli identi catori (in caso
contrario, verrebbe segnalato un errore in quanto l'analizzatore lessicale non
restituirebbe una variabile)
 per la sottoespressione (phrase" ") si ha:
G (phrase" ") T S ((phrase" ") ) = fcall beging Tfendg = .
La procedura sintattica e:


procedure block
if cc = begin then cc := PROSSIMO
if cc 2 vId then varDeclaration
0

43

elsif cc 62 fcall begin endg then ERRORE


endif
while cc 2 fcall beging do
phrase
enddo
if cc = end then cc:= PROSSIMO else ERRORE endif
else ERRORE
0

endif
end program

4.4 Esercizio
Data la grammatica soluzione dell'esercizio 3.4, si veri chi se la grammatica e di tipo
LL(1). Si consideri poi la versione in forma b.n.f. estesa, si veri chi se e di tipo LL(1)
e in caso aermativo se ne costruisca l'analizzatore a discesa ricorsiva.

Soluzione 4.4

E immediato veri care che la grammatica non e di tipo LL(k) per nessun k.
E possibile trasformarla in una grammatica LL(1), come la seguente, in cui sono
riportati anche gli insiemi guida delle produzioni:

8
>> S ! XY fp q r or and .g
>< Y ! f.g j or XY forg
G = > X ! AZ fp q r ( notg
>> Z ! for .g j and AZ fandg
: A ! p j q j r j (S ) j not A

La grammatica e scomoda per la costruzione di analizzatori sintattici e semantici integrati (una grammatica ad attributi per valutare il valore delle espressioni
o per tradurre in un linguaggio macchina sarebbe notevolmente pi u complicata del
necessario).
Per costruire analizzatori sintattico-semantici integrati a discesa ricorsiva si preferisce allora usare, per questo tipo di linguaggi, grammatiche in forma b.n.f. estesa,
come ad esempio la seguente grammatica G .
8 S ! D (or D)
>>
< ! C (and C )
G => D
>: C ! not A
A!pjqjrj ( S )
0

G e LL(1).
Per la produzioneTS ! D (or D) :
T
G (orD) S ((or D) ) = forg f. )g = .
Per la produzione D ! C (and C ) :
0

44

G ( and C ) T S ((andD) ) = fandg Tf. )g = .


La condizione di determinismo LL(1) e banalmente veri cata dalle altre produzioni.
La procedura sintattica per S e:


procedure S
D
while cc = or do
cc := PROSSIMO
D
enddo
if cc 62 f. )g then ERRORE endif
end S
0

La procedura sintattica per D e:

procedure D
C
while cc = and do
cc := PROSSIMO
C
enddo
if cc 62 f. )g then ERRORE endif
end D
0

La procedura sintattica per C e:

procedure C
while cc = not do
cc := PROSSIMO
enddo
A
end C
0

Lasciamo al lettore il completamento dell'analizzatore discendente con la procedura per il nonterminale A.

45

4.5 Esercizio
Data la grammatica:
(
SB j bB j 
G = SB !
! dS j SBe

1. Si eliminino le ricorsioni sinistre trasformandole in ricorsioni destre.


2. Detta G la grammatica equivalente a G cos  ottenuta, se ne calcolino gli insiemi
guida veri cando se essa e LL.
0

Soluzione 4.5

Nella grammatica vi sono due ricorsioni sinistre, S ! SB e B !2 Be. Per eliminare le ricorsioni sinistre bisogna ricorrere all'algoritmo descritto in Hopcroft 1969].
Conviene evitare di avere -regole associate al non-terminale di cui si deve eliminare la ricorsione sinistra, allo scopo di ridurre il numero di passi richiesto dall'algoritmo. Per questo si introduce un nuovo simbolo S0 che manterr a inalterato il
linguaggio eliminando la produzione critica. La grammatica diventer a:
8
>< S0 ! S j 
G = > S ! SB j bB j B
: B ! dS j d j SBe j Be
L'algoritmo opera nella maniera seguente: Siano A ! A1 j A2 j : : : j An, dove
nessun i o j e annullabile, le alternative immediatamente ricorsive a sinistra di A, e
siano A ! 1 j 2 j : : : j m le rimanenti alternative per A.
Introducendo un nuovo non-terminale A e scrivendo le seguenti regole:
A ! 1A j 2A j : : : j m A
A ! 1 A j 2 A j : : : j nA j 
si ottiene la grammatica equivalente ricorsiva a destra nel non-terminale A (la
-produzione non crea problemi perch e A non pu o essere ricorsivo a sinistra). Si
possono quindi eliminare tutte le ricorsioni sinistre immediate. Le ricorsioni sinistre
non immediate vengono poi eliminate con lo stesso procedimento, trasformandole
dapprima in immediate.
Applichiamo separatamente l'algoritmo sopra illustrato ai due non-terminali S e
B , aggiungendo due non-terminali S e B . Otteniamo G :
8>
>> S0 ! S j 
< S ! bBS j BS
G = S ! BS j 
>> B ! dSB j dB j SBeB
>: B ! eB j 
0

46

In G compare ancora una ricorsione sinistra nel termine B : B ! SBeB !


BS BeB . Per eliminare anche questa ricorsione si pu o sostituire il termine S nella
produzione critica di B , eliminandola senza alterare il linguaggio. Si ottiene in questo
modo una ulteriore produzione immediatamente ricorsiva a sinistra che si pu o gestire
con il precedente algoritmo.
La produzione del non-terminale B sar a:
0

B ! dSB j dB j bBS BeB j BS BeB


Applicando l'algoritmo introduciamo un nuovo simbolo B ottenendo la grammatica:
8> S ! S j 
>> S0! bBS j BS
><
! BS j 
G = > SB !
dSB B j dB B j bBS BeB B
>>
>: B ! eB j 
B ! S BeB B

0

00

00

00

00

00

00

00

Tutte le ricorsioni sinistre sono state eliminate.


Per determinare se la grammatica e LL(1) costruiamo gli insiemi guida dei nonterminali.
8 S ! S fb dg j f.g
>> 0
>> S ! bBS fbg j BS fb dg
< ! BS fb dg j fb d e .g
G = > SB !
dSB B fdg j dB B fdg j bBS BeB B fbg
>>
B
!
eB feg j fb d eg
>:
B ! S BeB B

0

00

00

00

00

00

00

Gli insiemi guida delle regole di produzione associate al non-terminale S (come


per i non-terminali S , B e B ) non hanno un'intersezione nulla, quindi la grammatica
non e di tipo LL(1).
0

4.6 Esercizio
Si de nisca mediante una sintassi il linguaggio delle spezzate mostrate nella gura 22.
L'alfabeto terminale e costituito dai simboli: ! = f% ! &g
La spezzata si compone di segmenti crescenti, orizzontali e decrescenti ogni segmento e costituito da un numero intero di vettori unitari. Il primo segmento e crescente l'ultimo e qualsiasi.
Tra un segmento crescente e uno decrescente vi pu o essere un segmento orizzontale
di lunghezza arbitraria. La lunghezza di un segmento crescente e maggiore o eguale
a quella del segmento decrescente successivo. Un segmento decrescente pu o mancare.

47

Figure 22: Le spezzate del linguaggio L


1. Si veri chi se la sintassi e LL(1) calcolando gli insiemi guida
2. Si cerchi di costruire una grammatica LL(1) per il linguaggio. Qualora questo
non sia possibile si modi chi il linguaggio in modo tale da poter de nire una
grammatica LL(1)

Soluzione 4.6

La grammatica si pu o costruire passo passo: la spezzata si pu o scomporre in un


insieme di segmenti, ognuno caratterizzato da un tratto crescente seguito da un tratto
decrescente, con in mezzo eventualmente un tratto pianeggiante.
Il singolo segmento pu o essere rappresentato dalle seguenti produzioni:

A =)% A j% A &j B
B =)! B j 

La sequenza di segmenti potr a essere rappresentata dalla produzione:

S =) AS j 
Inoltre, il primo segmento deve iniziare con un tratto crescente, per cui l'assioma
del linguaggio sar a il non-terminale S0 cui corrisponder a la produzione:
S0 =)% S j% S &
La grammatica che descrive il linguaggio sar a la seguente G:
8 S =)% S j% S &
>> 0
<
AS j 
G = > SA ==)
>: )% A j% A &j B
B =)! B j 
La grammatica risulta ambigua. Infatti la stringa %!! ammette le due derivazioni S0 =)% S =)% AS =)% AAS =)% AA =)% BA =)% BB =)%!
B =)%!! e S0 =)% S =)% A =)% B =)%! B =)%!! B =)%!!
Un'altra sorgente di ambiguit a e generata dal fatto che se il numero di tratti
decrescenti e inferiore al numero di tratti crescenti, vi sono diversi possibili modi
48

in cui le diverse produzioni di A possono essere utilizzate. Per eliminare la prima


ambiguit a e necessario distinguere il caso in cui una sequenza di tratti orizzontali
compare tra un tratto crescente e un tratto decrescente dal caso in cui non e seguita
da un tratto decrescente. Nel primo caso la sequenza verr a generata dal non-terminale
B , mentre nel secondo verr a generata dal non-terminale S . La seconda ambiguit a si
risolve introducendo un nuovo simbolo per A. La grammatica non ambigua che si
ottiene e la seguente:

8
>> S0 =)% S j% S &
>< S =) A1 S j! S j 
G = > A1 =)% A1 j% A2 &
>> A2 =)% A2 &j B
: B =)! B j 
0

Calcolando gli insiemi guida associati ai vari non terminali, si osserva come la
grammatica non sia LL(1). Un tentativo di renderla LL(1) applicando una fattorizzazione sinistra produce il seguente risultato:

8
>> S0 =)% S f%g(&j )f& .g
>< S =) A1 S f%g j! S f!g j f.g
G = > A1 =)% A1f%g j% A2 & f%g
>> A2 =)% A2 & f%g j B f! &g
: B =)! B f!g j f&g
Tutti i non terminali tranne A1 sono LL(1). Il problema consiste nel valutare se e
possibile rendere A1 LL(1). Ci o non e possibile. Infatti se si analizza il linguaggio si
00

vede come sia impossibile per il riconoscitore a discesa ricorsiva sapere se e corretto
scegliere la prima o la seconda produzione guardando solo l'elemento successivo. Pure
un riconoscitore LL(k) non sar a in grado di riconoscere il linguaggio: baster a infatti
prendere una stringa che contenga un segmento di lunghezza k + 1 per non essere in
grado di decidere quale delle due produzioni si debba scegliere.
Si pu o rendere il linguaggio LL(1) ad esempio imponendo che il numero di tratti
crescenti sia pari al numero di tratti decrescenti. Questo corrisponde alla grammatica
LL(1) seguente:

8
>> S0 =)% SS f%g
>< S =)& f&g j f.g
G = > S =)% A & S f%g j! S f!g j f.g
>> A =)% A & f%g j B f! &g
: B =)! B f!g j f&g
Il riconoscitore a pila della grammatica LL(1) e caratterizzato dal seguente com0

000

portamento (nella tabella sono sottointese le mosse di avanzamento testina quando il


terminale in ingresso e identico al terminale sulla cima della pila):
49

Cima
Carattere di ingresso
Pila
%
!
&
.
S0 push S S %
S
push & push 
S
push S & A push S !
push 
A push & A % push B push B
B
push B ! push 
0

4.7

Esercizi proposti

4.7.1 Esercizio

Veri care se la grammatica G:

8>
< S ! aSb j C
G = > C ! aD j 
: D ! cC

e LL(1). Nel caso negativo, cercare di trasformarla in una grammatica LL equivalente.

4.7.2 Esercizio

Si consideri l'insieme L delle sequenze degli eventi associati ad un insieme di operazioni


di lettura e di scrittura, secondo il modello di concorrenza tra processi noto come
modello dei lettori-scrittori. Pi u lettori possono operare contemporaneamente, ma
un solo scrittore pu o essere attivo, e soltanto se non vi sono lettori attivi. Inoltre ogni
lettura deve nire, e cos  ogni scrittura. In ne una lettura o scrittura non pu o nire
se non e iniziata. Si indichino gli eventi con i seguenti simboli terminali:

il inizio lettura
 ne lettura
is inizio scrittura
fs ne scrittura
Ad. es. sono valide le stringhe:

il il fl il fl fl il il fl fl is fs is fs il fl
mentre sono scorrette le stringhe:
il is fs il fl fl is fs is il fl fs il fl il fs il fl
50

1. Si costruisca una grammatica G BNF-estesa per L e si traccino i diagrammi


sintattici.
2. Si veri chi se G e LL(1) calcolando gli insiemi guida.
3. Se necessario si modi chi G in modo da renderla LL(1). Si scrivano almeno in
parte le procedure sintattiche dell'analizzatore a discesa ricorsiva.

5 Analisi sintattica ascendente


5.1 Esercizio
Costruire un automa a spostamento e riduzione LR(0) per la seguente grammatica:

8
>< S ! aTb j c
G = > T ! DSb j c
: D!a

Si illustri il funzionamento del riconoscitore sulla stringa acb.

Soluzione 5.1

Costruiamo direttamente il riconoscitore dei pre ssi ascendenti LR(0) in forma


deterministica. Si aggiunge alla grammatica G la produzione S0 ! S .. Lo stato
I0 in questo caso contiene una candidata di spostamento per ogni produzione, ma
nessuna candidata di riduzione, non essendoci -produzioni.
I0 contiene pertanto le candidate:

8>
< S0 ! S .
I0 > S ! aTb
: S ! c

L'automa viene costruito a partire da I0, considerando tutte le possibili mosse,


costituite da terminali o non terminali, che possono provocare uno spostamento. Iterando il procedimento ai nuovi stati cos  ottenuti, si costruisce l'automa costituito da
tutti e soli gli stati raggiungibili da I0.
Ad esempio, da I0 ci possono essere solo tre mosse che possono provocare uno
spostamento, in quanto ci sono solo tre caratteri distinti immediatamente a destra di
un : a c S .
Con un arco etichettato S possiamo perci o andare in uno stato I1 che contiene
solo la candidata di spostamento S0 ! S  .. Con un arco etichettato a (analogamente per c) possiamo andare in uno stato I2 con le seguenti candidate (tutte di
spostamento):
51

S0 -> S^/
S

S0 -> ^S/
S ->^ aTb

S->^c

I1
S ->a^Tb
T ->^DSb
T -> ^c
D -> ^a

I0

I2

Figure 23: Costruzione dell'automa riconoscitore dei pre ssi ascendenti per l'esercizio 5.1.

8> S ! a  Tb
>< T ! DSb
I2 > T ! c
>:
D ! a
Le candidate T ! DSb, T ! c e D ! a devono essere riportate in I2 in
quanto la candidata S ! a  Tb, ottenuta da I0, ha un T immediatamente a destra
di un . Inoltre la candidata, in I2 , T ! DSb ha un D immediatamente a destra di

un . Si veda la gura 23.


Iterando il procedimento si ottiene l'automa riportato in gura 24. Quando uno
stato e di riduzione, non si deve pi u continuare a espanderlo e lo si marca opportunamente.
Automa LR(0) a spostamento e riduzione
La riduzione di una produzione X ! x per il riconoscitore LR(0) consiste nelle
seguenti mosse:
 Non leggere l'ingresso (-mossa)
 Togli i primi 2 j x j simboli in cima alla pila
 Se I e lo stato in cima alla pila, allora push(X ) e push( (I X )), dove e la
funzione di transizione dell'automa riconoscitore dei pre ssi ascendenti LR(0).
Lo spostamento di un simbolo I consiste nelle seguenti mosse:
 Consuma il simbolo z in ingresso
 Non togliere simboli dalla pila
52

S0 -> S^/
S

S ->a^Tb
T ->^DSb
a

T
I0

D->a^
I4

T -> ^c
D -> ^a

S->^c

S0 -> S/^
I3

I1

S0 -> ^S/
S ->^ aTb

I2

S -> aT^b

I5

S -> aTb^
I7

c
S -> c^

T -> c^

I11

D
c

I8
a

T -> D^Sb
S -> ^c
S -> ^aTb

I9

T -> DS^b
I10
b
T -> DSb^
I6

Figure 24: L'automa riconoscitore dei pre ssi ascendenti LR(0) per l'esercizio 5.1.

53

Cima
Carattere di ingresso
Pila
a
b
c
.
I0 Sposta I2
Sposta I11
I1
Sposta I3
I2 Sposta I4
Sposta I8
I3
I4
I5
Sposta I7
I6
I7
I8
I9 Sposta I2 Sposta I11
I10
Sposta I6
I11


accetta
riduci D ! a
riduci T ! DSb
riduci S ! aTb
riduci T ! c
riduci S ! c

Table 1: L'automa a spostamento e riduzione per l'esercizio 5.1. Per l'esecuzione delle
mosse di riduzione l'automa considera la funzione di transizione de nita dall'automa
di gura 24.
 push(z ) e push(I ).

La accettazione avviene quando non ci sono pi u simboli sul nastro di ingresso e


sulla pila c' e il solo stato corrispondente alla candidata di riduzione S0 ! S . .
L'analizzatore parte con I0 sulla pila e la frase da riconoscere sul nastro di ingresso.
Durante il funzionamento l'analizzatore esegue azioni di spostamento e di riduzione,
salvando o eliminando dalla cima della pila l'appropriata sequenza di identi catori
dello stato dell'automa riconoscitore dei pre ssi ascendenti, intervallati con gli opportuni simboli terminali e non terminali che costituiscono il pre sso corrente. L'automa
a pila a spostamento e riduzione LR(0) e descritto dalla Tabella 1.
Il funzionamento dell'automa sulla frase acb e riportato nella Tabella 2.
Tradizionalmente, la tabella per l'analizzatore a spostamento e riduzione e completata da una seconda sezione, detta parte "goto". In essa vengono rappresentate
le transizioni del riconoscitore dei pre ssi ascendenti che sono marcate con un non
terminale (e che quindi non corrispondono a un carattere in ingresso), allo scopo di
dare una rappresentazione completa in una sola tabella dell'automa a spostamento e
riduzione e del riconoscitore dei pre ssi ascendenti. L'analizzatore ha infatti bisogno
di conoscere la funzione di transizione del riconoscitore per potere eseguire correttamente le mosse di riduzione. Riportiamo in Tabella 3 questa versione, a titolo di
esempio.
54

I0
I0
I0
I0
I0
I0

Pila

a
a
a
a
S

I2
I2
I2
I2
I1

c I8
T I5
T I5 b I7
. I3

Nastro di ingresso
azione
a c b .
sposta I2
c b .
sposta I8
b .
riduci T ! c
b .
sposta I7
.
riduci S ! aTb

riduci S0 ! S . (accetta)

Table 2: Traccia del funzionamento dell'automa di Tabella 1 sulla stringa acb.

Cima
Pila
I0
I1
I2
I3
I4
I5
I6
I7
I8
I9
I10
I11

Carattere di ingresso
Parte Goto
a b c . 
S T D
I2
I11
I1
I3
I4
I8
I5 I9
accetta
riduci D ! a
I7
riduci T ! DSb
riduci S ! aTb
riduci T ! c
I2
I11
I10
I6
riduci S ! c

Table 3: Rappresentazione sintetica dell'analizzatore ascendente per l'esercizio 5.1.

55

S0 -> S^/

S0 ->S^/

S
I7
S -> i^Ai
A -> ^i

S -> i^Ai

S -> aA^a

S -> a^Aa

S -> a^Bb
A -> ^i
B -> ^i

S -> ^aBb
S -> ^bBa
S -> ^iAi

I14

S0 -> ^S/
S -> ^aAa
S -> ^bAb

I13
a

I3
B

I4

S -> aB^b

I1

S -> aAa^

I5

S -> aBb
I6

I0
S -> iA^i
I15

A -> i^

b
i

I16

i
S -> iAi^
I17

A -> i^
B -> i^
I8

S -> b^Ab
S -> b^Ba
A -> ^i

stato I8 non

adeguato per
analisi LR(0)

B -> ^i
I2

S -> bA^b

S -> bB^a

I9

I10

b
S -> bAb^

a
S -> bBa^

I11

I12

Figure 25: L'automa riconoscitore dei pre ssi ascendenti LR(0) dell'esercizio 5.2.
5.2 Esercizio
Veri care se la seguente grammatica
8>
< S ! iAi j aAa j bAb j aBb j bBa
G=> B!i
: A!i
e LR(0), SLR(1), LALR(1), LR(1). Si costruisca inoltre l'automa a spostamento
e riduzione per L(G), guidato dal riconoscitore dei pre ssi ascendenti LR(1), e se ne
illustri il funzionamento sulla frase aib ..

Soluzione 5.2

L'automa riconoscitore dei pre ssi ascendenti LR(0) e riportato in gura 25.
L'automa risultante e per o inadeguato per l'analisi LR(0): infatti, nello stato I8
ci sono due candidate di riduzione (un automa a spostamento e riduzione guidato
56

dal riconoscitore dei pre ssi ascendenti non potrebbe essere deterministico, in quanto
altrimenti, giunto nella situazione I8 , non saprebbe quale mossa di riduzione scegliere).
Analisi SLR(1).
Si considera ancora il riconoscitore LR(0), ma si calcola l'insieme dei seguiti di
X per ogni produzione X !  per le candidate di riduzione X !  negli stati
inadeguati. L'insieme cos  calcolato e usato dal riconoscitore SLR(1) come insieme di
prospezione per ciascuna candidata di riduzione.
Per lo stato I8 dobbiamo calcolare i due insiemi: SLR(A ! i) = S (A) = fx 2
! j S )destra Axz, con z 2 ! e  2 (! S VN ) g = fa b ig (A compare nella parte
destra solo per le produzioni S ! iAi j aAa j bAb).
SLR(B ! i) = fa bg
La marca nale . in questo caso non appartiene a nessuno dei due insiemi (in generale, va esplicitamente considerata, inserendola nell'insieme di prospezione qualora
xz = ).
La prima condizione di adeguatezza SLR(1) eSche non ci siano candidate di spostamento del tipo X ! c
, con c 2 SLR(A ! i) SLR(B ! i). Questa e banalmente
veri cata in quanto non ci sono candidate di spostamento in I8. La seconda condizione, vale a dire che gli insiemi di prospezione delle varie candidate di riduzione siano
disgiunti, non e per o veri cata, e pertanto la grammatica non e adeguata per l'analisi
SLR(1).
Analisi LALR(1). Nell'analisi LALR(1) si considera ancora il riconoscitore dei
pre ssi ascendenti LR(0) e si esaminano solo gli stati inadeguati, allo stesso modo
dell'analisi SLR(1), ma l'insieme dei seguiti per ogni candidata di riduzione viene
calcolato tenendo conto anche del cammino dallo stato iniziale, che deve portare
proprio allo stato inadeguato. L'insieme di prospezione in generale non dipende solo
dalla candidata o dalla sua parte sinistra, ma anche dal modo in cui si e arrivati a
considerare la candidata. In formule, l'insieme di prospezione per la candidata A ! i
nello stato I8 e de nito come:
LALR(I8 A ! i) = fx 2 ! j S )destra Axz ) ixz con (I0 i) = I8g =
fa bg.
In questo caso semplice possiamo utilizzare direttamente la de nizione. Infatti, ci
sono le derivazioni:
S ) aAa ) aia, con (I0 ai) = I8
S ) bAb ) bib, con (I0 bi) = I8
mentre la derivazione S ) iAi ) iii ha il pre sso i che non porta in I8: (I0 ai) =
I14 .
Analogamente, LALR(I8 B ! i) = fa bg.
Nonostante l'analisi LALR sia risultata pi u ranata dell'analisi SLR, poich e il
terminale i fa parte dell'insieme SLR(A ! i) ma non di LALR(I8 A ! i), la grammatica non e nemmeno LALR. La condizione di adeguatezza per LALR(1) e che gli
insiemi di prospezione
delle varie candidate di riduzione siano disgiunti, e che inoltre
T
LALR(I8 A ! i) fc j (I8 c) e de nito g = . Quest'ultima parte e banalmente


57

veri cata in quanto non ci sono candidate di spostamento in I8 e pertanto non ci sono
nemmeno archi uscenti da I8, ma la prima parte non lo e, e pertanto la grammatica
non e adeguata per l'analisi LALR(1).
Analisi LR(1).
Nell'analisi LR(1) si deve tenere conto, nella costruzione dell'automa riconoscitore dei pre ssi ascendenti, anche degli insiemi di prospezione associati a ciascuna
candidata. La stessa candidata pu o presentarsi in uno stesso stato con insiemi di
prospezione diversi: in generale, l'automa a stati niti cos  ottenuto ha un numero di
stati molto maggiore di quello dell'automa LR(0) per la stessa grammatica.
L'insieme di prospezione e de nito come per LALR(1), ma il metodo LR(1) si
dierenzia da LALR(1) poiche gli insiemi di prospezione sono usati anche per costruire
l'automa riconoscitore dei pre ssi ascendenti.
La costruzione dell'automa procede dallo stato I0 che contiene le candidate:
8 S !S.
>> 0
>> S ! aAaf.g
<
bAbf.g
I0 > SS !
!
iAif.g
>>
>: S ! aBbf.g
S ! bBaf.g
Si procede come per l'automa LR(0), ma dierenziando gli stati anche a seconda
degli insiemi di prospezione delle candidate. Non conviene utilizzare la de nizione
dell'insieme di prospezione, ma le usuali regole di calcolo, in forma deterministica.
Ad esempio, un arco uscente da I0 marcato a deve portare in uno stato I1 (quindi
(I0 a) = I1 ), in cui ci sono le due candidate:
(
a  Aaf.g
I1 SS !
! a  Bbf.g
In I1 dobbiamo per o considerare anche le candidate A ! i e B ! i. Poich e la
candidata A ! i deriva dalla candidata S ! a  Aaf.g, l'insieme di prospezione
e costituito dal simbolo a destra della A nella candidata, cio e il solo a (la marca .
non fa parte dell'insieme per A ! i in quanto a non pu o andare in ).
Analogamente, l'insieme di prospezione per B ! i e costituito dal solo simbolo
terminale b, in quanto la candidata e stata ricavata da S ! a  Bbf.g.
L'automa risultante e riportato in gura 26.
Si osservi che ora lo stato I8 del riconoscitore LR(0) viene distinto, nell'automa
LR(1), nei due stati I8 e I7 , che sono entrambi adeguati per LR(1), in quanto in
entrambi i casi gli insiemi di prospezione delle candidate di riduzione sono disgiunti.
L'analisi LALR(1) non aveva permesso questa distinzione in quanto considerava il
riconoscitore LR(0).
Costruzione automa a spostamento e riduzione LR(1). Costruiamo ora l'automa
a spostamento e riduzione guidato dal riconoscitore dei pre ssi ascendenti LR(1).
58

S0 -> S^/

S0 -> S/

S
I13
S0 -> ^S/

S -> i^Ai {/}


A -> ^i {i}

I15

S -> iA^i {/}


I16
i
S -> iAi^ {/}
I18

S -> ^aAa {/}


S -> ^bAb {/}
S -> ^aBb {/}
S -> ^bBa {/}
S ->^ iAi {/}

S -> aA^a {/}

S -> a^Aa {/}

S -> a^Bb {/}


A -> ^i {a}
B -> ^i {b}

S -> aAa^ (/}


I4

S -> aB^b {/}

S -> aBb {/}


I6

I5

A -> i^ {a}
B -> i^ {b}

b
i

I17
S -> b^Ab {/}
S -> b^Ba {/}
A -> ^i {b}
B -> ^i {a}

I3

I1

I0

A -> i^ {i}

I14

I8

A -> i^ {b}
B -> i^ {a}

I2

I7
A

S -> bA^b {/}

S -> bB^a {/}

I9

I10

b
S -> bAb^ {/}

a
S -> bBa^ {/}

I11

I12

Figure 26: L'automa riconoscitore dei pre ssi ascendenti LR(1) dell'esercizio 5.2.

59

L'alfabeto della pila e costituito dai simboli I0 : : : I14 e dall'alfabeto terminale e nonterminale della grammatica. L'automa a pila parte con il solo I0 sulla pila e la frase da
riconoscere sul nastro di ingresso. Durante il funzionamento l'automa esegue azioni di
spostamento e di riduzione, salvando o eliminando dalla cima della pila l'appropriato
identi catore dello stato dell'automa riconoscitore dei pre ssi ascendenti. L'automa
e in grado di leggere un simbolo in ingresso sensa consumarlo, cio e senza avanzare la
testina di lettura.
La mossa di riduzione di una produzione X ! x consiste nelle seguenti mosse
elementari:
 Non consumare l'ingresso (non e una vera -mossa, poiche l'ingresso viene comunque letto, anche se non consumato, per potere decidere quale candidata
ridurre negli stati inadeguati)
 Togli i primi 2 j x j simboli in cima alla pila
 Se I e lo stato in cima alla pila, allora push(X ) e push( (I X )).
Lo spostamento di un simbolo I consiste nelle seguenti mosse:
 Non togliere simboli dalla pila
 Consuma un simbolo z dall'ingresso
 push(z ) e push(I ):
La accettazione avviene quando non ci sono pi u simboli sul nastro di ingresso e
sulla pila c' e il solo stato corrispondente alla candidata di riduzione S0 ! S . . A
questo ne, quando l'automa trova I14 in cima alla pila, eettua una -transizione, in
modo da svuotare la pila.
E anche possibile accettare quando il prossimo simbolo in ingresso e la marca .
e ci si trova nello stato corrispondente alla candidata di spostamento S0 ! S ..
L'automa a pila a spostamento e riduzione LR(1) e descritto dalla Tabella 4.
Una traccia di funzionamento dell'automa sull'ingresso aib . e riportato in Tabella 5.


5.3 Esercizio
Si veri chi se la grammatica G2 dell'esercizio 3.4 e adeguata per l'analisi LR(0) o
SLR(1):

8 S ! D or S j D
>>
< ! C and D j C
G2 = > D
>: C ! not C j A
A!pjqjr

60

Cima
Carattere di ingresso
Pila
a
b
i
.

I0
Sposta I1
Sposta I2
I1
Sposta I8
I2
Sposta I7
I3
Sposta I4
I4
riduci S ! aAa
I5
Sposta I6
I6
riduci S ! aBb
I7 riduci B ! i riduci A ! i
I8 riduci A ! i riduci B ! i
I9
Sposta I1
I10
Sposta I2
I11
riduci S ! bAb
I12
riduci S ! bBa
I13
Sposta I14
I14
accetta
I15
Sposta I17
I16
Sposta I18
I17
Riduci A ! i
I18
Riduci S ! iAi
Table 4: L'automa a spostamento e riduzione LR(1) dell'esercizio 5.2.

I0
I0
I0
I0
I0
I0

Pila

a
a
a
a
S

I1
I1
I1
I1
I13

i I8
B I5
B I5 b I6
. I14

Nastro di ingresso
azione
a i b .
sposta I1
i b .
sposta I8
b .
riduci B ! i
b .
sposta I6
.
riduci S ! aBb

accetta

Table 5: Traccia del funzionamento dell'automa di Tabella 4 sulla stringa aib.


61

S -> D ^ or S
S -> ^D or S

S -> D ^

S-> ^D
D -> ^ C and D
D -> ^ C

I1

C -> ^ not C
C -> ^ A
A -> ^p
A -> ^q
A -> ^r
I0

Figure 27: Un frammento dell'automa riconoscitore dei pre ssi ascendenti per l'esercizio 5.3.

Soluzione 5.3

La grammatica non e adeguata per l'analisi LR(0). Per veri carlo non e necessario
costruire l'intero automa riconoscitore dei pre ssi ascendenti, ma basta semplicemente
notare la presenza delle due produzioni S ! D or S e S ! D. Il riconoscitore dei
pre ssi ascendenti sar a costituito fra l'altro di uno stato iniziale I0 e uno stato I1 ,
con I1 raggiungibile da I0 tramite un arco marcato D. Lo stato I1 non e adeguato
per l'analisi LR(0) in quanto contiene la candidata di spostamento S ! D or S
e la candidata di riduzione S ! D . Si veda la gura 27. Per ovviare a questo
inconveniente, le grammatiche del tipo di G2 sono di solito analizzate con metodi
SLR o LALR.
La veri ca se la grammatica e SLR(1) e molto facile. Lasciamo al lettore la
costruzione del riconoscitore completo LR(0), dopo avere aggiunto come di consueto
la produzione S0 ! S .. Dal riconoscitore si pu o facilmente vedere che gli unici
stati inadeguati per LR(0) sono i seguenti:
1. Stato con la candidata di spostamento S ! D or S e la candidata di riduzione
S!D 
2. Stato con la candidata di spostamento D ! C andD e la candidata di riduzione
D!C 
Nel caso (1) l'insieme dei seguiti della candidata di riduzione e f.g: la condizione
SLR(1) e veri cata in quanto la candidata di spostamento e S ! D or S , con
or 62 f.g. Nel caso (2) l'insieme dei seguiti della candidata di riduzione e for .g
la condizione SLR(1) e pure veri cata in quanto la candidata di spostamento e D !
C and D, con and 62 for .g.


62

S0 -> S^/

S0 -> S/

S
I7

I8

S0 -> ^S/

S -> a^Sc

S -> ^aSc
S -> ^T
T -> ^aTb {/}
T-> ^

T -> a^Tb
S -> ^T
S -> ^aSc
T-> ^

S -> aS^c
I3

T -> ^aTb
I0

S -> aSc^
I4

T -> aT^b
S -> T^

T -> aTb ^
I6

I5
I1

S -> T^
I9

Figure 28: L'automa riconoscitore dei pre ssi ascendenti LR(0) per l'esercizio 5.4.
5.4 Esercizio
Si consideri il linguaggio L = fanbpcq j n  0 ^ n = p + qg dell'Esercizio 4.1 e si
veri chi se e LR(0) o LR(1).

Soluzione 5.4

La grammatica G data nella Soluzione dell'Esercizio 4.1:

aSc j T
G = ST !
! aTb j 
non e LR(0), come si pu o facilmente veri care dall'automa riconoscitore mostrato
in Figura 28, e non e nemmeno SLR. La grammatica e tuttavia LR(1), come si vede
dal riconoscitore dei pre ssi ascendenti LR(1) di Figura 29.
Dalla gura si pu o facilmente notare che G e anche LALR(1): basta accorpare
gli stati con le stesse candidate, cio e I1 con I2, I3 con I7, I5 con I9 , I8 con I4 e
I6 con I10 : gli insiemi di prospezione cos i ricavati sono adeguati per LALR(1). Gli
insiemi possono essere ricavati anche in base alla de nizione di LALR(1), riportata
nell'esercizio 5.2 a partire dall'automa riconoscitore LR(0).
In I0 l'insieme di prospezione LALR(1) per T ! e f.g. Infatti, l'unica derivazione destra del tipo S0 ) Tz tale che (I0  ) = I0, e la derivazione: S0 ) S .)
T . (perch e il pre sso  deve essere uguale a  se si vuole che (I0  ) = I0).
In I1 l'insieme di prospezione LALR(1) per T ! e fb cg perch e le derivazioni
destre che portano in I1 devono generare una frase del tipo a+Tz, e sono quindi di
uno dei due tipi seguenti:


S0 )+ apScp .) apTcp .
63

S0 -> S^/

S0 -> S/

S
I11
S0 -> ^S/
S -> ^aSc {/}
S -> ^T {/}
T -> ^aTb {/}
T-> ^ {/}

S -> a^Sc {/}

I12

I3

S -> ^T {c}
S -> ^aSc {c}
T-> ^ {b,c}

T -> ^aTb {b,c}

I0

S -> aS^c {/}

S -> aSc^

(/}

T -> a^Tb {/}

T -> aT^b {/}


S -> T^ {c}

I4
b

T -> aTb {/}


I6

I5

I1
a

S -> T^ {/}
I13

S -> a^Sc {c}

T -> a^Tb {b,c}

I7

S -> ^T {c}
S -> ^aSc {c}

S -> aS^c {c}

T -> ^aTb {b,c}

T -> aT^b {b,c}


S -> T^ {c}

T-> ^ {b,c}

S -> aSc^ {c}


I8

T -> aTb ^ {b,c}


I10

I9
I2

Figure 29: L'automa riconoscitore dei pre ssi ascendenti LR(1) per l'esercizio 5.4.

64

S0 )+ apTcp .)+ apaq Tbq cq .


In ne, nell'ultimo stato inadeguato, I5, la candidata di riduzione S ! T ha come
insieme di prospezione LALR(1) fcg, poich e le derivazioni destre che da I0 portano
in I5 devono generare una frase del tipo a + Sz, e sono quindi tutte del tipo:


S0 )+ apScp .
Si osservi che sia la grammatica G che il linguaggio L non sono LL(k) per nessun
k, ma che tuttavia la grammatica e LR(1). Infatti la classe dei linguaggi LR(1) e pi u
ampia di quella che contiene i linguaggi LL(k).
Si pu o addirittura costruire una versione, pi u complicata, di grammatica per L
che e anche LR(0). Questo non sorprendente visto che la classe dei linguaggi LR(1)
coincide con la classe dei linguaggi deterministici, mentre LR(0) coincide con la classe
dei linguaggi deterministici per i quali nessuna frase e pre sso proprio di un'altra
frase: usando una marca di ne stringa che non compare nell'alfabeto terminale, le
due classi vengono di fatto a coincidere. Nonostante questo, una grammatica LR(1)
pu o non essere LR(0), come in questo caso. La trasformazione in LR(0) e per o sempre
possibile, nell'ipotesi di considerare una marca di ne stringa ed essendo disposti ad
accettare una grammatica pi u complicata e meno intuitiva.
Una grammatica LR(0) per L e la seguente G :
8
>< S0 ! S .j.j T .
G = > S ! aSc j ac j aTc
: T ! aTb j ab
0

La veri ca che la grammatica G e LR(0) e lasciata al lettore. Rispetto a G, G


e LR(0) in quanto non contiene le due produzioni S ! T e T ! , la cui presenza
porta a costruire per G alcuni stati inadeguati.
0

5.5

Esercizi proposti

5.5.1 Esercizio

Sia data la sintassi:


(
aAc
G = SA !
! bAb j b
Si veri chi se G e LR(1) e, se necessario, si costruisca una sintassi equivalente
LR(0) o LR(1). Si progetti un analizzatore ascendente per G.

65

5.5.2 Esercizio
Per ciascuna delle seguenti grammatiche si veri chi se la grammatica e LR(0), SLR(1),
LALR(1), LR(1):

aAaa j bAba
G1 = SA !
!bj
8 S!X.
>>
< ! bA j aB
G2 = > X
>: A ! a j aX j bAA
B ! b j bX j aBB
Si mostri inoltre una traccia del calcolo svolto da un analizzatore ascendente, su
una stringa a scelta.

6 Traduzioni sintattiche
6.1 Esercizio
Si costruisca uno schema di traduzione semplice per calcolare la traduzione:
((a)nc(b)n ) = d n=2 en, con n  0
Descrivere un trasduttore a pila deterministico che esegue la traduzione, usando
la tecnica LL(1) e la tecnica LR(0), e un trasduttore ricorsivo discendente.
b

Soluzione 6.1

La sintassi sorgente deve generare il linguaggio L = f(a)nc(b)n j n  0g. La


grammatica pi u ovvia per questo e la seguente:

n
G0 = S ! aSb j c

Lo schema di traduzione potrebbe allora scrivere una d per ogni coppia di a, e una
e per ogni b. Non si pu o per o ricavare una sintassi pozzo a partire da G0 , in quanto
occorre distinguere i due casi: quando si genera una a e non si scrivono d, e quando
si genera una coppia di a e si scrive una d in uscita.
Questo pu o essere ottenuto semplicemente con il seguente schema di traduzione:

n
Gt = S ! aafdgSbbfeeg j acbfeg j c

Ad esempio, (aaacbbb) = deee e cos  ottenuta:


Sorgente: S ) aaSbb ) aaacbbb.
Pozzo: S ) dSee ) deee.
La grammatica non e LL(1). La si pu o rendere LL(1) ad esempio in questo modo:
66

aTbfeg j c
Gt = ST !
! afdgSbfeg j c
Ad esempio, (aacbb) = dee e cos  ottenuta:
Sorgente: S ) aTb ) aaTbb ) aacbb.
Pozzo: S ) Te ) dTee ) dee.
Lo schema di traduzione e chiaramente deterministico, in quanto la grammatica
sorgente e addirittura LL(1). Infatti:
0

G (S ! aTb) = fag
G (S ! c) = fcg
G (T ! aSb) = fag
G (T ! c) = fcg
L'automa a pila che implementa la traduzione si ottiene facilmente dall'automa
riconoscitore LL(1) aggiungendo opportune azioni di emissione. Il risultato e riportato
nella tabella seguente:
Cima
Carattere di ingresso
Pila
a
b
c
S
push(fegbTa)
push(c)
T push(afegSbfdg)
push(c)
a
avanza
b
avanza
c
avanza
feg
emetti e
emetti e emetti e
fdg
emetti d
emetti d emetti d
Analogamente per il trasduttore ricorsivo discendente:

procedure S
if cc 2 fag then cc:= PROSSIMO
T
if cc 6= "b" then ERRORE else cc := PROSSIMO endif
EMETTI("e")
elsif cc 2 fcg then cc := PROSSIMO
else ERRORE
endif
end S
67

procedure T
if cc 2 fag then cc:= PROSSIMO
EMETTI("d")
S
if cc 6= "b" then ERRORE else cc := PROSSIMO endif
EMETTI("e")
elsif cc 2 fcg then cc := PROSSIMO
else ERRORE
endif
end T
Per potere costruire un traduttore con tecnica LR(0), occorre portare la grammatica pozzo in forma post ssa. In questo caso si pu o introdurre un nonterminale
D da usare al posto di fdg nello schema di traduzione. Per non rendere la grammatica inadeguata per l'analisi LR(0), evitiamo l'introduzione di -produzioni (come
succederebbe per la grammatica sorgente se si aggiungesse la produzione D ! fdg).
Conviene allora usare D per generare una a nella grammatica sorgente e una d in
quella pozzo. Lo schema di traduzione risultante e il seguente:

8
>< S ! aTbfeg j c
Gt = > T ! DSbfeg j c
: D ! afdg
0

Lo schema LR(0) (che e lo stesso dell'esercizio 5.1) e riportato in gura 30.


Il trasduttore a spostamento e riduzione basato sul riconoscitore LR(0) si ottiene
facilmente dall'automa a spostamento e riduzione dell'esercizio 5.1 aggiungendo opportune azioni di emissione da eseguire durante le riduzioni. Si veda la Tabella 6.
6.2 Esercizio
Si costruisca uno schema di traduzione semplice per calcolare la traduzione: (x) =
xR x, con x 2 fa bg . Tracciare poi lo schema di un trasduttore a pila che esegua la
traduzione. E possibile costruire un trasduttore deterministico?


Soluzione 6.2

Notiamo innanzitutto che (xxR ) = xR si pu o de nire banalmente:

n
Gt0 = S ! aSafag j bSbfbg j 

Inoltre, (xxR ) = x e ottenibile con il seguente schema:

n
Gt1 = S ! fagaSa j fbgbSb j 

68

S0 -> S^/
S

S ->a^Tb e
T ->^DSb e
a

T
I0

D->a^ d
I4

T -> ^c
D -> ^a

S->^c

S0 -> S/^
I3

I1

S0 -> ^S/
S ->^ aTb e

I2

S -> aT^b e

I5

S -> aTb^ e
I7

c
S -> c^

T -> c^

I11

D
c

I8
a

T -> D^Sb e
S -> ^c
S -> ^aTb e

I9

T -> DS^b e
I10
b
T -> DSb^ e
I6

Figure 30: L'automa riconoscitore dei pre ssi ascendenti LR(0) per l'esercizio 6.1.
I caratteri della grammatica pozzo, da emettere al momento di una riduzione, sono
segnati in grassetto.

69

Cima
Pila
a
I0 Sposta I2
I1
I2 Sposta I4
I3
I4

I5
I6

Carattere di ingresso
c
.
Sposta I11
Sposta I3
Sposta I8

Sposta I7

accetta
riduci D ! a
emetti d
riduci T ! DSb
emetti e
riduci S ! aTb
emetti e
riduci T ! c

I7
I8
I9
I10
I11

Sposta I2 Sposta I11


Sposta I 6

riduci S ! c

Table 6: Il trasduttore a spostamento e riduzione dell'esercizio 6.1.


Per ottenere la traduzione desiderata, basta a questo punto combinare queste
traduzioni in modo opportuno.
Lo schema di traduzione risultante e il seguente:

n
Gt = S ! fagSafag j fbgSbfbg j 

Un esempio di derivazione e:
Sorgente: S ) Sa ) Sba ) Sbba ) Sbbba ) bbba.
Pozzo: S ) aSa ) abSba ) abbSbba ) abbbSbbba ) abbbbbba.
Un trasduttore a pila per la si pu o costruire sfruttando il nondeterminismo.
Prima di cominciare a leggere, l'automa "indovina", con una serie di -mosse il riesso
xR della stringa da riconoscere, lo emette e lo impila. Questo e possibile in quanto si
pu o costruire un automa che ad ogni passo sceglie nondeterministicamente se emettere
e impilare il carattere a, oppure il carattere b oppure cominciare a leggere l'ingresso.
A un certo punto, l'automa comincia a leggere la stringa in ingresso, emettendola
in uscita e confrontandola con la stringa salvata sulla pila. Se le due stringhe sono
una il riesso dell'altra, allora l'automa accetta, e quindi la stringa xR x e il risultato
della traduzione dell'ingresso x. Se invece l'automa non accetta, i caratteri emessi
non fanno parte della traduzione, in quanto, per stabilire il risultato della traduzione,
la de nizione di trasduttore non considera le computazioni fallite.
70

Stato /
cima pila
q0 Z0

q0 A
q0 B


(q0 A a)
(q0 B b)
(q0  )
(q0 AA a)
(q0 AB b)
(q1 A )
(q0 AA a)
(q0 AB b)
(q1 B )

Ingresso
a

q1 A
(q1  a)
q1 B
(q1  b)
Table 7: La funzione di transizione di un trasduttore a pila che calcola (x) = xR x,
per l'esercizio 6.2.
La de nizione dell'automa trasduttore pu o essere cos i precisata. Sia Z0 il simbolo
iniziale della pila l'alfabeto di ingresso e fa bg, quello della pila fZ0 A B g. L'insieme
di stato e fq0 q1g. L'automa accetta quando la pila e vuota e il nastro di ingresso e
vuoto. Il risultato della traduzione della stringa di ingresso e de nito come l'insieme
delle stringhe emesse durante computazioni che portano ad accettazione (in questo
caso, per ogni ingresso ci sar a una e una sola computazione che porta ad accettazione,
e pertanto il risultato della trasduzione sar a una stringa e non un insieme di stringhe).
La funzione di transizione dell'automa e descritta nella Tabella 7, in cui sulle righe
sono riportate solo le coppie (stato, simbolo in cima alla pila) per le quali la funzione
e de nita per almeno un valore dell'ingresso. Poiche l'automa e non deterministico,
in una stessa con gurazione sono possibili pi u mosse, riportate nella stessa cella della
tabella. Ogni mossa e rappresentata da una tripla (stato, stringa da impilare, stringa
di uscita). L'automa esegue una pop ad ogni passo, cambia di stato, esegue una push
della stringa da impilare ed emette la stringa di uscita.
E facile comprendere che nessun automa a pila deterministico e in grado di eseguire
questa traduzione.
6.3 Esercizio
Si costruisca uno schema di traduzione nito per calcolare la traduzione: (x) e la funzione identit a no alla prima occorrenza, da sinistra, della stringa aba in x, restituisce
c per questa prima occorrenza, e ancora la funzione identit a dopo l'occorrenza.
Ad esempio, (aab) = aab, (aba) = c, (aabbabababa) = aabbcbaba.

71

Stato

ingresso
b

(q0 b)
(q2 ) (q4 a)
(q0 abb) (q4 ab)
(q3 b)

q0 (q1 )
q1 (q1 a)
q2 (q0 c)
q3 (q3 a)
q4
Table 8: Il trasduttore nito per l'esercizio 6.3. Il primo elemento di ogni coppia e lo
stato prossimo, il secondo la stringa emessa in uscita. Gli stati q0 , q3 e q4 sono nali.
Si costruisca il trasduttore nito che calcola la traduzione.

Soluzione 6.3

Uno schema di traduzione e il seguente:


8 S ! aT j bfbgS j 
>>
<
bU j afagT j fag
Gt = TU !
>: ! afcgV j bfabbgS j fabg
V ! afagV j bfbgV j 
Il corrispondente trasduttore nito e dato in Tabella 8.
6.4 Esercizio
Si progetti uno schema sintattico semplice di traduzione per calcolare la traduzione:

(an1 ?an2 ?an3 : : :?ank ) = bn1 cn1 1bn2 cn2 2bn3 cn3 : : : bnk cnk
con k  1 ni  1. La traduzione sostituisce i separatori "?" di posto dispari con
1, quelli di posto pari con 2.
La traduzione pu o essere calcolata da un trasduttore deterministico?

Soluzione 6.4

Una soluzione e data dal seguente schema:


8
>< S ! T j T ?f1gT j T ?f1gT ?f2gS
Gt = > T ! afbgT fcg j 

E evidente che si pu o costruire un trasduttore deterministico. Per convincersene,


si pu o anche modi care la grammatica in modo da renderla LL(1) (come si pu o
facilmente veri care):
72

8 S ! TU
>><
?f1gTW j 
Gt1 = > UW !
!
 mid?f2gTS
>:
T ! afbgT fcg j 
6.5

Esercizi proposti

6.5.1 Esercizio

Si costruisca un trasduttore nito che calcola la seguente traduzione:


(a3n ) = b2n n  0

6.5.2 Esercizio
Si costruisca uno schema di traduzione sintattico che calcola la seguente traduzione,
per n  0:
n=2
(an c bn ) = dpn+1 nn pari
dispari
Si veri chi se la traduzione pu o essere calcolata in modo deterministico e si
costruisca il relativo automa trasduttore.


7 Grammatiche ad attributi
7.1 Esercizio
Costruire una grammatica ad attributi che generi il linguaggio non libero

L = fanbncn j n  1g

Soluzione 7.1

Possiamo procedere in due modi:


1. Costruire una grammatica per a+ b+c+, i cui attributi veri cano se vi sia lo
stesso numero di occorrenze di a, di b e di c.
2. Costruire una grammatica per an bnc+ e veri care poi che il numero di occorrenze di c sia proprio n.
Seguendo il primo metodo de niamo la seguente grammatica, scritta in una forma
comoda per sempli care gli attributi:

73

a=true

A 2 b

B 2

C 2

A 1 b

B 1

C 1

3 B

C 3

Figure 31: Albero decorato per la stringa aaabbbccc per la grammatica ad attributi
dell'esercizio 7.1.

8
>> 1)S ! ABC
>> 2)A ! aA
>> 3)A ! a
<
G1 = > 4)B ! bB
>> 5)B ! b
>> 6)C ! cC
>: 7)C ! c

Gli attributi sono i seguenti: aofS restituisce true se la stringa generata e una
frase di L, mentre numofA, numofB e numofC rappresentano rispettivamente il
numero di a, b e c generati da A, B , C .

8
>> 1)aofS := (numofA = numofB ^ numofB = numofC )
>> 2)numofA0 := 1 + numofA1
>> 3)numofA := 1
<
4)numofB0 := 1 + numofB1
>> 5)
>> numofB := 1
>> 6)numofC0 := 1 + numofC1
: 7)numofC := 1

Un esempio di albero di derivazione per la frase aaabbbccc, decorato con i corrispondenti attributi, e mostrato in gura 31.
Il secondo metodo e mostrato dalla seguente grammatica:

74

8
>> 1)S ! XC
>< 2)X ! aXb
G1 = > 3)X ! ab
>> 4)C ! cC
: 5)C ! c
Gli attributi sono i seguenti: aofS restituisce true se la stringa generata e una
frase di L, mentre numofX restituisce il numero di a (uguale a quello delle b) e
numofC rappresenta il numero di c generati da C .

8
>> 1)aofS := (numofX = numofC )
>< 2)numofX0 := 1 + numofX1
numofX := 1
>> 3)
4)
>: numofC0 := 1 + numofC1
5)numofC := 1

7.2 Esercizio
Costruire una grammatica ad attributi che generi il linguaggio non libero

L = fww j q 2 (0
1) g


Si possono usare solo attributi di tipo intero o booleano.

Soluzione 7.2

Una soluzione pu o essere facilmente costruita se si considera una stringa di 0 e


1 come una rappresentazione binaria di un opportuno numero intero. Si pu o allora
de nire una grammatica che considera frasi divise in due met a di pari lunghezza, i cui
attributi calcolano il valore intero corrispondente alle due met a. Poich e le due stringhe
sono di pari lunghezza, sono uguali se, e solo se, rappresentano lo stesso numero intero.
In questo caso, infatti, non vi e alcuna ambiguit a nella rappresentazione dovuta alla
possibilit a che vi siano zeri iniziali (0010 ha lo stesso valore di 010 e di 10).
Per calcolare il valore numerico delle due met a basta osservare che aggiungere
un bit v a sinistra, cio e nella posizione pi u signi cativa, di una stringa di n bit che
rappresenta il numero b, de nisce un numero binario di valore b + v  2n 1. Aggiungere
un bit v a destra, cio e nella posizione meno signi cativa, di una stringa di n bit che
rappresenta il numero b, de nisce un numero binario di valore 2  b + v.
Si pu o allora usare una produzione che attacchi un bit a sinistra e uno a destra,
con opportuni attributi che tengano conto della profondit a dell'albero.
La grammatica costruisce simmetricamente stringhe del tipo (0
1)n(0
1)n. Gli
attributi sono des e sin per i valori della parte destra e sinistra della frase, val per il
valore di un singolo bit, d per la profondit a dell'albero.
;

75

1)S ! T
aofS := sinofT = desofT
2)T ! XTX sinofT0 := valofX  2dofT1 + sinofT1
desofT0 := valofX + 2  desofT1
dofT0 := dofT1 + 1
3)T ! 
desofT := 0
sinofT := 0
dofT := 0
4)X ! 0
valofX := 0
5)X ! 1
valofX := 1
Un albero decorato per la stringa 0101 e un albero per 0111 sono mostrati in
gura 32.
Si noti che il metodo e facilmente generalizzabile a qualunque alfabeto nito: dato
un qualunque alfabeto nito di cardinalit a k a,b, . . . z basta assegnare un valore tra 0
e k ad ogni lettera. Le formule per aggiungere cifre a sinistra e a destra sono uguali,
salvo che la cifra 2 e sostituita da k.
7.3 Esercizio
Si de nisca una grammatica ad attributi per il linguaggio delle dichiarazioni e di
chiamate di procedura. Una dichiarazione ha la forma: proc Id (P1 P2 : : : Pn)
lista-chiamate-di-procedura end dove Id e un identi catore che rappresenta il nome
della procedura e i Pi sono gli identi catori dei parametri formali, che si suppongono
tutti dello stesso tipo (intero). Vi e almeno un parametro formale per procedura.
Una chiamata ha la seguente forma: call Id (A1 A2 : : : An), dove ogni parametro
attuale Ai deve essere un intero positivo.
Una frase consiste di una o pi u dichiarazioni e chiamate, terminate da un carattere
punto. Ad esempio, una frase e:

proc P1(A, B)
call P1(2,3)
proc P2(X,Y)
call P2(4,5)
call P1(1,2)
call P2(3,6)
end.
La grammatica deve svolgere i seguenti controlli semantici:
 non vi sono due dichiarazioni di procedura con lo stesso nome
 le chiamate di procedura sono relative solo alle procedure che sono state dichiarate in un punto precedente del programma
76

S
d

0 X

2 T

1 1

1 T

val

val

val

val
sin des
0 T 0 0 X 0
d

1 T

val

0 1 X 1

1
val
sin des
0 T 0 1 X 1
d

1 3

sin des

0 X

0 1 X 1

a
false
sin des

sin des

0
val

sin des

2 T

val

a
true

Figure 32: Alberi decorati per la stringhe 0101 e 0111 per la grammatica ad attributi
dell'esercizio 7.2.

77

1)program ! prg

aofprogram := aofprg
envofprg := 
2)prg0 ! prcd prg1
aofprg0 := aofprcd ^ aofprg
1
envofprg1 := envofprg0 S updofprcd
envofprcd := envofprg0
3)prg ! :
aofprg := true
4)prcd ! procpId(fPar)cll aofprcd := aofcll ^ valofpId 62 nomi(envofprcd)
updofprcd := f(valofpId
numoffPar)g
envofcll := envofprcd Sf(valofpId numoffPar)g
5)fPar ! id
numoffPar := 1
6)fPar0 ! id fPar1
numoffPar0 := 1 + numoffPar1
7)cll0 ! callpId(actPar)cll1 aofcll0 := (pId numofactPar) 2 envofcll0 ^ aofcll1
envofcll1 := envofcll0
8)cll ! end
aofcll := true
9)actPar ! int
numofactPar := 1
10)actPar0 ! int actPar1 numofactPar0 := numofactPar1 + 1
Table 9: La grammatica ad attributi per l'esercizio 7.3
 i parametri attuali di una chiamata sono in numero pari a quelli formali della
dichiarazione corrispondente
Si descriva, almeno in parte, un analizzatore sintattico-semantico integrato per la
grammatica.

Soluzione 7.3

La grammatica, illustrata in Tabella 9, e costituita dai non-terminali program,


prg, prcd, cll, fPar, actPar, pId, int. Gli attributi da considerare sono: aofprogram,
che restituisce true o false a seconda che i controlli semantici diano esito positivo
o negativo envofprogram, envofprog, ecc., che sono attributi ereditati costituiti da
un insieme di coppie < nome numero > che rappresentano l'environment di una
dichiarazione, vale a dire i nomi e il numero dei parametri delle procedure visibili in
un certo punto del programma. Vi sono poi altri attributi, tutti sintetizzati, come
updofprcd che contiene la coppia nome-numero corrispondente alla dichiarazione corrente numofactPar e numoffPar che rappresentano il numero di parametri di una
dichiarazione e di una chiamata rispettivamente. I nonterminali pId, id e int non sono
espansi ulteriormente in quanto si suppone che il loro (unico) attributo sintetizzato
val sia ritornato da un opportuno analizzatore lessicale.
La regola (1) serve solo per inizializzare l'ambiente di prg. Da prg si deriva un
programma sintatticamente corretto, costituito da una o pi u dichiarazioni di procedura (prcd), tramite le regole (2) e (3). Ogni procedura e costruita secondo la regola
(4). L'attributo sintetizzato envofprg permette di veri care se l'identi catore della
procedura e gi a stato utilizzato. Si suppone che vi sia un analizzatore lessicale che
78

restituisce un identi catore per pId e un intero per int (in caso contrario, l'albero
sintattico sar a scorretto).
La grammatica e in forma normale di Bochman e sono veri cate le condizioni di
tipo L, in quanto gli attributi ereditati di ogni regola dipendono al pi u da attributi
di nonterminali fratelli che si trovano pi u a sinistra e dagli attributi ereditati della
parte sinistra della regola. La grammatica e LL(2), a causa delle produzioni 5, 6, 9
e 10. Le altre produzioni veri cano le condizioni LL(1). Costruiamo un valutatore
di attributi a discesa ricorsiva solo per il nonterminale prcd, per il quale e suciente
considerare un valutatore LL(1).
La procedura riceve come parametri di ingresso il valore degli attributi ereditati
di prcd e restituisce in uscita il valore di quelli sintetizzati. La procedura costruisce
l'albero sintattico e intanto valuta gli attributi.

procedure prcd (in envofprcd out aofprcd, updofprcd)


in ingresso: attributi ereditati di prcd *
in uscita: attributi sintetizzati di prcd *
if cc 2 fprocg then
cc:= PROSSIMO
* non ci sono attributi ereditati di pId *
* calcolo attributi sintetizzati di pId: *
pId(valofpId)
if cc 6= "(" then ERRORE
else cc:=PROSSIMO
* non ci sono attributi ereditati di fPar *
* calcolo attributi sintetizzati di fPar: *
call fPar(numoffPar)
if cc 6= ")" then ERRORE
else cc:= PROSSIMO
* calcolo attributi ereditati
di cll: *
S
envofcll := envofprcd f(valofpId numofpId)g
* calcolo attributi sintetizzati di cll: *
call cll(envofcll, aofcll)
* calcolo attributi sintetizzati di prcd: *
updofprcd := f(valofpId numofpId)g
aofprcd := aofcll ^ valofpId 2 nomi(envofprcd)
endif
endif
else ERRORE
endif
end prcd
79

7.4 Esercizio
Descrivere un insieme di attributi per la grammatica dell'esercizio 5.1 in modo da
calcolare, come attributo dofS , la profondit a di un albero di derivazione della grammatica. Mostrare una traccia di funzionamento di un automa a pila a spostamento e
riduzione per l'analisi sintattico-semantica integrata sulla frase acb.

Soluzione 7.4

La grammatica ad attributi e:

8>
>> 1)S ! aTb
< 2)S ! c
G = > 3)T ! DSb
>> 4)T ! c
: 5)D ! a

8> 1)dofS := dofT + 1


>< 2)dofS := 1
>> 3)dofT := 1 + dofS
: 4)dofT := 1
La grammatica ad attributi e di tipo elementare, in quanto tutti gli attributi sono
sintetizzati, ogni attributo dofX dipende solo dagli attributi della parte destra o da
attributi sintetizzati di X0, e la grammatica e in forma normale di Bochman. Si pu o
pertanto usare l'automa a spostamento e riduzione presentato per l'esercizio 5.1, che
nelle mosse di riduzione per produzioni del tipo X !  salva sulla pila i valori degli
attributi del nonterminale X . Nei successivi passi di riduzione i valori degli attributi
di X e degli altri nonterminali salvati sulla pila possono essere utilizzati per il calcolo
degli attributi dei nonterminali di sinistra delle produzioni ridotte.
Una traccia di esecuzione sulla stringa acb e riportata in Tabella 10. Si osservi che
il calcolo di dofS quando si riduce S ! aTb richiede la conoscenza degli attributi di
T , che per o sono sulla pila.
7.5 Esercizio
Si consideri il linguaggio delle parentesi dato dalla seguente grammatica:

8> 1)S ! (S )S
>> 2)S ! T  S
><
S!
G = > 3)
4)
>> T ! aT
>: 5)T ! bT
6)T ! 

80

I0
I0 a
- I0 a
- I0 a
- I0 a
- I0 S
- d=2

Pila

I2
I2 c I8
- - I2 T I5
- d=1
I2 T I5 b I7
- d=1 - I1 . I3
- - - -

Nastro di ingresso
a c b .

azione
sposta I2

b .

sposta I8

b .

riduci T ! c
dofT := 1
sposta I7

b .
.

riduci S ! aTb
dofS := dofT + 1
accetta

Table 10: Traccia del funzionamento dell'automa di Tabella 1 sulla stringa acb.
Un esempio di frase e:
(abb ab (aab aba )abbb ()a aa )
Si costruisca una grammatica ad attributi tale per cui il linguaggio generato coincide con le stringhe di L(G) per le quali tutti gli identi catori (cioe le stringhe di a e
di b) che si trovano allo stesso livello di annidamento siano distinti.
Ad esempio, la frase precedente e corretta, mentre la seguente non lo e:
(abb ab (aab aba )abbb (aab )a aa )
in quanto vi sono due sottostringhe aab allo stesso livello di annidamento (il secondo).

Soluzione 7.5

La soluzione fa uso di due attributi ereditati, env e lev. L'attributo env ha come
valore un insieme di coppie (identificatore livello) lev e costituito da un numero
naturale che rappresenta il livello di annidamento. Vi sono poi gli attributi sintetizzati
a, che pu o assumere un valore booleano che denota la correttezza semantica di una
frase, upd, che contiene una coppia (identificatore livello), e val che e la stringa
associata a un identi catore.
La grammatica ad attributi e G per la parte sintattica, a cui corrispondono gli
opportuni assegnamenti degli attributi.
envofS e inizializzato con l'insieme vuoto, levofS con il numero zero.
81

8
>> 1)S0 ! (S1 )S2
>>
>>
>>
>>
>>
>>
>> 2)S0 ! T  S1
>>
<
Ga = >
>>
>>
>> 3)S ! 
>>
>>
>> 4)T0 ! aT1
>> 5)T0 ! bT1
>>
>: 6)T ! 

levofS1 := levofS0 + 1
levofS2 := levofS0
envofS1 := envofS0
envofS2 := envofS0
updofS1
updofS0 := updofS1
updofS2
aofS0 := aofS1 ^ aofS2
levofS1 := levofS0
updofT := f(valofT levofS0)g
envofS1 := envofS0
updofT
updofS0 := f(valofT levofS0)g
updofS1
aofS0 := aofS1 ^ (valofT levofS0) 62 envofS0
updofS := 
aofS := true
valofT0 := a  valofT1
valofT0 := b  valofT1
valofT := 

La grammatica veri ca che gli identi catori allo stesso livello siano distinti, confrontando l'attributo upd con l'attributo env.
Si osservi che questo tipo di confronto non e lo stesso dei linguaggi di programmazione che ammettono procedure annidate, in quanto il confronto in questo caso
considera solo il livello di annidamento, mentre nei linguaggi di programmazione anche l'annidamento stesso.
7.6 Esercizio
E data la grammatica ad attributi GX di g. 33.
Si decida se la grammatica risulta valutabile in una sola scansione, e in tal caso
si costruisca la corrispondente procedura di valutazione. Si ipotizzi che gli attributi
siano inizializzati correttamente.

Soluzione 7.6

Anch e gli attributi di una grammatica possano essere valutati in una sola scansione, e necessario e suciente che siano soddisfatte le seguenti condizioni per ciascuna
produzione P : A0 ;! A1 : : : Ar :
1. Il grafo delle dipendenze funzionali dipP , 8P : A0 ;! A1 : : : Ar e tale per cui:
(a) dipP e aciclico
(b) Non esistono cammini da un attributo sintetizzato di Ai a un attributo
ereditato dello stesso Ai 
82

1: X0

X0

2: X

YX1
1

a
1

k
g

X1

bY1

3: Y0

Y0

4: Y

c
Y

p
m

bY1

Figure 33: Grammatica ad attributi GX


(c) Non esistono dipendenze di attributi ereditati di Ai da un attributo sintetizzato di A0 .
2. Il grafo fraP dei fratelli e aciclico per ogni P .
La grammatica GX soddisfa tutte queste condizioni. In particolare valutiamo il
punto (2): l'attributo di Y nella produzione (1:) dipende da attributi di X1, per
cui si costruisce un ordine topologico in cui X  Y . Non vi sono poi altre occorrenze
di relazioni di precedenza.
L'ordine topologico per gli attributi ereditati e immediato, visto che vi e un solo
attributo ereditato e bisogna rispettare la condizione appena vista. Per quanto riguarda gli attributi sintetizzati, si pu o scegliere un ordine topologico in cui 1  2 ,
ma l'ordine e indierente, visto che entrambe le possibilit a vanno bene.
Realizziamo il codice della procedura di visita, ipotizzando che ofX sia iniazializzato a 1:

program
procedure RX (in of X0 , T  out 1 of X0, 2 of X0)
case alternativa(T ) of
1:

calcola in ordine topologico gli attributi ereditati di X1 :

83

of X1

2:

endcase
end RX 

:=

f ( of X0 )

calcola attributi sintetizzati di X1 :


RX ( of X1, T1, 1 of X1, 2 of X1 )
calcola in ordine topologico gli attributi ereditati di Y :
of Y := h( of X1, 1 of X1)
calcola attributi sintetizzati di Y :
RY ( of Y , T2  2 of Y )
calcola in ordine topologico gli attributi sintetizzati di X0
1 of X0 := g(1 of X1 )
2 of X0 := i( of Y , 2 of Y )
1 of X0 := k( of X0)
2 of X0 := 9

procedure RY (in of Y0, T  out 2 of Y0)


case alternativa(T ) of
3:
4:

endcase
end RY 

of Y1 := m( of Y0)
RY ( of Y1, T1, 2 of Y1)
2 of Y0 := n(2 of Y1)
2 of Y0 := p( of Y0)

Leggi l'albero T0

RX (1,T0  1 of X , 2 of X )
emetti il valore di 2 of X

end

7.7 Esercizio
E data la grammatica ad attributi GX di g. 34.
Si decida se la grammatica risulta valutabile in una o pi u scansioni.
0

Soluzione 7.7

La grammatica non e ad una scansione perch e l'attributo of X1 dipende da 


of X1. Le altre condizioni risultano per o veri cate:
 Il grafo delle dipendenze funzionali dipP , 8P : A0 ;! A1 : : : Ar e aciclico.
 Non esistono dipendenze di attributi ereditati di Ai da un attributo sintetizzato
di A0.

84

1: X0

X0

2: X

YX1
1

a
1

k
g

X1

bY1

3: Y0

Y0

4: Y

c
Y

p
m

bY1

Figure 34: Grammatica ad attributi GX


0

 Il grafo fraP dei fratelli e aciclico per ogni P .

Per valutare se la grammatica risulta valutabile in pi u scansioni bisogna costruire


il grafo semplice delle dipendenze (Figura 35).

Figure 35: Grafo semplice delle dipendenze per la grammatica GX


0

Il grafo risulta aciclico, quindi i componenti connessi massimali sono costituiti dai
semplici nodi visto che il grafo e costituito da 3 nodi, la grammatica sar a valutabile al
massimo con 3 scansioni. Non e dicile intuire che e possibile accorpare le scansioni
per e per 2 , in quanto la dipendenza "proibita" era solo fra e sigma1.
Per la scansione che calcola 1 , qualunque ordinamento topologico dei fratelli e
degli attributi va bene. Per la scansione che calcola e 2 e necessario scegliere, per la
85

produzione X ! Y X , l'ordine topologico derivato dal graf o semplice di dipendenza


e: X  Y .
7.8 Esercizio
E data la grammatica ad attributi GX di g. 36.
00

t1

t2

Figure 36: Grammatica ad attributi GX


00

Si decida se la grammatica risulta valutabile in una o pi u scansioni, e in tal caso


si costruisca la corrispondente procedura di valutazione.

Soluzione 7.8

La grammatica e valutabile con una scansione. Infatti:


1. Il grafo delle dipendenze funzionali dipP , 8P : A0 ;! A1 : : : Ar e tale per cui:
(a) dipP e aciclico
(b) Non esistono cammini da un attributo sintetizzato di Ai a un attributo
ereditato dello stesso Ai 
(c) Non esistono dipendenze di attributi ereditati di Ai da un attributo sintetizzato di A0 .
2. Il grafo fraP dei fratelli e aciclico per ogni P .

86

L'ordine topologico dei fratelli da utilizzare nella scansione e f S , X g, mentre per


quanto riguarda gli attributi non c' e un problema di ordinamento in quanto esiste un
unico attributo sintetizzato ed un unico attributo ereditato per ogni non-terminale.
La procedura di visita sar a:

procedure S (in a of S0, T  out c of S0 )


case alternativa(T ) of
S ;! XS :

S ;! t1:

endcase

a of S1 := f1(a of S0 )
S (a of S1 , T1 , c of S1)
b of X := f2(c of S1)
X (b of X , T2  d of X )
c of S0 := f3(d of X )
c of S0

:=

f4(a of S0)

end S 

procedure X (in b of X , T  out d of X )


d of X

end Y 

:=

f5(b of X )

7.9 Esercizio
Di ognuna delle seguenti grammatiche, di cui sono dati i gra delle dipendenze funzionali, si dica:
 se la grammatica e ben formata, ovvero se tutti gli attributi risultano senza
ambiguit a sintetizzati o ereditati
 se e nella forma normale di Bochmann
 se e della classe L
 se e valutabile con una scansione
 se e valutabile con un numero sso di scansioni.

Si supponga che gli attributi siano inizializzati in modo opportuno

7.9.1 Grammatica (i)


Soluzione 7.9.1
87

XY
Y

Y
a

t1
Y

X
a

t1

t2
X

t2

Figure 37: Grammatica (i)


 No, la grammatica non e ben formata perche l'attributo a risulta sia sintetizzato
(per le dipendenze nelle produzioni Y ;! XY e Y ;! t1) che ereditato (per
la dipendenza nella produzione S ;! Y ). Per rendere corretta la grammatica,
eliminiamo la dipendenza che compare nella produzione S ;! Y , rendendo
l'attributo a sintetizzato. Si noti che se invece si invertisse il verso della freccia,
si otterrebbe uniformit a nella classi cazione degli attributi, ma la grammatica
risulterebbe ugualmente scorretta in quanto ciclica.
 La grammatica modi cata e nella forma normale di Bochmann.
 Non e della classe L, in quanto in Y ! XY c' e attributo dofX che dipende da

aofX
 La grammatica modi cata e calcolabile con una scansione, scegliendo, per la
produzione Y ! XY , l'ordine fra fratelli Y  X .

7.9.2 Grammatica (ii)


Soluzione 7.9.2
 La grammatica e ben formata.
 La grammatica e nella forma normale di Bochmann.
 La grammatica non appartiene alla classe L, perche esiste una dipendenza del
primo glio dal secondo nella produzione S ! Y X .
 La grammatica non e valutabile con una scansione. Infatti, c' e un ciclo (X !
Y ! X ) nel grafo dei fratelli della produzione S ! Y X .
 Disegnando il grafo semplice delle dipendenze (rappresentato in Figura 39), si
osservano due sottogra connessi massimali, evidenziati in Figura 40. Si pu o
quindi determinare se gli attributi di ogni componente sono valutabili con una

88

S
b

YX

zY

Y
b

zY

wX

wX

w
X

Figure 38: Grammatica (ii)


scansione. In entrambi i componenti, il grafo dei fratelli di S ! Y X risulta
aciclico (con il singolo arco Y ! X per il primo componente, e il singolo arco
X ! Y per il secondo). La coppia di attributi fb cg e quindi valutabile con
una scansione che scende prima nel ramo Y e poi analizza il ramo X , mentre
la coppia di attributi fa dg e valutabile da una scansione successiva che scende
invece prima nel ramo X per poi analizzare il ramo Y . Le due scansioni in
questo caso sono caratterizzate da ordini di visita dierenti. Si osserva inoltre
che le due scansioni non possono essere accorpate (altrimenti la grammatica
risulterebbe ad una scansione, cosa che abbiamo mostrato non possibile).

7.9.3 Grammatica (iii)


Soluzione 7.9.3
89

Figure 39: Grafo semplice delle dipendenze per la Grammatica (ii)


c

scm1

scm2

Figure 40: I sottogra connessi massimali del grafo semplice delle dipendenze per la
Grammatica (ii)
 La grammatica e ben formata, a patto che gli attributi d of X in S ! X e b of
X in S ! XT2 siano inizializzati.
 La grammatica e nella forma normale di Bochmann.
 La grammatica non e valutabile con una scansione e quindi non appartiene
nemmeno alla classe L, in quanto vi sono, in S ! X e S ! Xt2 , attributi
ereditati che dipendono da attributi sintetizzati dello stesso nonterminale. Un
valutatore semantico non sarebbe quindi in grado di calcolare tutti gli attributi
ereditati di X prima di tutti gli attributi sintetizzati.
 Disegnando il grafo semplice delle dipendenze (rappresentato in Figura 42), si
osserva un unico sottografo connesso massimale che racchiude tutti gli attributi. La grammatica non e quindi valutabile neanche con un numero superiore
di scansioni. La grammatica presenta un ciclo nel grafo approssimato delle
dipendenze, ma in eetti la grammatica e valutabile, in quanto i gra delle dipendenze funzionali sono aciclici ci o si pu o veri care costruendo i gra delle
dipendenze per ognuna delle quattro frasi (t3 t4 t3 t2 t4 t2) generate dalla grammatica. Questo comportamento anomalo della grammatica e giusti cato dal
fatto che per ogni albero della grammatica c' e un proprio ordinamento topologico, non compatibile ocn quello di altri alberi. Ad esempio, per S ! X ! t3
l'unico ordinamento e abc, mentre per S ! Xt2 ! t4t2 l'ordinamento e cda.
Si tratta pertanto di un caso degenere, abbastanza raro nella pratica, in cui il
metodo di valutazione multiscansione fallisce, anche quando la grammatica non
e ciclica.

90

X t2

t3

X t2

t4

t3

t4

Figure 41: Grammatica (iii)


b

Figure 42: Grafo semplice delle dipendenze per la Grammatica (iii)

7.9.4 Grammatica (iv)


Soluzione 7.9.4
 La grammatica e ben formata.
 La grammatica non e nella forma normale di Bochmann, che richiede che tutti
gli attributi interni (cio e che compaiono a sinistra di un assegnamento) di ogni
produzione dipendano solo da attributi esterni (cio e che compaiono a destra di
un assegnamento). Infatti nell'ambito della produzione Y ;! XY compare la
coppia di assegnamenti:

1. cofX := (aofY0)
2. aofY1 :=  (cofX dofX )
L'attributo cofX e interno (in quanto compare a sinistra di un assegnamento)
e quindi aofY1 e un attributo interno (si trova a sinistra di un assegnamento)
che dipende a sua volta da un interno. Per rendere la grammatica in forma
normale, basta sostituire i due assegnamenti precedenti con:
91

XY

Y
a

t1
Y

X
b

t2
X

t1

t2

Figure 43: Grammatica (iv)


1. cofX := (aofY0)
2. aofY1 :=  ( (aofY0) dofX )
o
 La grammatica appartiene alla classe L.
 La grammatica e quindi anche valutabile con una scansione.
S

t1

t1

Figure 44: Grammatica (v)

7.9.5 Grammatica (v)


Soluzione 7.9.5
 La grammatica e ben formata.
 La grammatica e nella forma normale di Bochmann.

92

t2

t2

Figure 45: Grafo semplice delle dipendenze per la grammatica (v)


 Gli attributi di X nella produzione S ;! X dipendono direttamente dagli attributi sintetizzati di X , e quindi la grammatica non rispetta le condizioni per
essere valutabile in una scansione. Di conseguenza la grammatica non appartiene neanche alla classe L.
 La grammatica non e neanche valutabile in pi u scansioni in quanto non risulta
possibile de nire un ordinamento topologico tra gli attributi che valga per qualsiasi albero sintattico. Costruendo il grafo semplice delle dipendenze si ottiene
infatti un grafo ciclico caratterizzato da un unico grafo connesso massimale (vedi
Figura 45).

Si osserva che costruendo le dipendenze approssimate per la produzione S ;! X


si ottiene il ciclo: a ! b ! c ! d ! a: la grammatica non e neanche assolutamente
aciclica e anche il metodo di Katayama non pu o essere applicato. La grammatica
risulta per o aciclica, in quanto analizzando gli alberi sintattici corrispondenti alle due
frasi del linguaggio non si osserva la presenza di cicli nelle dipendenze degli attributi.
Si tratta ovviamente di un caso degenere.
7.10 Esercizio
E data la grammatica ad attributi GA di g. 46. Nei gra i nomi delle funzioni
semantiche sono scritti a anco degli archi che collegano gli argomenti al risultato
ad es.:
 of Y := h(1 ofX0 ofX1 )
 ofX0 := 1

Si esaminino le dipendenze funzionali e si costruiscano le procedure ricorsive che


valutano gli attributi, usando il metodo di Katayama.

Soluzione 7.10

La grammatica risulta assolutamente aciclica.


Utilizzando il metodo di Katayama costruiamo il seguente programma per il calcolo del valore degli attributi:
93

1: X 0

X1Y

2: X
k

X0

a
7
1

f
h

X1

4: Y

3: Y 0

b Y1

Y0

Figure 46: Grammatica ad attributi GA

program
procedure RX (in of X0, T  out 2 of X )
case alternativa(T ) of
2

1:

2:

endcase
end RX 

RX1 ( of X0, T  1 of X0)


of X1 := f ( of X0 )
of Y := h( of X1, 1 of X0)
RY2 ( of Y , T1 2 of Y )
2 of X := i( of Y , 2 of Y )
2 of X := 7

procedure RX (in of X0, T  out 1 of X0 )


case alternativa(T ) of
1

1:
2:

endcase
end RX 

of X1 := f ( of X0 )
RX1 ( of X1, T1  1 of X1)
1 of X0 := g(1 of X1 )
1 of X0 := k( of X0)

94

Y1

procedure RY (in of Y0, T  out 2 of Y0)


case alternativa(T ) of
2

3:
4:

endcase
end RY 

of Y1 := k( of Y0)
RY2 ( of Y1, T1 2 of Y1)
2 of Y0 := m(2 of Y1)
2 of Y0 := p( of Y0)

Leggi l'albero T0

RX2 (1,T0  2 of X )
emetti il valore di 2 of X

end

7.11

Esercizi proposti

7.11.1 Esercizio

Si deve calcolare per mezzo di una grammatica ad attributi il valore, scritto come
una frazione, di una espressione di numeri frazionari. Ad esempio:
1=3 + 5=2 + 2 + (1=2 + 3)=8 = 29=6
2=(1 + 2=5) + 1=8 = 223=112
(1=2 + 3)=0 = indefinito
L'espressione pu o contenere i numeri interi, gli operatori + e = e le parentesi. Si
progettino la sintassi del linguaggio, gli attributi semantici e le regole semantiche per
il calcolo dell'attributo valore. Si disegni l'albero semantico decorato per il secondo
esempio mostrato. Si indichi quale tecnica di valutazione degli attributi e possibile
impiegare.

7.11.2 Esercizio

Un'agenzia marittima invia all'armatore dei telex codi cati per annunciare la partenza
dal porto (sigle NA, LI, GE, VE, TS, ...) di una o pi u navi. Ciascuna nave e
individuata da un nome e dal prossimo porto di destinazione e contiene un insieme
di container. Ogni container e individuato da un numero intero e da un porto di
destinazione. All'arrivo, il telex deve essere controllato e decodi cato. Ad esempio,
il telex: NA (LAURA LI (1235 LI, 78990 GE)), (COSTA TS (67 TA, 3345 AN, 7899
VE)) deve essere tradotto nel messaggio:
"Da Napoli parte LAURA per Livorno con 2 container: 1235 per Livorno, 78990
per Genova parte COSTA per Trieste con 3 container: 567 per Taranto, 3345 per
Ancona, 7899 per Venezia".
95

Si de nisca una sintassi per i telex e uno schema di traduzione ad attributi per
controllare il telex (non possono esservi due navi con lo stesso nome, ne due container
con lo stesso numero, ecc.) e per stampare il messaggio in chiaro.
Si costruisca almeno in parte il programma che calcola la traduzione de nita dallo
schema.

7.11.3 Esercizio
Si progetti una grammatica (oppure uno schema di traduzione) ad attributi per
calcolare la derivata @=@x di una espressione. Una espressione e un polinomio i
cui termini possono essere costanti intere (ad esempio 4 o 19), potenze della variabile x (ad esempio, x, x2 x3 : : :) o prodotti di costanti e potenze. Ad esempio,
@=@x(x2 + 5x3 ) = 2x + 15x2 .
Nel calcolo della derivata e possibile non sempli care le espressioni, lasciando
anche termini o fattori inutili, come ad esempio 1x.
Si modi chi la grammatica in modo che i termini possano contenere anche funzioni
trigonometriche e loro potenze, come in x2 sin(x) + 3x4 cos3(x).

7.11.4 Esercizio

Si consideri la grammatica ad attributi Ga:


1: S ;! X
2: X0 ;! X1 Y
3: X ;! Y
4: Y ;! a

 of S := g1( of X )
 of X := h1 ( of X )
 of X0 := f2( of X1 ,  of Y )
 of X0 := g2( of X0,  of X1 ,  of Y )
 of X1 := h2( of Y )
 of Y := h3( of X0)
 of X := f3 ( of Y )
 of X := g3( of Y )
 of Y := h3( of X )
 of Y := cost
 of Y := g4( of Y ,  of Y )

1. Si indichino gli attributi sintetizzati ed ereditati. Si veri chi se Ga e in forma


normale di Bochmann. Si veri chi se Ga e assolutamente aciclica, e se e valutabile in una o pi u passate.
2. Si costruiscano le procedure semantiche del valutatore degli attributi.

7.11.5 Esercizio

E data la seguente grammatica ad attributi


96

1: Z ;! X
2: X0 ;! Y X1

3: Y ;! X
4: X ;! ab

c of X := 0
a of X := 0
f of Z := b of X + d of X
c of X1 := c of X0
d of X0 := d of X1
a of X1 := a of X0 + d of Y + d of X1
c of Y := a of X0
e of Y := d of Y
b of X0 := b of Y + b of X1
a of X := e of Y + c of Y
c of X := c of Y
b of Y := b of X
b of X := a of X
d of X := c of X

1. Si determini di quale tipo sono le dipendenze funzionali tra gli attributi (L, S,
a pi u passate, assolutamente aciclica, aciclica).
2. Si costruisca un valutatore degli attributi con una tecnica appropriata, supponendo noto l'albero sintattico.

97

Potrebbero piacerti anche