Sunteți pe pagina 1din 132

Limbaje Formale si Tehnici de Compilare

Dragan Mircea
April 19, 2006

PREFAT
A
Materialul prezentat constituie notele de curs tinute studentilor din primii
doi ani la Sectia Informatica a Facultatii de Matematica si Informatica de la
Universitatea de Vest Timisoara.
In primul capitol, Introducere se trec n revista notiunile fundamentale din
teoria limbajelor formale si se prezinta problema generala a compilarii.
Capitolul al doilea, Limbaje regulate si analiza lexical
a, prezinta chestiunile
teoretice fundamentale privind teoria automatelor si echivalenta cu limbajele de
tipul trei, proprietati speciale si mecanisme echivalente cu automatele finite. Sunt
prezentate de asemenea si principiile analizei lexicale, finalizate cu realizarea unui
analizor lexical.
Capitolul al treilea, Limbaje independente de context este dedicat studiului
teoretic al mecanismelor de generare si de recunoastere a limbajelor de tipul
doi. Sunt prezentate formele normale ale gramaticilor independente de context
si cateva proprietati speciale.
Capitolul patru, Analiza sintactica este dedicat prezentarii principiilor generale de analiza sintactica si a algoritmilor specializati de analiza. Pentru fiecare
tip de algoritm analizat s-au considerat exemple practice de aplicare.
Capitolul al cincilea, Sinteza programelor trateaza formele intermediare uzuale
pentru traducerea programelor si generarea codului obiect pornind de la formatul intermediar. Pentru cazul expresiilor aritmetice sunt prezentati si algoritmi
directi de generarea a formatului intermediar, mpreuna cu proceduri standard
de optimizare a codului generat.
Ultimul capitol, Masina Turing prezinta succint mecanismul formal ce defineste modelul de calculabilitate.
La sfarsitul fiecarui capitol sunt date cateva exercitii (nerezolvate), aplicatii
directe la chestiunile teoretice prezentate. Acestea pot fi parcurse n cadrul orelor
de seminar si laborator.
In expunerea algoritmilor s-a folosit un limbaj mai putin rigid, fara prea multe
reguli stricte. In general s-a urmarit descrierea cat mai simpla a structurilor care
apar n text.

Cuprins
1 Introducere
1.1 Limbaje formale . . . . . . . . . . . .
1.2 Gramatici generative de tip Chomsky
1.3 Ierarhia Chomsky . . . . . . . . . . .
1.4 Traducerea programelor . . . . . . .
1.5 Probleme propuse . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

5
5
8
12
17
20

2 Limbaje Regulate si Analiza Lexical


a
2.1 Automate finite si limbaje regulate . . . .
2.2 Proprietati speciale ale limbajelor regulate
2.3 Expresii regulate si sisteme tranzitionale .
2.4 Analiza lexicala . . . . . . . . . . . . . . .
2.5 Probleme propuse . . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

23
23
29
34
37
48

3 Limbaje Independente de Context


3.1 Arbori de derivare . . . . . . . . . . . . .
3.2 Ambiguitate n familia L2 . . . . . . . . . .
3.3 Forme normale pentru gramatici de tipul 2
3.4 Lema BarHillel . . . . . . . . . . . . . . .
3.5 Automate push-down (APD) . . . . . . . .
3.6 Automate pushdown deterministe . . . .
3.7 Probleme propuse . . . . . . . . . . . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

51
51
54
56
62
65
73
76

.
.
.
.
.
.
.
.

79
80
80
81
84
90
90
92
93

4 Analiza Sintactic
a
4.1 Algoritmi TOP-DOWN . . . . . . . . . . . . . . . . . . . .
4.1.1 Algoritmul general de analiza top-down . . . . . . .
4.1.2 Analiza top-down fara reveniri . . . . . . . . . . . .
4.1.3 Programarea unui analizor sintactic. Studiu de caz
4.2 Algoritmi BOTTOM-UP . . . . . . . . . . . . . . . . . . .
4.2.1 Gramatici cu precedenta simpla . . . . . . . . . . .
4.2.2 Relatii de precedenta . . . . . . . . . . . . . . . . .
4.2.3 Proprietati ale gramaticilor cu precedenta simpla .
3

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

CUPRINS
4.2.4
4.2.5
4.2.6
4.2.7
4.2.8
4.2.9

Determinarea relatiilor de precedenta pentru gramatici cu


precedenta simpla . . . . . . . . . . . . . . . . . . . . . . . 95
Studiu de caz . . . . . . . . . . . . . . . . . . . . . . . . . 95
Gramatici operatoriale . . . . . . . . . . . . . . . . . . . . 97
Gramatici operatoriale . . . . . . . . . . . . . . . . . . . . 100
Determinarea relatiilor de precedenta pentru gramatici operatoriale . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Studiu de caz . . . . . . . . . . . . . . . . . . . . . . . . . 104

5 Sinteza Programelor
5.1 Forme interne ale programelor . . . . . . . . . . . . . . . .
5.1.1 Tabelele compilatorului . . . . . . . . . . . . . . . .
5.1.2 Cvadruple si triplete . . . . . . . . . . . . . . . . .
5.2 Generarea formatului intermediar . . . . . . . . . . . . . .
5.2.1 Generarea cvadruplelor . . . . . . . . . . . . . . . .
5.2.2 Generarea tripletelor . . . . . . . . . . . . . . . . .
5.2.3 Generarea sirului polonez . . . . . . . . . . . . . .
5.3 Generarea formatului intermediar pentru instructii clasice .
5.3.1 Instructiunea de atribuire . . . . . . . . . . . . . .
5.3.2 Instructiunea If . . . . . . . . . . . . . . . . . . . .
5.3.3 Variabile indexate . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

107
107
107
109
114
115
117
118
121
121
121
121

6 Masina Turing
123
6.1 Limbaje de tipul zero . . . . . . . . . . . . . . . . . . . . . . . . . 123
6.2 Masina Turing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

Capitolul 1
Introducere
1.1

Limbaje formale

Notiunea general
a de limbaj. Se numeste alfabet sau vocabular orice multime
finita si nevida. Elementele unui alfabet V le vom numi simboluri (sau litere,
caractere, variabile).
Definitie 1.1 Un cuv
ant peste un alfabet V este o secvent
a p = a1 a2 . . . an , ai
V, i = 1, . . . , n.
Numarul n, deci numarul simbolurilor cuvantului p, se numeste lungimea cuvantului
si va fi notat cu |p| sau l(p). Vom considera si cuvantul vid sau e, care nu contine
nici un simbol; evident || = 0.
Notiunea de cuv
ant este fundamentala n teoria limbajelor formale sau n alte
domenii ale informaticii; termeni sinonimi utilizati n literatura sunt propozitie,
fraz
a sau sir. Sa observam ca nu exista o similitudine foarte buna ntre notiunile
de alfabet, cuvant, etc. din teoria limbajelor formale si notiunile corespunzatoare din lingvistica.
Multimea tuturor cuvintelor peste un alfabet V o notam cu V + . Aceasta
multime mpreuna cu cuvantul vid va fi notata cu V . In general, vom utiliza
litere mari de la sfarsitul alfabetului pentru notarea diverselor alfabete, U, V, W,
etc.; litere de la nceputul alfabetului (mari sau mici) pentru notarea simbolurilor,
A, B, C, . . . , a, b, c, . . . , i, j, . . . (uneori cifre 0,1,2,...); pentru notarea cuvintelor
vom utiliza litere mici de la sfarsitul alfabetului, p, q, r, s, t, u, v, w, x, y, z, etc.
(aceasta conventie de notare nu va fi absoluta).
Fie p = a1 . . . an , q = b1 . . . bm . Definim pe multimea V operatia de concatenare sau juxtapunere prin pq = a1 . . . an b1 . . . bm .
Se poate verifica usor ca aceasta operatie este asociativa. Prin urmare,
multimea V + nzestrata cu aceasta operatie este un semigrup (semigrupul liber
peste V ). Multimea V cu aceiasi operatie este un semigrup cu unitate, deci un
monoid, unitatea fiind cuvantul vid (monoidul liber peste V ). Structura are si
5

CAPITOLUL 1. INTRODUCERE

proprietatea de simplificare la stanga si la dreapta, adica:


ua = uba = b, respectiv, au = bua = b, a, b, u V
Fie din nou p, q V . Vom spune ca q este un subcuvat sau un infix (propriu)
al lui p daca p = uqv, u, v V (u, v V + ); q este prefix (propriu) al lui p daca
p = qv, v V (v V + ); q este sufix (propriu) al lui p daca p = uq, u V (u
V + ).
Definitie 1.2 Un limbaj L peste alfabetul V este o parte a multimii tuturor
cuvintelor peste V , deci L V .
Sa observam ca V (sau V + ) este ntotdeauna o multime infinita (evident
numarabila); n aceasta acceptiune generala, un limbaj poate sa fie o multime
finita sau infinita, uneori chiar vida.
Exemplu. Fie V = {0, 1}. Avem
V + = {0, 1, 00, 01, 10, 000, . . .},
V = {, 0, 1, 00, 01, 10, 000, . . .}.
Limbaje peste alfabetul V sunt de exemplu multimile
L1 = {, 00, 11},
L2 = {1, 11, 111, . . .} = {1n |n 1}.
Observatie. Notatia an , unde a este un simbol al unui alfabet, nseamna
cuvatul constituit din n simboluri a, adica aa
. . . a}. In particular a0 = .
| {z
Operatii cu limbaje Limbajele fiind multimi se pot efectua cu limbaje operatiile obisnuite cu multimi: reuniune, intersectie, diferent
a, complementariere

(fat
a de V ). Exista si operatii specifice limbajelor.
In general, o operatie de n-aritate oarecare (cel mai adesea binara sau unara)
pe multimea V defineste o operatie corespunzatoare pe multimea limbajelor.
Astfel, daca
: V P(V ) si : V V P(V )
sunt doua operatii pe V (unara si respectiv binara) si L1 , L2 sunt doua limbaje
peste V , putem defini limbajele (L1 ) respectiv (L1 , L2 ) prin
(L1 ) =

[
xL1

Exemple:

(x), (L1 , L2 ) =

[
xL1 ,yL2

(x, y).

1.1. LIMBAJE FORMALE

1. Produsul (concatenarea) a doua limbaje definit prin


L1 L2 = {pq|p L1 , q L2 }.
Daca L1 = L2 = L vom nota LL = L2 . Prin recurenta, se defineste Ln
astfel
L0 = {}, Lk = Lk1 L, k 1.

2. Inchiderea
(Kleene) a unui limbaj L este
L =

Lk .

k=0

3. Limbajul Sub(L). Fie V si Sub(x) multimea tuturor subcuvintelor lui x


(evident Sub este o operatie unara pe V ). Daca L este un limbaj peste V ,
putem defini limbajul
[

Sub(L) =

{Sub(x)}.

xL

adica limbajul constituit din toate subcuvintele tututor cuvintelor lui L.


Semnificatii analoage vor avea si limbajele P ref (L) si Suf (L).
4. Limbajul M i(L). Fie x = a1 . . . an un cuvant peste alfabetul V . Cuvantul
M i(x) = an . . . a1 se numeste r
asturnatul sau oglinditul lui x (M i este prescurtarea cuvantului englez mirror). Se mai noteaza M i(x) = x. Avem
atunci si rasturnatul unui limbaj
[

M i(L) =

{M i(x)}.

xL

5. Operatia de substitutie. Fie U si V doua alfabete si fie aplicatia s : V


P(U ). Extindem (prelungim) aceasta aplicatie la V prin
s() = {}, s(xy) = s(x)s(y), x, y V .
O astfel de prelungire se numeste canonica; ea pastreaza operatia de concatenare, n sensul ca daca p = xy, atunci s(p) = s(x)s(y) este concatenarea
limbajelor s(x), s(y). Operatia de substitutie a limbajelor este data de
s(L) =

s(x).

xL

Sa observam ca aceasta operatie transforma un limbaj peste un alfabet V


ntr-un limbaj peste un alfabet U si ca pastreaza operatia de concatenare.
Daca card(a) < , a V , vom spune ca substitutia este finita, iar daca
card(a) = 1, a V vom spune ca s este un homomorfism.
Operatiile reuniune, produs si nchidere Kleene se mai numesc operatii regulate asupra limbajelor.

CAPITOLUL 1. INTRODUCERE

1.2

Gramatici generative de tip Chomsky

Un limbaj peste un alfabet poate sa fie o multime finita sau infinita. Daca este o
multime finita, el poate fi definit prin scrierea efectiva a cuvintelor limbajului. In
cazul n care este o multime infinita, el poate fi definit n anumite cazuri punand
n evidenta structura cuvintelor lui. De exemplu
L2 = {01, 0011, 000111, . . .} = {0n 1n |n 1}.
Exista doua procedee mai generale pentru definirea limbajelor:
1. Procedee generative, care permit generarea tuturor cuvintelor limbajului.
Exista mai multe tipuri de mecanisme de generare a limbajelor, ntre care
gramaticile Chomsky, sisteme Lindenmayer,etc.
2. Procedee analitice, care determina daca un cuvant dat apartine sau nu
limbajului. Sunt asa-numitele automate, automate finite, automate pushdown, etc.
Un rol deosebit n teoria limbajelor formale l au gramaticile Chomsky.
Notiunea de gramatic
a Fie VN si VT doua alfabete disjuncte,VN VT =
numite respectiv alfabetul simbolurilor neterminale (VN ) si alfabetul simbolurilor
terminale (VT ). Notam VG = VN VT alfabetul general si P VG VN VG VG
alfabetul regulilor.
Multimea P va fi deci formata din perechi de forma (u, v), unde u = u0 Au00 ,
0
u , u00 VG , A VN iar v VG , deci u si v sunt cuvinte peste VG , cu observatia
ca u trebuie sa contina cel putin un simbol neterminal. Vom spune ca o astfel
de pereche este o regul
a (productie, regula de generare, regula de rescriere) si o
vom nota u v (vom spune: u se transforma n v). Apartenenta unei reguli la
P o vom nota n mod obisnuit (u v) P , sau mai simplu, u v P (nu va
exista confuzia cu faptul ca v este un element al lui P ).
Definitie 1.3 O gramatic
a este un sistem G = (VN , VT , X0 , P ), unde VN este
alfabetul simbolurilor neterminale, VT este alfabetul simbolurilor terminale, X0
VN si se numeste simbol de start al gramaticii, iar P este multimea de reguli.
Observatie. Simbolurile alfabetului VN le vom nota n general cu litere mari
A, B, C, . . . , X, Y, Z (mai putin U, V, W ) iar cele ale alfabetului VT cu litere mici
de la nceput a, b, c, . . . sau cu cifre 0, 1, 2, . . ..
a direct n q
Fie G o gramatica si p, q VG . Vom spune ca p se deriveaz
si vom scrie p q (sau mai simplu pq) daca exista cuvintele r, s, u, v VG
G

astfel nct p = rus, q = rvs iar u v P . Vom spune ca p0 se deriveaz


a n p00
(fara specificatia direct) daca exista p1 , p2 , . . . , pn n 1 astfel ncat
p0 = p1 p2 . . . pn = p00 .
G

1.2. GRAMATICI GENERATIVE DE TIP CHOMSKY


+

Vom scrie p0 p00 (sau p0 p00 cand nu exista nici o confuzie) daca n > 1
G
0

00

si p p (sau p0 p00 ) daca n 1. Sirul de mai sus va fi numit derivare iar


G

numarul de derivari directe din sir l vom numi lungimea derivarii; se mai spune
ca p0 deriv
a n p00 .
+

Sa observam ca transformarile astfel definite , , sunt relatii pe VG .


+

Este clar ca relatia este nchiderea tranzitiva a relatiei , iar relatia este
nchiderea tranzitiva si reflexiva a relatiei de transformare directa .
Definitie 1.4 . Limbajul generat de gramatica G este prin definitie multimea

L(G) = {p VT , X0 p}.
G

Observatie. Daca p VG si X0 p se spune ca p este o form


a propozitional
a
G

n gramatica G.
Exemple:
1. Fie G = (VN , VT , X0 , P ), unde VN = {A}, VT = {0, 1}, X0 = A (evident)
si P = {A 0A1, A 01}. O derivare n aceasta gramatica este, de
exemplu
A0A100A11000111 = 03 13 .
Este evident ca L(G) = {0n 1n |n 1}.
Observatie. In cazul n care mai multe reguli au aceeasi parte stanga, le
vom scrie compact astfel u v1 |v2 | . . . |vn , simbolul | avand sensul de sau;
n cazul nostru, A 0A1|01.
2. G = (VN , VT , X0 , P ), unde
VN = {<propozitie>, <subiect>, <atribut>, <predicat>, <complement>,
<substantiv>, <adjectiv>, <verb>, <articol>},
VT = {o, orice, matrice, functie, derivabila, continua, este },
X0 =<propozitie>,
P = {<propozitie><subiect><atribut><predicat><complement>,
<subiect><articol><substantiv>,
<atribut><adjectiv>,
<predicat><verb>,
<complement><adjectiv>,
<articol>o|orice,
<substantiv>matrice|functie,
<adjectiv>derivabila|continua,
<verb>este.
Observatie. In acest exemplu, <propozitie>, <subiect>, etc., reprezinta
fiecare cate un simbol neterminal; de asemenea, o, orice, matrice,

10

CAPITOLUL 1. INTRODUCERE
etc., reprezinta simboluri terminale. Se poate usor observa ca aceasta
gramatica genereaza propozitii simple de forma subiect-atribut-predicatcomplement care exprima judecati asupra conceptelor de matrice si functie.
De exemplu, se poate forma propozitia: orice functie derivabila este continua, care este din punct de vedere semantic corecta, precum si propozitia
orice functie continua este derivabila, care, dupa cum se stie, este falsa.
Evident, se pot genera si numeroase propozitii care nu au sens. Ceea ce ne
intereseaza n acest moment este aspectul formal, deci din punct de vedere
sintactic toate aceste propozitii sunt corecte; semantic, unele propozitii pot
sa fie incorecte sau chiar sa nu aibe sens.
Sa mai observam ca o gramatica Chomsky este n masura sa constituie
un model matematic pentru sintaxa unei limbi, fara sa intereseze aspectele
semantice. Este ceea ce a ncercat sa faca Naom Chomsky pentru limba
engleza n lucrarile sale din anii 050.
3. G = (VN , VT , X0 , P ), unde
VN = {<program>, <instructie>, <atribuire>, <if>, <expresie>, <termen>,
<factor>, <variabila>, <index>},
VT = {begin, end, if, then, stop, t, i, +, *, (, ), =, ,, ; },
X0 =<program>
P = {<program>begin <linie> end
<linie><linie>;<instructie> | <instructie>
<instructie><atribuire> | <if> | stop
<atribuire><variabila>=<expresie>
<if>if( <expresie>) then <atribuire>
<expresie><expresie> + <termen> | <termen>
<termen><termen> <factor> | <factor>
<factor>(<expresie>)| <variabila>
<variabila>t(<index>)|i
<index><index>, <expresie> | <expresie>
Gramatica din acest exemplu defineste un limbaj de programare simplu cu
trei tipuri de instructii: atribuiri, if-then, stop. Expresiile aritmetice au numai operatorii + si *; variabilele pot fi simple sau indexate (tablouri), iar i
tine loc de identificator sau constanta. Mentionam ca definirea n acest mod
a unui limbaj, inclusiv utilizarea crosetelor pentru desemnarea simbolurilor
neterminale, poarta adesea denumirea de notatie Backus Naur; n acest
mod s-a definit limbajul ALGOL60.

Tipuri de gramatici Dupa forma regulilor de generare, gramaticile Chomsky


se mpart n mai multe tipuri; clasificarea obisnuita este urmatoarea:
Gramatici de tipul 0; sunt gramatici fara restrictii asupra regulilor;
Gramatici de tipul 1 (dependente de context); sunt gramatici care au reguli
de forma

1.2. GRAMATICI GENERATIVE DE TIP CHOMSKY

11

uAv upv, u, p, v VG , p 6= , A VN
sau A si n acest caz A nu apare n dreapta vreunei reguli.
Observatie. Evident, regulile de forma a doua au sens numai daca A este
simbolul de start.
Gramaticile de tipul 2 (independente de context); sunt gramatici care au
reguli de forma
A p, A VN , p VG .
Gramaticile de tipul 3 (regulate); sunt gramatici care au reguli de forma
(

A Bp
sau
Cq

A pB
Cq

cu A, B, C VN si p, q VT .
Vom nota cu Lj , j = 0, 1, 2, 3 familiile de limbaje generate de gramaticile
de tipurile j = 0, 1, 2, 3; vom avea astfel limbaje de tipul 0, limbaje de tipul 1
(sau dependente de context) , limbaje de tipul 2 (sau independente de context)
si limbaje de tipul 3 (sau regulate). Sa observam ca este importanta structura
cuvintelor unui limbaj si nu modul n care sunt notate simbolurile terminale. De
exemplu , limbajele
L02 = {0n 1n |n 1}, L002 = {an bn |n 1}
sunt n mod practic identice. Putem utiliza o unica notatie pentru afabetul
simbolurilor terminale , de exemplu , VT = {i1 , . . . , in }. Clasificarea de mai
sus este fundamentala n teoria limbajelor formale, ea a fost introdusa de Naom
Chomsky in 1958 si prin traditie noile clase de limbaje sunt raportate la aceasta
clasificare. O alta clasificare este urmatoarea
Gramatici de tipul 0; fara restrictii;
Gramatici monotone (de tipul 1):
u v, |u| |v|, u, v VG ;
Gramatici dependente de context:
uAv upv, u, p, v VG , p 6= , A VN ;
Gramatici independente de context (de tipul 2):
A p, A VN , p VG ;

12

CAPITOLUL 1. INTRODUCERE
Gramatici liniare:
A uBv, A VN , B VN {} u, v VT ;
Gramatici (stang) drept liniare:
A uB (A Bv), A VN , B VN {} u, v VT ;
Gramatici regulate (de tipul 3); gramatici stang liniare sau gramatici drept
liniare.

Gramaticile monotone ca si cele dependente de context nu pot avea reguli cu


partea dreapta vida. Se introduce urmatoarea conventie de completare: ntro gramatic
a monotona sau dependent
a de context se admite o regula de forma
A cu conditia ca A s
a nu apar
a n partea dreapt
a a vreunei reguli. Dupa
cum vom vedea , existenta sau inexistenta regulilor de forma A , reguli
numite de stergere, poate modifica esential puterea generativa a unei gramatici.
O gramatica n care nu avem astfel de reguli o vom numi gramatic
a liber
a; de
asemenea, un limbaj care nu contine cuvantul vid, l vom numi limbaj liber.
Sa mai observam ca existenta regulilor de stergere ntr-o gramatica nu implica n
mod necesar existenta cuvantului vid n limbajul generat.
Doua gramatici care genereaza acelasi limbaj se numesc echivalente.
Gramaticile monotone si gramaticile dependente de context sunt echivalente;
de asemenea, gramaticile drept si stang liniare sunt echivalente, justificandu-se
astfel clasa gramaticilor regulate.

1.3

Ierarhia Chomsky

Lemele care urmeaza vor avea o utilizare frecventa n cele ce urmeaza.


Lema 1.1 (Lema de localizare a gramaticilor independente de context) Fie G o
gramatic
a independent
a de context si fie derivarea

x1 . . . xm p, unde xj VG , j = 1, m , p VG .
at
Atunci exista p1 , p2 , . . . , pm VG astfel nc

p = p1 . . . pm si xj pj , j = 1, m.
Demonstratie. Procedam prin inductie asupra lungimii derivarii l.
Daca l = 0 atunci p = x1 . . . xm si luam pj = xj .
Presupunem ca proprietatea este adevarata pentru derivari de lungime l si

fie o derivare de lungime l + 1, x1 . . . xm p. Punem n evidenta ultima derivare

1.3. IERARHIA CHOMSKY

13

directa x1 . . . xm qp. Conform ipotezei inductive, q = q1 . . . qm si xj qj , j =


1, . . . , m.
Fie apoi A u regula care se aplica n derivarea directa qp si sa presupunem
ca A intra n subcuvantul qk , deci qk = qk0 Aqk00 . Vom lua
(

pj =

qj
0
qk uqk00

,j =
6 k
,j = k

Este evident ca xj pj , j 6= k, iar pentru j = k avem

xk qk = qk0 Aqk00 qk0 uqk00 = pk .2


Vom pune n evidenta n continuare o proprietate asupra structurii regulilor gramaticilor Chomsky. Partea dreapta a unei reguli, pentru toate tipurile de gramatici, este un cuvant format din terminale sau neterminale. Este convenabil
de multe ori ca partea dreapta a regulilor sa contina un singur tip de simboluri,
terminale sau neterminale. Acest lucru este posibil fara modificarea tipului gramaticii.
Lema 1.2 (Lema A i) Fie G = (VN , VT , S, P ) o gramatic
a de tipul 2. Exista
o gramatic
a G0 echivalent
a, de acelasi tip, cu proprietatea ca daca o regul
a are
n partea dreapt
a un terminal, atunci ea este de forma A i, A VN , i VT .
Demonstratie. Luam gramatica G0 de forma G0 = (VN 0 , VT 0 , S, P 0 ) unde VN 0 si
P 0 se construiesc astfel: VN VN 0 si includem n P 0 toate regulile din P care
convin. Fie acum o regula din P care nu convine (punem n evidenta aparitia
terminalelor din partea dreapta):
u v1 i1 v2 i2 . . . in vn+1 , ik VT , vk VN .
Vom introduce n P 0 urmatoarele reguli:
u v1 Xi1 v2 Xi2 . . . Xin vn+1 , Xik ik , k = 1, n ,
unde Xik sunt neterminale noi pe care le adaugam la VN 0 . Este evident ca G0
pastreaza tipul lui G si ca L(G0 ) = L(G)2.
Observatie. Constructia din lema se poate extinde usor la gramatici de tipul
0, nlocuind si terminalele din partea stanga a regulilor (u poate fi un sir arbitrar
ce contine minim un neterminal). Gramatica astfel obtinuta este echivalenta cu
cea initiala si pastreaza tipul.
Ierarhia Chomsky. Este evident ca L3 L2 si ca L1 L0 , deoarece orice
regula a unei gramatici de tipul 3 respecta prescriptiile unei gramatici de tipul
2; analog pentru familiile L1 si L0 . Aparent, o regula de forma A p (de tipul
2) este un caz particular a unei reguli de forma uAv upv (de tipul 1), pentru

14

CAPITOLUL 1. INTRODUCERE

u = v = ; totusi, realitatea nu este aceasta, deoarece la tipul 2 de gramatici


sunt permise reguli de stergere, pe cand la tipul 1 se impune conditia p 6= . Vom
arata ca avem L2 L1 .
Sirul de incluziuni
L3 L 2 L 1 L 0
poarta denumirea de ierarhia Chomsky (vom arata pe parcursul acestui curs
ca incluziunile sunt stricte). Aceasta ierarhie caracterizeaza puterea generativa
a celor patru tipuri de gramatici, aceasta putere fiind crescatoare de la 3 la 0.
Orice alte mecanisme generative se raporteaza la aceasta ierarhie fundamentala.
Vom demonstra mai ntai urmatoarea lema.
Lema 1.3 (Lema eliminarii regulilor de stergere). Orice limbaj independent de
context -liber poate fi generat de o gramatic
a de tipul 2 far
a reguli de stergere.
Demonstratie. Fie G = (VN , VT , X0 , P ) o gramatica independenta de context si
L(G) limbajul generat. Prin ipoteza 6 L(G). Definim prin recurenta sirul de
multimi Uk astfel:
U1 = {X|X VN , X P }
Uk+1 = {X|X VN , X p P, p Uk } Uk , k 1.
Sa observam ca sirul de multimi definite este crescator n raport cu relatia de
incluziune. Cum toate aceste multimi sunt incluse n VN si VN este finita, rezulta
ca exista o multime maximala Uf astfel astfel ncat
U1 U2 Uf = Uf +1 = .

Are loc de asemenea si implicatia X Uf X .


Vom ilustra aceasta implicatie cu un exemplu. Sa presupunem ca Uf = U3
si fie X U3 . Atunci n mod necesar trebuie sa avem X p P , p U2 ; de
exemplu p = X1 X2 si X1 , X2 U2 . In mod analog X1 Y1 Y2 Y3 , X2 Z1 Z2 si
Y1 , Y2 , Y3 , Z1 , Z2 U1 , prin urmare Y1 , Y2 , Y3 , Z1 , Z2 .
Putem scrie derivarea

XX1 X2 Y1 Y2 Y3 Z1 Z2 .
Definim acum urmatoarea gramatica independenta de context fara reguli de
stergere G0 = (VN , VT , X0 , P 0 ) unde VN , VT , X0 sunt ca n gramatica data, iar P 0
se construieste pornind de la P astfel. Fie X p P, p 6= . Includem atunci
n P 0 aceasta regula precum si toate regulile de forma X pj , unde pj se obtine
din p lasand la o parte, n toate modurile posibile, simbolurile din Uf (se excepta
cazul pj = ). De exemplu daca X ABC P si A, B Uf , vom induce n P 0
regulile
X ABC, X BC, X AC, X C.

1.3. IERARHIA CHOMSKY

15

Sa observam ca n acest fel multimea P a fost pe de o parte micsorata (au fost


excluse regulile de alegere), iar pe de alta parte mbogatita cu eventualele noi
reguli. Sa mai obsevam ca G0 este independenta de context si ca nu contine
reguli de stergere.
Vom arata ca L(G) = L(G0 ).
Mai ntai, sa aratam ca L(G) L(G0 ).

Fie p L(G), deci X0 p; vom arata ca X0 p. Vom arata o implicatie


G0

G0

ceva mai generala, X p implica X p, pentru orice X VN (relatia ceruta


se obtine pentru X = X0 ). Procedam prin inductie asupra lungimii derivarii l.
Daca l = 1 avem
X p deci X p P. Dar p 6= deci X p P 0
G

adica X p.
G0

Presupunem ca afirmatia este adevarata pentru l = n si luam o derivare cu


lungimea l = n + 1. Punem n evidenta prima derivare directa

X X1 . . . Xm p
G

Conform lemei de localizare avem p = p1 . . . pm si Xj pj , j = 1, . . . , m.


G

Unele din cuvintele pj pot sa fie vide; pentru precizarea ideilor sa presupunem ca

p2 , p3 , p5 = . Atunci pentru derivarile Xj pj , j 6= 2, 3, 5, care au lungimea


G

de cel mult n, conform ipotezei inductive avem Xj pj .


G0

Pe de alta parte , pentru j = 2, 3, 5 avem X2 , X3 , X5 ,


deci X2 , X3 , X5 Uf . Rezulta ca
X X1 X4 X6 . . . Xm P 0
asa ncat putem scrie

X X1 X4 X6 . . . Xm p1 p4 p6 . . . pm = p.
G0

G0

Deci X p si luand X = X0 obtinem p L(G0 ). Prin urmare L(G) L(G0 ).


G0

Sa aratam acum incluziunea inversa , L(G0 ) L(G).

Fie p L(G), X0 p. Punem n evidenta o derivare directa oarecare


G0

X0 u v p.
G0

G0

G0

16

CAPITOLUL 1. INTRODUCERE
Daca n derivarea directa u v se aplica o regula care exista si n G, atunci
G0

evident pasul respectiv poate fi facut si n G. Sa presupunem ca se aplica o regula


nou introdusa de exemplu X BC, deci pasul respectiv va avea forma
u = u0 Xu00 u0 BCu00 = v
G0

Regula X BC P 0 a provenit dintr-o regula din P , lasand la o parte simboluri


din Uf , n cazul nostru din X ABC, lasandu-l la o parte pe A Uf . Deoarece

A , avem
G

u = u0 Xu00 u0 ABCu00 u0 ABCu00 = v.


G

Prin urmare orice pas al derivarii considerate se poate obtine si n gramatica G,

deci X0 p si p L(G), adica L(G0 ) L(G)2.


G

Teorema 1.1 L2 L1 .
Demonstratie. Fie L L2 un limbaj independent de context si G o gramatica de
tipul 2 care l genereaza, adica L = L(G).
Presupunem ca L. Construim gramatica G0 ca n lema precedenta; orice
cuvant p 6= din L(G) se poate obtine n G0 si invers , deci L(G0 ) = L(G) {}.
Consideram atunci o gramatica G00 = (VN {X000 }, VT , X000 , P 0 {X000 , X000
X0 }). Evident L(G00 ) = L(G). Toate regulile lui G00 respecta tipul 1 (cu u =
v = ) si contine o singura regula de stergere X000 iar X000 nu apare n partea
dreapta a vreunei reguli. Deci G00 este de tipul 1 si orice limbaj independent de
context este inclus n L1 , adica L2 L1 .2
Fiind data o operatie binara notata cu pe o familie de limbaje L, vom
spuna ca familia L este nchisa la operatia daca L1 , L2 L implica L1 L2
L. Definitia notiunii de nchidere pentru operatii unare sau cu aritate oarecare
este analoaga. Relativ la proprietatile de nchidere a familiilor din clasificarea
Chomsky mentionam urmatorul rezultat.
Teorema 1.2 Familiile Lj , j = 0, 1, 2, 3 sunt nchise la operatiile regulate.
Demonstratie. Fie Gk = (VNk , VTk , Sk , Pk ), k = 1, 2 doua gramatici de acelasi
tip j, j = 0, 1, 2, 3. Putem presupune ca VN1 VN2 = . Trebuie sa aratam ca
limbajele L(G1 ) L(G2 ), L(G1 )L(G2 ), L(G1 ) , sunt de acelasi tip j. In acest
scop vom construi gramatici de tipul j care sa genereze le genereze. Vom indica
fara demonstrtie modul de constructie al gramaticilor (pentru detalii vezi [?]):
Reuniune

1.4. TRADUCEREA PROGRAMELOR

17

j = 0, 1, 2, 3:
G = VN1 VN2 {S}, VT1 VT2 , P1 P2 {S S1 |S2 }).
Produs
j = 0, 1, 2:
G = VN1 VN2 {S}, VT1 VT2 , P1 P2 {S S1 S2 }).
j = 3:
G = VN1 VN2 {S}, VT1 VT2 , S1 , P10 P2 ),
unde P10 se obtine din P1 prin nlocuirea regulilor de forma A p cu A pS2 .

Inchidere
Kleene
j = 0, 1:
G = (VN {S , X}, VT , S , P {S |S|XS, Xi Si|XSi, i VT })
j = 2:
G = (VN {S }, VT , S , P P prime {S S S|})
j = 3:
G = (VN {S }, VT , S , P P prime {S S|})

1.4

Traducerea programelor

Un limbaj de programare este un limbaj care are drept scop descrierea unor
procese de prelucrare a anumitor date si a structurii acestora (n unele cazuri
descrierea structurii datelor este preponderenta), prelucrare care se realizeaza n
general cu ajutorul unui sistem de calcul.
Exista n prezent un numar mare de limbaje de programare de nivel nalt sau
evoluate care se caracterizeaza printr-o anumita naturalete, n sensul ca descrierea
procesului de prelucrare cu ajutorul limbajului este apropiata de descrierea naturala a procesului respectiv precum si prin independenta unor astfel de limbaje
fata de sistemul de calcul. Dintre limbajele de acest tip cu o anumita raspandire
n momentul de fata mentionam limbajele PASCAL, FORTRAN, C, JAVA, etc.
O alta clasa importanta de limbaje, sunt limbajele de asamblare, sau de nivel
inferior, ale caror caracteristici depind de sistemul de calcul considerat. In general, fiecare sistem de calcul (sau tip de sistem de calcul), are propriul sau limbaj de asamblare; de exemplu, limbajul de asamblare ale sistemelor de calcul
echipate cu procesoare de tip Intel Z-80 este denumit n mod curent ASSEMBLER. Instructiile unui limbaj de asamblare corespund cu operatiile simple ale

18

CAPITOLUL 1. INTRODUCERE

sistemului de calcul iar stocarea datelor n memorie este realizata direct de utilizator la nivelul locatiilor elementare ale memoriei. Exista de asemenea anumite
pseudo-instructii sau directive referitoare la alocarea memoriei, generarea datelor,
segmentarea programelor, etc., precum si macroinstructii care permit generarea
unor secvente tipice de program sau accesul la bibliotecile de subprograme.
In afara de limbajele evoluate si de limbajele de asamblare, exista numeroase
limbaje specializate, numite uneori si de comand
a, care se refera la o anumita clasa
de aplicatii. Mentionam de exemplu limbajul pentru prelucrarea listelor LISP,
limbajele utilizate n cadrul softwarelui matematic (Mathematica, Maple, MATCAD, etc.) si multe altele. In general nsa astfel de limbaje nu sunt considerate
limbaje de programare propriuzise.
Un program redactat ntr-un limbaj de programare poarta denumirea de program surs
a. Fiecare sistem de calcul, n functie de particularitatile sale, poseda
un anumit limbaj propriu, numit cod masina, acesta fiind singurul limbaj nteles
de procesorul sistemului. Un astfel de limbaj depinde de structura instructiilor
procesorului, de setul de instructii, de posibilitatile de adresare, etc. Un program redactat n limbajul cod masina al sistemului de calcul l numim program
obiect.
Procesul de transformare al unui program sursa n program obiect se numeste
compilare sau translatare, uneori chiar traducere. De obicei termenul de compilare este utilizat numai n cazul limbajelor evoluate, n cazul limbajelor de
asamblare fiind utilizat termenul de asamblare.
Compilarea (asamblarea) este efectuata de un program al sistemului numit
compilator (asamblor). De multe ori compilatoarele nu produc direct program
obiect, ci un text intermediar apropiat de programul obiect, care n urma unor
prelucrari ulterioare devine program obiect. De exemplu, compilatoarele sistemelor de operare DOS produc un text numit obiect (fisiere cu extensia obj)
care n urma unui proces numit editare de legaturi si a ncarcarii n memorie
devine program obiect propriuzis, numit program executabil (fisiere cu extensia
exe). Exista mai multe ratiuni pentru o astfel de tratare, ntre care posibilitatea
cuplarii mai multor module de program realizate separat sau provenite din limbaje sursa diferite, posibilitatea crearii unor biblioteci de programe n formatul
intermediar si utilizarea lor n alte programe, etc.
Un program sursa poate de asemenea sa fie executat de catre sistemul de
calcul direct, fara transformarea lui prealabila n program obiect. In acest caz,
programul sursa este prelucrat de un program al sistemului numit interpretor;
acesta ncarca succesiv instructiile programului sursa, le analizeaza din punct
de vedere sintactic si semantic si dupa caz, le executa sau efectueaza anumite
operatii auxiliare.
Procesul de compilare este un proces relativ complex si comporta operatii care
au un anumit caracter de autonomie. Din aceste motive procesul de compilare
este de obicei descompus n mai multe subprocese sau faze, fiecare faza fiind o
operatie coerenta, cu caracteristici bine definite. In principiu aceste faze sunt

1.4. TRADUCEREA PROGRAMELOR

19

Program Sursa
Analiza Lexicala

Analiza sintactica

Tratarea
erorilor

Generarea formatului
intermediar

Prelucrarea
tabelelor

Generarea codului

Optimizarea codului
Program Obiect

Figura 1.1: Fazele compilarii


parcurse secvential (pot sa existe si anumite reveniri) iar programul sursa este
transformat succesiv n formate intermediare. Se poate considera ca fiecare faza
primeste de la faza precedenta un fisier cu programul prelucrat ntr-un mod corespunzator fazei respective, l prelucreaza si furnizeaza un fisier de iesire, iarasi
ntr-un format bine precizat, fisier utilizat n faza urmatoare. Exista cinci faze de
compilare principale: analiza lexicala, analiza sintactica, generarea formatului intermediar, generarea codului, optimizarea codului si doua faze auxiliare, tratarea
erorilor si tratarea tabelelor (vezi figura 1.1).
Analiza lexical
a are ca obiectiv principal determinarea unitatilor lexicale ale
unui program, furnizarea codurilor acestora si detectarea eventualelor erori lexicale. Pe langa aceste operatii de baza, la analiza lexicala se mai pot efectua
anumite operatii auxiliare precum: eliminarea blank-urilor (daca limbajul permite utilizarea fara restrictii a acestora), ignorarea comentariilor, diferite conversiuni ale unor date (care se pot efectua la aceasta faza), completarea tabelelor
compilatorului.
Analiza sintactica determina unitatile sintactice ale programului (secvente
de text pentru care se poate genera format intermediar) si verifica programul
din punct de vedere sintactic. Este faza centrala a unui compilator, deseori toate
celelalte faze sunt rutine apelate de analizorul sintactic pe masura ce este posibila
efectuara unei parti din faza respectiva. Tot la analiza sintactica se definitiveaza

20

CAPITOLUL 1. INTRODUCERE

tabelele de informatii si se realizeaza prelucrarea erorilor sintactice.


Faza de generare a formatului intermediar se refera la transformarea programului ntr-o forma numita intermediara pornind de la care se poate, printr-o
procedura relativ simpla, sa se obtina programul obiect. Structura acestei faze
depinde de formatul intermediar ales de catre proiectant si de modalitatea de
implementare; uzual se folosesc cvadruple, triplete sau sirurile poloneze.
Generarea codului este o faza in care se realizeaza codul obiect corespunzator
programului. Practic n aceasta faza se obtine programul n limbaj de asamblare
corespunzator programului sursa redactat ntr-un limbaj evoluat. In mod obisnuit
generatorul de cod este constituit din rutinele generatoare de cod corespunzatoare
diverselor unitati ale formatului intermediar.
In faza de optimizare a codului se realizeaza o anumita mbunatatire a codului
obiect astfel ncat programul rezultat sa fie cat mai performant (n privinta consumului de timp si memorie). Cele mai tipice exemple sunt eliminarea ncarcarilor
si a memorarilor redundante sau optimizarea ciclurilor.
Fazele de Prelucrare a tabelelor si de Tratare a erorilor vor fi atinse numai
partial n aceast curs. Facem nsa mentiunea ca prelucrarea tabelelor poate sa
aiba o influenta importanta asupra performantelor unui compilator, n mod special din punctul de vedere al timpului de executie (compilare) si ca tratarea
erorilor are o anumita implicatie n eliminarea erorilor sintactice.

1.5

Probleme propuse

1. Gasiti limbajul generat de gramatica G = (VN , VT , S, P ), precizand tipul


gramaticii (cf. clasificarii Chomsky):
(a) VN = {S}; VT = {0, 1, 2};
P = {S 0S0|1S1|2S2|0}.
(b) VN = {S}; VT = {a, b};
P = {S aSb|ab}.
(c) VN = {S, A, B}; VT = {a, b, c};
P = {S abc|aAbc, Ab bA, Ac Bbcc, bB Bb, aB
aaA|aa}.
(d) VN = {S, A, C}; VT = {+, , 0, 1, . . . , 9};
P = {S A| + A| A, A AC|C, C 0|1| . . . |9}.
(e) VN = {S, A, B}; VT = {0, 1};
P = {S 0S|1A, A 0B|1S|0, B 0A|1B|1}.
(f) VN = {A}, VT = {a, b}, S = A, P = {A aA|b};
(g) VN = {x0 }, VT = {A, B, . . . , Z}, S = x0 , P = {x0 x1 D,
x1 x2 N, x2 E};

1.5. PROBLEME PROPUSE

21

(h) VN = {A}, VT = {0, 1, 2}, S = A, P = {A 0A0|1A1|2A2|};


(i) VN = {S, A}, VT = {0, 1, . . . , 9, .},
P = {S A.A, A 0A|1A| . . . |9A|0|1| . . . |9};
(j) VN = {S}, VT = {P CR, P DAR, U DM R},
P = {S P CR|P DAR|U DM R};
(k) VN = {A, B, C}, VT = {0, 1}, S = A, P = {A 0A|1B|1,
B 0C|1A, C 0B|1C|0};
(l) VN = {S, A, B, C}, VT = {0, 1, . . . , 9, +, },
P = {S +A| A|A, A 0A|1A| . . . |9A|0|1| . . . |9};
(m) VN = {S}, VT = {(, )}, P = {S S(S)S|};
(n) VN = {E, T, F }, VT = {(, ), i, +, }, S = E,
P = {E E + T |T, T T F |F, F (E)|i};
(o) VN = {S, A, B}, VT = {a, b, c}, P = {S abc|aAbc,
Ab bA, Ac Bbcc, bB Bb, aB aaA|aa};
(p) VN = {S, A, B, C, D, E}, VT = {a}, P = {S ACaB, Ca aaC, CB
DB|E, aD Da, AD AC, aE Ea, AE };
(q) VN = {S, A, B, C, D, E}, VT = {a, b}, P = {S ABC,
AB aAD|bAE, DC BaC, EC BbC, Da aD, Db bD, Ea
aE, Eb bE, AB , C , aB Ba, bB Bb};
2. Precizati care dintre gramaticile precedente sunt echivalente.
3. Gasiti gramatici pentru generarea urmatoarelor limbaje:
(a) L = {};
(b) L = ;
(c) L = {0n |n N };
(d) L = {a, ab, aab, ba, baa}.
(e) L = {an cbn |n 1}.
(f) L = {w {a, b, c} |w contine cc si se termina cu a}.
(g) L = {BEGIN |EN D|IF |W HILE|U N T IL}.
(h) L = {w {0, 1} | reprezentarea binara pe 8 biti a unui ntreg }.
(i) L = {an bn+3 an+1 |n 0}.
(j) L = {w {a, b, c} |w ncepe cu a si are maxim 4 litere }.
(k) L = {ai bj ck |i, j, k > 0}.
(l) L = {w {0, 1} |w multiplu de 8 }.
(m) L = { constante reale n scrierea obisnuita cu punct zecimal pi .pz }.

22

CAPITOLUL 1. INTRODUCERE
(n) L = {ai bj ai bj };
(o) L = {awbbw0 |w, w0 {0, 1} };
(p) L = {w {0, 1} |w contine maxim 2 de 0 };
(q) L = {waw|w
{0, 1} };
(r) L = {w|w octet ce reprezinta un numar par };
(s) L = {A, B, C, . . . , Z};
4. Construiti o gramatica ce contine reguli de stergere, dar genereaza un limbaj
-liber.
5. Folosind teorema sa se construiasca o gramatica independenta de context,
fara reguli de stergere care genereaza limbajul de la punctul precedent.

Capitolul 2
Limbaje Regulate si Analiza
Lexical
a
2.1

Automate finite si limbaje regulate

Automate finite. Automatele finite sunt mecanisme pentru recunoasterea limbajelor de tipul 3 (regulate). Un automat finit (AF ) se compune dintr-o band
a
de intrare si un dispozitiv de comand
a.
Pe banda de intrare sunt nregistrate simboluri ale unui alfabet de intrare, constituind pe banda un cuvant p. La fiecare pas de functionare banda se deplaseaza
cu o pozitie spre stanga.
Dispozitivul de comanda poseda un dispozitiv de citire de pe banda; dispozitivul se afla permanent ntr-o anumita stare interna, element al unei multimi
finite de stari. Schema unui automat finit este redata n figura 2.1.
Automatul finit functioneaza n pasi discreti. Un pas de functionare consta
din: dispozitivul de comanda citeste de pe banda de intrare simbolul aflat n
dreptul dispozitivului de citire; n functie de starea interna si de simbolul citit,
automatul trece ntr-o noua stare si muta banda cu o pozitie spre stanga. Automatul si nceteaza functionarea dupa ce s-a citit ultimul simbol nregistrat pe
banda; n acest moment el se va afla ntr-o anumita stare, care, dupa cum vom
vedea, va juca un rol important n recunoasterea cuvintelor.
Din punct de vedere matematic, un automat finit este un sistem
AF = (, I, f, s0 , f ),
unde
este alfabetul (multimea) de stari;
I este alfabetul de intrare;
f : I P() este functia de evolutie;
s0 este starea initiala;
f este multimea de stari finale.

23


CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

24

i1

i2

i3

...

ik

...

i n-1

in

...

Banda de intrare

Dispozitiv de citire

s S

Dispozitiv de comanda

Figura 2.1: Reprezentarea schematica a unui automat finit


Daca pentru orice (s, i) I, avem |f (s, i)| 1 automatul se numeste
determinist; n caz contrar se numeste nedeterminist.
Observatii:
1. Functionarea unui automat finit se poate bloca n situatia n care el se afla
n starea s, citeste de pe banda simbolul i si f (s, i) = ; evident ca n acest
caz functionarea n continuare nu mai este posibila.
2. In cazul unui automat determinist vom scrie f (s, i) = s0 (n loc de f (s, i)
{s0 }.
3. Definitia data este specifica teoriei limbajelor formale. O alta definitie (mai
generala) , ntalnita n teoria automatelor este urmatoarea: un automat finit
este un sistem AF = (, I, O, f, g, s0 , F ) unde, , I, f, s0 , F au semnificatia
de mai sus, O este alfabetul de iesire iar g : I P(O) este functie
de iesire. Functionalitatea unui astfel de automat finit este analoaga cu
cea descrisa mai sus, cu deosebirea ca la fiecare pas automatul furnizeaza o
iesire o g(s, i).
Prin diagrama de stari a unui automat finit ntelegem un graf orientat care are
nodurile etichetate cu starile s iar arcele se construiesc astfel: nodurile s, s0
se unesc cu un arc orientat de la s la s0 daca exista i I astfel ncat s0 f (s, i);
arcul respectiv va fi notat cu i.
Exemplu AF = (, I, f, s0 , f ) unde = {s0 , s1 , s2 }, I = {i1 , i2 }, f = {s2 },
iar f este data de tabelul
i1
i2

s0
{s1 }

s1
{s2 }
{s0 , s1 }

s2
{s0 }
{s0 , s1 }

2.1. AUTOMATE FINITE SI LIMBAJE REGULATE

25

i2
i1
i2

s1
i1

s0

i2
i2
s2

Figura 2.2: Diagrama de stari


Diagrama de stari corespunzatoare este prezentata n figura 2.2.
Functia de evolutie Functia f se prelungeste de la I la P() I deci
definim f 0 : P() I P(), astfel:
(a) f 0 (s, ) = {s}, s ,
(b) f 0 (, i) = , i I,
S
(c) f 0 (Z, i) = sZ f (s, i), Z P(), Z 6= ,
(d) f 0 (Z, pi) = f 0 (f 0 (Z, p), i).
Prin abuz de limbaj, vom folosi pentru noua functie tot notatia f .Sa observam
ca relatiile de mai sus constituie o definitie prin recurenta, corecta; fiind dat f ,
putem defini mai ntai toate valorile f (Z, i) (un numar finit, deoarece I este o
multime finita), apoi f (Z, p) pentru |p| = 2, n continuare f (Z, p) pentru |p| = 3,
etc.
Proprietatile functiei f:
1. Daca Zk este o familie de parti a lui , avem
[

f(

Zk , i) =

f (Zk , i)

Demonstratie. Utilizand (c) putem scrie


[

f (Zk , i) =

[ [

sZk

f (s, i)) =

[
sZk

f (s, i) = f (

Zk , i).2

2. f (Z, p) = sZ (f (s, p)), p I .


Demonstratie. Prin inductie asupra lungimii lui p.
S
Pentru |p| = 1 avem f (Z, i) = sZ f (s, i), adica (c).
Presupunem ca relatia este adevarata pentru |p| = m si consideram un p astfel


CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

26

ncat |p| = m + 1, deci p = p0 i, |p0 | = m. Putem scrie


S

f (Z, p) = f (Z, p0 i) = f (f (Z, p0 ), i) = f ( sZ f (s, p0 ), i) =


S
S
S
2
= sZ f (f (s, p0 ), i) = sZ f (s, p0 i) = sZ f (s, p).
3. f (s, pq) = f (f (s, p), q), p, q I .
Demonstratie. Inductie asupra lungimii lui q.
Daca |q| = 1, atunci q = i si relatia se reduce la (d).
Presupunem ca proprietatea este adevarata pentru r si consideram |q| = r +1.
Deci q = q 0 i. Avem
f (s, pq) = f (s, pq 0 i) = f (f (s, pq 0 ), i) = f (f (f (s, p), q 0 ), i) =
2
= f (f (s, p), q 0 i) = f (f (s, p), q).
Limbaje regulate.
Definitie 2.1 Limbajul recunoscut de automatul finit AF = (, I, f, s0 , f ) este
L(AF ) = {p|p I , f (s0 , p) f 6= }
Deci p L(AF ) daca automatul aflandu-se n starea initiala s0 , dupa |p| pasi
de functionare poate sa ajunga ntr-o stare finala.
In cazul unui automat finit determinist limbajul recunoscut poate fi definit
n modul urmator. Pentru fiecare s definim functia fs : I P() prin
fs (p) = f (s, p).
Atunci
f (s0 , p) f 6= f (s0 , p) = fs0 (p) f ,
deci
L(AF ) = {p|f (s0 , p) f 6= } = fs1
(f )
0
Limbajele recunoscute de automate finite le vom numi limbaje regulate; familia
acestor limbaje o vom nota cu R. Evident, familia limbajelor recunoscute de
automate finite deterministe, Rd , este o parte a lui R, Rd R. Vom arata ca
cele doua familii coincid.
Teorema 2.1 Rd = R.
Demonstratie. Fie AF = (, I, f, s0 , f ) un automat finit (n general nedeterminist). Construim urmatorul automat finit determinist AF 0 = (0 , I, f 0 , {s0 }, 0f )
unde 0 = P(), f 0 = f (prelungirea la I ), 0f = {Z| Z P(), Zf 6= }.
Evident, automatul AF 0 este determinist.
Fie p L(AF ). Atunci f (s0 , p) f 6= si f (s0 , p) 0f . Pe de alta parte,
conform cu proprietatea 2 a functiei de evolutie, avem
f 0 ({s0 }, p) = f (s0 , p)

2.1. AUTOMATE FINITE SI LIMBAJE REGULATE

27

si deci f 0 (s0 , p) 0f , adica p L(AF 0 ) si L(AF ) L(AF 0 ).


Pe o cale analoaga se arata ca L(AF 0 ) L(AF ).2
Observatie. Faptul ca un cuvant este recunoscut de un automat finit se poate
verifica prin calcul direct sau pe diagrama de stari.
Exemplu. Consideram automatul din exemplul anterior (figura 2.2) si fie
p = i1 i2 i1 . Prin calcul direct:
f (s0 , i1 i2 i1 ) = f (f (f (s0 , i1 ), i2 ), i1 ) = f (f ({s1 }, i2 ), i1 ) =
= f ({s0 , s1 }, i1 ) = f ({s0 }, i1 ) f ({s1 }, i1 ) = {s1 } {s2 }.
Astfel ca f (s0 , i1 i2 i1 ) f = {s2 } 6= si p L(AF ).
Pe diagrama de stari exista traiectoriile:
i

1
2
1
s0 s
1 s0 s1 ;
i1
i2
i1
s0 s
1 s1 s2 ;

A doua traiectorie ne duce ntr-o stare finala, deci p L(AF ).


Limbaje de tipul trei si limbaje regulate. Vom arata n cele ce urmeaza ca
familia limbajelor de tipul 3 coincide cu familia limbajelor regulate. In prealabil
vom pune n evidenta o forma speciala a limbajelor de tipul 3, pe care convenim
sa o numim forma normala.
Definitie 2.2 Vom spune ca o gramatic
a de tipul 3 este n forma normala dac
a
are reguli de generare de forma
(

A iB,
unde A, B, C VN , i, j VT
C j,

sau regula de completare S si n acest caz S nu apare n dreapta vreunei


reguli.
Lema 2.1 Orice gramatic
a de tipul 3 admite o forma normala.
Demonstratie. Daca G = (VN , VT , S, P ) G3 este gramatica data, eliminam n
primul rand -regulile (ca n lema eliminarii regulilor de stergere) apoi construim
gramatica G0 = (VN0 , VT , S, P 0 ), unde VN0 si P 0 se definesc astfel: introducem n
VN0 toate simbolurile din VN iar n P 0 toate regulile din P care convin; fie acum
n P o regula de forma
A pB, p = i1 . . . in
Vom introduce n P 0 regulile:
A i1 Z1 ,
Z1 i2 Z2 ,
...,
Zn1 in B,

28

CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

iar simbolurile Z1 , . . . Zn1 le includem in VN0 .


In cazul unei reguli de forma A p cu |p| > 1 procedam analog, exceptand ultima regula nou introdusa care va avea forma Zn1 in . Sa mai facem observatia
ca simbolurile Z1 , . . . , Zn1 le luam distincte pentru fiecare caz.
Se poate arata usor ca L(G) = L(G0 ).2
Teorema 2.2 Familia limbajelor de tipul 3 coincide cu familia limbajelor regulate.
Demonstratie. Partea I: E L3 E R.
Fie E un limbaj de tipul 3 si G = (VN , VT , S, P ) gramatica care l genereaza;
putem presupune ca G este n forma normala. Construim automatul finit AF =
(, I, f, s0 , f ) unde = VN {X} ( X simbol nou), I = VT , s0 = S si
(

f =

{X, S} , pentru E
{X}
, pentru 6 E

Functia de evolutie este definita de:


daca A iB P luam B f (A, i),
daca C j P luam X f (C, j),
n rest
Observatie. Automatul astfel definit este n general nedeterminist. De exemplu,
daca A 0B|0 atunci f (A, 0) = {B, X}.

Fie p L(G), p = i1 . . . in , deci S p. Detaliat, aceasta derivare va avea


forma
(1) Si1 A1 i1 i2 A2 i1 i2 . . . in1 An1 i1 i2 . . . in .
S-au aplicat regulile:
S i1 A1 ,
A1 i2 A2 ,
(2)
...
An1 in .
In automat avem corespunzator:

(3) :

A1 f (S, i1 ),
A2 f (A1 , i2 ),
...
X f (An1 , in )

Putem scrie traiectoria


i

1
2
3
n
(4) S
A1 A
2 . . . X f

I SPECIALE ALE LIMBAJELOR REGULATE


2.2. PROPRIETAT

29

Deci p L(AF ).
Daca p = , atunci S si S P . Dar atunci L(AF ), caci
automatul este n starea S si ramne n aceasta stare dupa citirea lui ; cum
nsa n acest caz S f rezulta ca si n acest caz p L(AF ). In consecinta
L(G) L(AF ).
Fie acum p = i1 . . . in L(AF ); atunci avem traiectoria (4), relatiile (3),
regulile de generare (2) si putem scrie derivarea (1), adica p L(G) si L(AF )
L(G).2
Partea II E R E L3 .
Vom indica numai modul de constructie a gramaticii. Fie AF = (, I, f, s0 , f )
automatul finit care recunoaste limbajul E, pe care l presupunem determinist.
Construim gramatica G = (, I, s0 , P ) unde multimea P este definita astfel
f (A, i) = B genereaza regula A iB P ,
n plus daca B f se genereaza si regula A i P .
Putem arata ca L(G) = L(AF ).2

2.2

Propriet
ati speciale ale limbajelor regulate

Caracterizarea algebric
a a limbajelor regulate. Limbajele regulate, fiind
parti din I , se pot caracteriza algebric, independent de mecanismele de generare
(gramaticile de tipul 3) sau de cele de recunoastere (automatele finite).
Teorema 2.3 Fie E I un limbaj. Urmatoarele afirmatii sunt echivalente.
(a) E R;
(b) E este o reuniune de clase de echivalente a unei congruente de rang finit;
(c) Urmatoarea congruent
a
= {(p, q)|E (r1 pr2 ) = E (r1 qr2 ), r1 , r2 I },
unde E este functia caracteristic
a a lui E, este de rang finit.
Demonstratie: Vom arata urmatoarele implicatii: (a) (b), (b) (c), (c) (a).
(a) (b).
Fie AF = (, I, f, s0 , f ) automatul finit care recunoaste limbajul E. Definim
pe I relatia
= {(p, q)|f (s, p) = f (s, q), s }.
Se poate vedea cu usurinta ca este o relatie de echivalenta (reflexiva , simetrica
, tranzitiva). In plus , daca r I si (p, q) , atunci (pr, qr) si (rp, rq) .
De exemplu, prima apartenenta se deduce astfel
f (s, pr) = f (f (s, p), r) = f (f (s, q), r) = f (s, qr), etc.

30

CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

Prin urmare este o relatie de congruenta.


Sa aratam ca aceasta congruenta este de rang finit, adica multimea cat I /
este finita.
Fie : o aplicatie oarecare si fie multimea
I () = {p|p I , f (s, p) = (s), s }.
Sa observam ca daca este functia identica atunci I (). Deci nu toate
I () sunt vide; n acest caz I () este o clasa de echivalenta. Intr-adevar, fie
p I () I fixat si fie Cp clasa de echivalenta a lui p. Aratam ca Cp = I ().
Daca q I (), atunci f (s, q) = (s), s , ceea ce nseamna ca f (s, q) =
f (s, p), s , si deci (p, q) adica q Cp si I () Cp .
Invers daca q Cp atunci f (s, q) = f (s, p) = (s), s si q I (),
adica Cp I (). Aceasta nseamna ca I () = Cp , adica I () este o clasa de
echivalenta .
Intre multimea cat I / si multimea functiilor definite pe cu valori n
putem stabili urmatoarea corespondenta biunivoca: unei functii : i
corespunde clasa de echivalent
a I (). Invers, fiind data o clasa de echivalenta C,
luam p C (oarecare) si atasam lui C functia (s) = f (s, p)s . T
inand cont
ca daca q C atunci f (s, p) = f (s, q), s , rezulta ca functia nu depinde
de elementul p ales.
Dar multimea functiilor definite pe cu valori n este finita, deci I / este
finita, adica congruenta este de rang finit.
Fie acum p L(AF ) si q astfel ca (p, q) . Avem
f (s0 , q) = f (s0 , p) f ;
adica q L(AF ). Aceasta nseamna ca odata cu elementul p, L(AF ) contine
clasa de echivalenta a lui p. De aici rezulta ca L(AF ) este constituit dintr-un
anumit numar de clase de echivalenta a lui .2
(b)(c)
Fie o congruenta de rang finit si E o reuniune de clase de echivalenta. Fie
apoi (p, q) ; aceasta nseamna ca r1 pr2 E r1 qr2 E, deci
E (r1 pr2 ) = E (r1 qr2 ), r1 , r2 I .
Prin urmare, (p, q) . Orice clasa de echivalenta din I / este inclusa
ntr-o clasa de echivalenta din I /, asa ncat card(I /) < card(I /), adica
congruenta este de rang finit.2
(c) (a)
Presupunem ca este o congruenta de rang finit; consideram automatul finit
AF = (I /, I, f, C , f ), unde functia de evolutie f si multimea de stari finale
sunt
f (Cp , i) = Cpi , f = {Cp |p E}.

I SPECIALE ALE LIMBAJELOR REGULATE


2.2. PROPRIETAT

31

Vom arata ca E = L(AF ). In primul rand sa observam ca f (Cp , q) = Cpq (se


poate arata prin inductie asupra lui |q|). Avem
p E Cp f f (C , p) = Cp = Cp f p L(AF )
adica E = L(AF ) si E este un limbaj regulat.2
Corolar 2.4 Familia R este nchis
a la operatia de rasturnare.
Demonstratie. Fie E R si Ee rasturnatul lui E. Conform teoremei de caracterizare, card(I /E ) < . Avem
(p, q) E E (r1 pr2 ) = E (r1 qr2 )
si

e q)
e E
Ee(rf1 perf2 ) = Ee(rf1 qerf2 ) (p,

Cu alte cuvinte daca C este o clasa de echivalenta a lui E atunci Ce (rasturnatul


lui C) este o clasa de echivalenta a lui Ee. Aceasta nseamna ca card(I /Ee) =
card(I /E ) < si conform aceleiasi teoreme de caracterizare Ee R.2
Observatie. Am vazut ca limbajele de tipul 3 pot fi definite de gramatici cu
reguli de doua categorii: drept liniare sau stang liniare. Este evident ca limbajele
stang liniare sunt rasturnatele limbajelor drept liniare. Cum familia limbajelor
regulate (drept liniare) este nchisa la operatia de rasturnare, rezulta ca cele doua
familii de limbaje coincid.
Inchiderea familiei L3 la operatiile P ref si complementariere.
Operatiile P ref si complementariere se definesc n modul urmator
P ref (E) = {p|r I , pr E}, C(E) = I \ E.
Teorema 2.5 Familia L3 este nchis
a la operatiile P ref si complementariere.
Demonstratie. Fie AF = (, I, f, s0 , f ) automatul finit care recunoaste limbajul
E. Putem presupune ca AF este determinist.
Limbajul P ref (E). Construim automatul finit AF 0 = (, I, f, s0 , 0f ) unde
0f = {s |s = f (s0 , q), q P ref (E)}.
Este evident ca P ref (E) L(AF 0 ), caci daca q P ref (E) atunci s = f (s0 , q)
0f conform definitiei lui 0f .
Sa aratam acum ca L(AF 0 ) P ref (E). Fie r L(AF 0 ), atunci f (s0 , q) 0f ,
deci exista q P ref (E) astfel ncat f (s0 , r) = f (s0 , q). Cum q este prefixul unui
cuvant din E, exista w I astfel ncat qw E, adica f (s0 , q) f . Dar
f (s0 , rw) = f (f (s0 , r), w) = f (f (s0 , q), w) = f (s0 , qw) f ,

32

CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

ij

sj = s

ik+1

s j-1
i1

s1

s k-1

s k+1

s j+1

s n-1

s0

in
sn

Figura 2.3: Traiectoria automatului finit


deci rw E si r P ref (E). Aceasta nseamna ca L(AF 0 ) P ref (E) si prin
urmare P ref (E) = L(AF 0 ), adica P ref (E) este limbaj regulat.2
Limbajul C(E). Avem
C(E) = {p I |p 6 E} = {p I |f (s0 , p) 6 f } = {p I , f (s0 , p) C(f )}.
Prin urmare C(E) = L(AFc ) unde AFc = (, I, f, s0 , C(f )}, adica C(E) este
un limbaj regulat.2
Lema de pompare pentru limbaje regulate Sub aceasta denumire (sau lema
uvw) este cunoscuta o proprietate a limbajelor regulate (ca si a altor familii de
limbaje) care ne premite sa descompunem cuvintele suficient de lungi ale limbajului n forma uvw si sa multiplicam subcuvantul v de un numar arbitrar de ori,
obtinand cuvinte care apartin de asemenea limbajului. Cu alte cuvinte, putem
sa pompam n cuvantul dat o anumita parte a sa. Astfel de leme se utilizeaza
deseori pentru a rezolva probleme de neapartenenta, adica pentru a arata ca un
anumit limbaj nu apartine unei familii date de limbaje.
Lema 2.2 Fie E un limbaj regulat si AF = (, I, f, s0 , f ) automatul finit care
l recunoaste. Daca p E si |p| card() atunci p se descompune n forma
p = uvw, v 6= si uv m w E, m N .
Demonstratie. Fie p = i1 . . . in , n card(); fie s0 , s1 , . . . , sn starile parcurse
de automat la citirea cuvantului p. Atunci, sj = f (sj1 , ij ), j = 1, n, sn f .
Exista n mod necesar doua stari egale, sj = sk , j < k. Traiectoria va avea o
bucla (vezi figura 2.3).
Descompunem cuvantul p n forma p = uvw unde u = i1 . . . ij , v = ij+1 . . . ik , w =
ik+1 . . . in . Este clar ca v 6= , caci j < k. Pe de alta parte, putem parcurge traiectoria facand de mai multe ori bucla, adica
f (s0 , uv m w) = sn f .
Prin urmare uv m w E.2

I SPECIALE ALE LIMBAJELOR REGULATE


2.2. PROPRIETAT

33

Consecint
a 2.3 Incluziunea L3 L2 este stricta.
In adevar, fie limbajul L2 = {0n 1n |n 1}. Stim ca acest limbaj este de tipul 2 si
ca poate fi generat de gramatica G = ({A}, {0, 1}, A, {A 0A1|01}). Sa aratam
ca L2 nu este de tipul 3.
Sa presupunem ca L2 este de tipul 3 si fie AF = (, I, f, s0 , f ) automatul
finit care l recunoaste. Cum L2 contine cuvinte oricat de lungi, fie p L2
astfel ncat p card(). Conform lemei de pompare, p se descompune n forma
p = uvw, v 6= si uv m w E. Putem avea una din situatiile:
(1) p = 0| .{z
. . 0} 0| .{z
. . 0} 0| . . . 01
{z . . . 1},
u

(2) p = 0| . . . 01
. . 1} 1| .{z
. . 1},
{z . . . 1} 1
| .{z
u

(3) p = 0| .{z
. . 0} 0| .{z
. . 1} 1| .{z
. . 1} .
u

Primele doua cazuri nu pot avea loc deoarece multiplicandu-l pe v, numarul de


simboluri 0 si 1 nu s-ar pastra egal. In al treilea caz, luand de exemplu, m = 2
obtinem
p2 = 0 . . . 00 . . . 10 . . . 11 . . . 1 L2
ceea ce din nou nu este posibil, ntrucat se contrazice structura cuvintelor lui L2 .
Prin urmare L2 nu este de tipul 3.2
Observatie. Este interesant de observat ca limbajele simple de forma lui L2
sunt semnificative pentru clasele din clasificarea Chomsky. Astfel
L1 = {an |n 1}, L1 L3 ;
L2 = {an bn |n 1}, L2 L2 , L2 6 L3 ;
L3 = {an bn cn |n 1}, L3 L1 (?), L3 6 L2 ;
Ne-am putea astepta ca limbajul L3 , un exemplu analog lui L2 , sa fie de tip
1, adica L3 L1 , L3 6 L2 . In adevar, se poate arata ca L3 6 L2 , dar dupa
cunostinta autorului, aparenta L3 L1 este o problema deschisa.
Consecint
a 2.4 Fie E un limbaj regulat si AF = (, I, f, s0 , f ) automatul finit
care l recunoaste. Atunci E este infinit daca si numai daca exista p E astfel
nc
at |p| card().
Daca limbajul este infinit, este clar ca exista p E cu |p| card(). Invers, daca
exista p E cu |p| card() atunci p = uvw, v 6= si uv m w E, m N ,
deci limbajul este infinit.2


CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

34

2.3

Expresii regulate si sisteme tranzitionale

Expresii regulate Fie V un alfabet. Expresiile regulate sunt cuvinte peste


alfabetul V {, , |} {(, )} la care se adauga simbolul , Simbolurile |-sau,
-produs, -nchidere, le vom considera operatori. Expresiile regulate se
definesc astfel:
(1) si sunt expresii regulate;
(2) pentru orice a V , cuvantul a este o expresie regulata;
(3) daca R si S sunt expresii regulate, atunci (R|S) (R S) si (R ) sunt
expresii regulate;
(4) orice expresie regulata se obtine prin aplicarea de un numar finit de ori a
regulilor (1)-(3).
Parantezele sunt utilizate pentru a pune n evidenta ordinea de aplicare a operatorilor. Pentru simplificarea scrierii vom considera ca operatorul are ponderea
cea mai mare, apoi operatorul si | ponderea cea mai mica. Astfel parantezele
redundante pot fi eliminate. De exemplu, prin R|S vom ntelege (R|(S )).
Observatie. Expresiile regulate se pot defini cu ajutorul gramaticii G =
({E}, V {|, , , (, )}, E, P ) unde
P = {E (E|E) | (E E) | (E ) | a | | }.
Unei expresii regulate i putem asocia un anumit limbaj peste V ; vom spune
ca expresia regulata reprezinta (desemneaza, noteaza) acel limbaj. Modul n care
asociem un limbaj unei expresii regulate este
(1)
(10)
(2)
(3)

reprezinta limbajul {};


reprezinta limbajul ;
a reprezinta limbajul {a};
daca R si S sunt expresii regulate ce reprezinta limbajele
LR respectiv LS atunci
(i) R|S reprezinta limbajul LR LS ;
(ii) R S reprezinta limbajul LR LS ;
(iii) R reprezinta limbajul (LR ) .

Fie R, S, P trei expresii regulate si LR , LS , LP limbajele reprezentate. Avem :


L(R|S)|P = (LR LS ) LP = LR (LS LP ) = LR|(S|P ) ,
ntrucat operatia de reuniune este asociativa. Vom scrie (R|S)|P = R|(S|P ). In
mod analog se pot obtine si alte proprietati. De exemplu:
S|R = S|R,
R|R = R,
(R S) P = R (S P ),
R (S|P ) = (R S)|(R P ), etc.

2.3. EXPRESII REGULATE SI SISTEME TRANZIT


IONALE

35

In cazul n care nu exista pericol de confuzie, vom nota cu L (fara indice) limbajul
reprezentat de o anumita expresie regulata.
Exemple.
S

j
2
1. R = a ; L =
j=0 {a } = {, a, a , . . .}.
2. R = aa ; L = a {, a, a2 , . . .} = {a, a2 , a3 . . .}.
3. R = (a|b) ; L = (La Lb ) = ({a} {b}) = {a, b} ;
{a, b} = {}{a, b}1 {a, b}2 . . . = {, a, b, aa, ab, ba, bb, . . .}, adica
(a|b) reprezinta multimea tuturor cuvintelor peste alfabetul {a, b}.
4. R = a|ba ; L = {a} {b} {, a, a2 , . . .} = {a, b, ba, ba2 , . . .}.

Limbajele reprezentate de expresii regulate constituie o anumita familie de limbaje; o vom nota cu Llr . Apare urmatoarea problema: care este pozitia acestei
familii n ierarhia Chomsky? Vom arata ca Llr coincide cu familia limbajelor
regulate.
Sisteme tranzitionale
Definitie 2.3 Un sistem tranzitional este un sistem de forma
ST = (, I, f, 0 , f , )
unde:
este o multime (finita) de stari;
I este alfabetul de intrare;
f : I P() este functia de tranzitie;
0 este multimea de stari initiale;
f este multimea de stari finale;
este relatia de tranzitie .
Exemplu. = {s0 , s1 , s2 }, I = {0, 1}, 0 = {s0 , s1 }, f = {s2 } iar functia si
relatia de tranzitie sunt date de:
f
0
1

s0
s1
s2
{s1 }
{s2 }
{s0 }

{s0 , s1 } {s0 , s2 }
= {(s0 , s1 ), (s2 , s1 )}.

Ca si n cazul unui automat finit putem construi diagrama de stari completata


cu relatia (arcele punctate). In cazul exemplului nostru diagrama de stari este
prezenta n figura 2.4
Observatie: fiind o relatie, are sens (nchiderea tranzitiva si reflexiva).
Fie i I {}; vom spune ca sistemul tranzitional evolueaza direct din starea
0
s n starea s00 daca:
(1) i = si (s0 , s00 ) . Pe diagrama de stari vom avea o traiectorie punctata
de la starea s0 la starea s00 ;
s0 O O . . . O s00 .

36

CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

0
1

s1

s0

0,1
s2

Figura 2.4: Diagrama de stari a sistemului tranzitional


(2) i 6= si exista s1 , s2 astfel ncat (s0 , s1 ) , s2 f (s1 , i) si (s2 , s00 )
. Pe diagrama de stari, putem ajunge din s0 n s00 pe o traiectorie punctata,
apoi un pas pe un arc plin si din nou pe o traiectorie punctata.
i

s0 O . . . s1 s2 O . . . s00 .
i

Vom scrie s0 ` s00 .


Fie acum p = i1 . . . in . Vom spune ca sistemul evolueaza din starea s0 n starea
00
s daca exista s0 , s1 , . . . , sn astfel ncat
i1

i2

in

s0 = s0 ` s1 ` . . . ` sn = s00 .
p

Vom scrie s0 ` s00 .


Definitie 2.4 Limbajul recunoscut de un sistem tranzitional ST este
p

L(ST ) = {p|p I , s0 0 , s0 ` s, s f }.
Vom nota cu LST familia limbajelor recunoscute de sisteme tranzitionale. Este evident ca orice automat finit este un sistem tranzitional particular n care card(0 ) =
1 iar = (nu exista arce punctate). Prin urmare R LST .
Teorema 2.6 R = LST .
Demonstratie. Evident, trebuie sa aratam incluziunea LST R. Fie ST =
(, I, f, 0 , f , ) un sistem tranzitional. Construim automatul finit AF = (P(), I, f 0 , 0 , 0f )
unde
i
f 0 (Z, i) = {s|s0 Z, s0 ` s},
0f = {Z|Z f 6= }.


2.4. ANALIZA LEXICALA

s0

37

s0

s1

s1

s0

s1

Figura 2.5: Sistemele tranzitionale ce recunosc limbajele , a, .


Fie p = i1 . . . in L(ST ) si fie urmatoarea evolutie a sistemului tranzitional
i1

i2

in

s0 ` s1 ` . . . ` sn f .
Putem construi o traiectorie a lui AF de forma
i

1
2
n
0
Z1
. . .
Zn ,

unde Z1 = f 0 (0 , i1 ), Zk = f 0 (Zk1 , ik ), k = 2, . . . , n. Sa observam ca s0


0 si ca daca sk1 Zk1 , atunci conform definitiei functiei f 0 , avem sk
f 0 (Zk1 , ik ) = Zk . Asftel, sk Zk , k = 1, . . . , n; pentru k = n avem sn Zn si
cum sn f rezulta ca Zn f 6= , adica Zn 0f . Deci automatul ajunge
ntr-o stare finala, p L(AF ) si L(ST ) L(AF ).
Incluziunea inversa se arata n mod analog.2
Constructia sistemelor tranzitionale pentru expresii regulate. Fiind data
o expresie regulata putem ntotdeauna construi un sistem tranzitional care recunoaste limbajul reprezentat de expresia respectiva.
Constructia se face cu ajutorul diagramelor de stari.
Sistemele tranzitionale (diagramele de stari) corespunzatoare expresiilor regulate , a si sunt prezentate n figura 2.5.
Daca R si S sunt expresii regulate si notam cu STR si STS sistemele tranzitionale
corespunzatoare, atunci sistemele tranzitionale pentru R|S, R S si R sunt redate n figura 2.6.
In acest mod putem construi succesiv (recurent) un sistem tranzitional corespunzator unei expresii regulate.
Exemplu. Sistemul tranzitional corespunzator expresiei R = a|ba este redat
n figura 2.7.
Consecint
a Dandu-se o expresie regulata, putem construi sistemul tranzitional care recunoaste limbajul reprezentat de expresia respectiva. Cum orice
limbaj recunoscut de un sistem tranzitional este regulat, rezulta ca limbajele
reprezentate de expresii regulate sunt limbaje regulate.

2.4

Analiza lexical
a

Procesul de analiza lexicala este o faza a procesului de compilare n care se determina unitatile lexicale (cuvintele, atomii) ale unui program sursa, se furnizeaza

38

CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

ST R

ST S

ST R

ST L

ST R

Figura 2.6: Sistemele tranzitionale ce recunosc limbajele R|S, R S si

Figura 2.7: Sistemul tranzitional corespunzator expresiei regulate


2.4. ANALIZA LEXICALA

39

codurile interne ale acestora si se detecteaza eventualele erori lexicale. Analizorul


lexical mai poate efectua o serie de operatii auxiliare precum: eliminarea blankurilor, ignorarea comentariilor, diferite conversiuni ale unor date, completarea
tabelelor compilatorului, gestiunea liniilor textului sursa.
Unit
ati lexicale O unitate lexicala (Lexic = vocabular; totalitatea cuvintelor
unei limbi) este o secventa din textul sursa care are o anumita unitate logica.
Definitia riguroasa a unitatilor lexicale ale unui limbaj particular se da la definirea
limbajului de programare respectiv. De obicei, n majoritatea limbajelor de programare, unitatile lexicale sunt: cuvinte cheie, identificatori, constante, operatori,
delimitatori. Din punctul de vedere al analizei lexicale si al modului de prelucrare,
unitatile lexicale pot fi de doua categorii:
Unitati lexicale simple, sunt unitati lexicale care nu comporta atribute suplimentare, de exemplu, cuvintele cheie, operatorii;
Unitati lexicale compuse (atributive), sunt unitati lexicale care comporta
anumite atribute suplimentare, de exemplu, identificatorii si constantele.
Atributele sunt informatii specifice, de exemplu, tipul identificatorului sau
al constantei (ntreg, real, etc.). Este necesara specificarea tipului unui
identificator sau al unei constante din startul programului deoarece structura programului obiect sau reprezentarea interna a constantelor depinde
de acest tip.
Reprezentarea interna a unitatilor lexicale se face n functie de categoria lor.
Cele simple se reprezinta printr-un cod specific(numar ntreg). Unitatile lexicale
compuse se reprezinta prin cod si informatii (de natura semantica) asupra sa.
De obicei compilatoarele utilizeaza tabele pentru stocarea atributelor (tabel de
constante, tabel de variabile, tabel de etichete, etc.). In acest caz unitatea lexicala
se reprezinta intern printr-un cod urmat de o referinta ntr-un tabel. Informatia
continuta de tabel ar putea fi pentru constante: cod, tip, valoare, iar pentru
identificatori: cod, tip, indicator de initializare.
Este posibil ca o clasa de unitati lexicale simple sa se reprezinte printr-un
cod unic si un atribut pentru distingerea n cadrul clasei. De exemplu, operatorii
aritmetici cu aceiasi prioritate au o tratare similara din punct de vedere al analizei sintactice. Lista unitatilor lexicale si definitia riguroasa a acestora se da la
proiectarea compilatorului.
Un exemplu de unitati lexicale si coduri asociate ar putea fi cele din figura
2.8.
Analizorul primeste textul sursa si produce sirul de unitati lexicale n codificarea interna. De exemplu secventa de text sursa urmatoare:
{if (unu < 2) return 0;
a=33;
}

40

CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

Unitate lexicala
if
else
identificator
constanta ntreaga
constanta reala
+

/
<
>
<=
>=
(
)
{
}

COD
if = 1
else = 2
ID = 3
NUM = 4
FLOAT = 5
op = 6
op = 6
op = 6
op = 6
opr = 7
opr = 7
opr = 7
opr = 7
LPAR = 8
RPAR = 9
LBRACE = 10
RBRACE = 11

ATRIBUT

Exemplu

referinta
referinta
referinta
1
2
3
4
1
2
3
4
-

if, If, IF
else ElSe
Nelu v tabel
4 -3 233
4.32 -3.233

Figura 2.8: Coduri asociate unitatilor lexicale


2.4. ANALIZA LEXICALA

41

va produce sirul de unitati lexicale


LBRACE If LPAR [ID,22] [opr,1] [NUM, 40], RPAR RETURN [NUM, 42] SEMI
[ID,24] opAssign [NUM,44] SEMI RBRACE.
In lista codurilor interne gasite atributul identificatorului este adresa relativa
din tabela de identificatori, analog atributele constantelor numerice sunt adrese
relative n tabelele de constante.
Majoritatea limbajelor evoluate contin si secvente de text care nu sunt unitati
lexicale, dar au actiuni specifice asociate . De exemplu:
comentarii

/* text */

directive de preprocesare

#include<stdio.h>
#define MAX 5.6

Inaintea analizei lexicale (sau ca subrutina) se preproceseaza textul si abia


apoi se introduce rezultatul n analizorul lexical.
Specificarea unit
atilor lexicale Definirea riguroasa a unitatilor lexicale se face
de catre proiectantul limbajului. O posibilitate de descriere este limbajul natural.
De exemplu, pentru C si JAVA:
Un identificator este o secventa de litere si cifre: primul caracter trebuie sa
fie litera. Liniuta de subliniere conteaz
a ca litera. Literele mari si mici sunt
diferite. Daca sirul de intrare a fost mp
artit n unitati lexicale pan
a la un caracter dat, noua unitate lexical
a se consider
a astfel nc
at sa includa cel mai lung sir
de caractere ce poate constitui o unitate lexical
a. Spatiile, taburile, newline si comentariile sunt ignorate cu exceptia cazului cand servesc la separarea unitatilor
lexicale. Sunt necesare spatii albe pentru separarea identificatorilor, cuvintelor
cheie si a constantelor.
Orice limbaj rezonabil poate fi folosit pentru implementarea unui analizor
lexical.
Unitatile lexicale se pot specifica cu ajutorul limbajelor regulate, deci folosind
gramatici de tipul 3 sau expresii regulate ce noteaza limbajele. Ambele specificatii
conduc la construirea de automate finite echivalente, care se pot usor programa.
In cele ce urmeaza, vom folosi ambele variante de specificare pentru un set uzual
de unitati lexicale ntalnit la majoritatea limbajelor evoluate.
Consideram gramatica regulata ce genereaza identificatori, constante ntregi,
cuvinte cheie, operatori relationali si aritmetici.

G:

< ul >< id > | < num > | < cc > | < op > | < opr >

< id > l < id1 > |l, < id1 > l < id1 > |c < id1 > |l|c

< num > c < num > |c

< cc > if |do|else|f or

< op > +| | |/

< opr >< | <= | > | >=

42

CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

unde l-litera, c-cifra.


Pornind de la aceasta gramatica se poate construi una echivalenta n forma
normala, apoi se extrage functia de evolutie a automatului finit determinist
echivalent ce recunoaste unitatile lexicale.
Descrieri echivalente ale unitatilor lexicale cu ajutorul expresiilor regulate sunt
cuvinte cheie = if | do | else | for
identificatori = ( a|b|c|...z )( a|b|c|...z|0|1|...|9 )*
Numar = ( 0|1|...|9 )( 0|1|...|9 )*
Operatori aritmetici = + | - | * | /
Operatori relationali = < | <= | > | >=
Limbajul generat de gramatica precedenta se obtine prin suma expresiilor
regulate. Mentionam ca exista programe specializate (Lex, Flex, JavaCC) ce
genereaza un analizor lexical (n C sau Java) pornind de la expresiile regulate.
Sintaxa folosita n scrierea expresiilor regulate este dependenta de programul
folosit.
Programarea unui analizor lexical Realizarea efectiva a unui analizor revine
la simularea functionarii unui automat finit. O varianta de programare este
atasarea unei secvente de program la fiecare stare a automatului. Daca starea
nu este stare finala atunci secventa citeste urmatorul caracter din textul sursa si
gaseste urmatorul arc din diagrama de stari. Depinzand de rezultatul cautarii
se transfera controlul altei stari sau se returneaza esec (posibila eroare lexicala).
Daca starea este finala atunci se apeleaza secventa de returnare a codului unitatii
lexicale si eventuala instalare a unitatii lexicale n tabelele compilatorului.
Pentru simplificarea implementarii se cauta urmatoarea unitate lexicala prin
ncercarea succesiva a diagramelor corespunzatoare fiecarei unitati lexicale (ntro ordine prestabilita). Eroarea lexicala se semnaleaza doar atunci cand toate
ncercarile se ncheie cu esec.
De obicei textul sursa contine si secvente ce se pot descrie cu ajutorul expresiilor regulate, dar care nu sunt unitati lexicale (de exemplu comentariile). Aceste
secvente nu vor genera cod lexical, dar au asociate diverse actiuni specifice. Pentru a evita aparitia unor caractere necunoscute in textul sursa se considera si
limbajul ce consta din toate simbolurile ASCII. Astfel, indiferent de unde ncepe
analiza textului, programul de analiza lexicala gaseste o potrivire cu o descriere.
Spunem ca specificatia este complet
a.
Exista posibilitatea ca mai multe secvente cu aceeasi origine sa corespunda la
diferite descrieri ale unitatilor lexicale. Se considera unitate lexicala cel mai lung
sir ce se potriveste unei descrieri (longest match rule). Daca sunt doua reguli


2.4. ANALIZA LEXICALA

43

care se potrivesc la acelasi sir de lungime maxima atunci se considera o prioritate


asupra descrierilor (rule priority).
De exemplu, in textul urmator,
i

if

if8

unitatile lexicale delimitate vor fi iidentificator, ifcuvant cheie, if8identificator.


Regula de prioritate se aplica pentru potrivirea lui if cu identificator si cuvant
cheie, iar criteriul de lungime maxima pentru if8.
Pentru depistarea celei mai lungi potriviri, din punt de vedere al programarii
analizorului, este suficient sa prevedem un pointer suplimentar pe caracterul ce
corespunde ultimei stari finale atinse pe parcursul citirii.
Studiu de caz. Se considera problema realizarii unui analizor lexical ce delimiteaza ntr-un text sursa cuvinte din limbajul ce contine identificatori, cuvinte
cheie (pentru simplificare folosim doar cuvantul cheie if), constante numerice
(ntregi fara semn). De asemenea se face salt peste spatiile albe si se ignora comentariile. Presupunem ca un comentariu ncepe cu doua caractere slash si se
termina cu newline. Orice caracter ce nu se potriveste descrierii este semnalat ca
si caracter ilegal in text.
Etapa I. Descriem secventele cu ajutorul expresiilor regulate
IF = "if"
ID = (a|b|c|...|z)(a|b|c|...|z|0|1|...|9)*
NUM = (0|1|...|9)(0|1|...|9)* = (0|1|...|9)+
WS = (\n|\t|" ")+
COMMENT = "//"(a|b|c|...|z|0|1|...|9|" ")*\n
ALL = a|b|...|z|0|...|9|\t| ...

toate caracterele ASCII

Etapa II. Corespunzator expresiilor avem urmatoarele automate finite deterministe echivalente, prezentate n figura 2.9 (starile au fost notate prin numere
ntregi):
Etapa III. Se construieste sistemul tranzitional (vezi figura 2.10) ce recunoaste limbajul reuniune, adaugand o noua stare initiala (notata cu 1), pe
care o conectam prin arce punctate (ce corespund -tranzitiilor). Constructia
provine din legarea sistemelor tranzitionale n paralel. S-au renumerotat starile
sistemului tranzitional, asignand nume simbolice starilor finale.
Etapa III. Constructia automatului finit determinist general ce recunoaste
reuniunea limbajelor. Pentru aceasta sistemul tranzitional se transforma cu teorema de echivalenta n automat finit determinist (practic se trece de la stari ale
sistemului tranzitional la submultimi de stari, ce devin starile automatului finit).

44

CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

a-z
0-9

a-z
2

ID
0-9

0-9
NUM

\n\t\b
\n\t\b

WS

a-z,\b
/

/
2

orice
1

\n
3

COM

ERR

Figura 2.9: Automatele finite corespunzatoare expresiilor regulate


In cazul particular al automatului nostru, diagrama de stari este data n figura
2.11.
Etapa IV. Programarea analizorului lexical.
Automatul finit obtinut are starile finale asociate cu clasele de cuvinte recunoscute. Se asociaza actiuni starilor finale, corespunzator definitiilor unitatilor lexicale (de exemplu pentru constante numerice se genereaza reprezentarea interna, se
memoreaza n tabelul de constante si se returneaza codul unitatii lexicale NUM).
Pentru programarea analizorului se folosesc trei variabile de tip pointer in textul
sursa: FirstSymbol, CurrentSymbol, LastFinalSymbol, ce retin indicele caracterului de nceput al secventei, indicele caracterului ce urmeaza la citire, indicele
ultimului caracter ce corespunde atingerii unei stari finale. Cei trei pointeri au
fost reprezentati prin semnele grafice |, respectiv >. De asemenea consideram
o variabila State, ce retine starea curenta a automatului.
In tabelul 2.12 este indicata evolutia analizorului lexical (inclusiv actiunile
asociate) pentru cazul analizei urmatorului text sursa.
if if8%// ha\n
Pentru simplificarea codificarii, starile automatului finit determinist au fost
redenumite prin numere ntregi ncepand cu starea initiala 1, starea {3, 6, 16} = 2,
{4, 6} = 3, {6, 16} = 4, s.a.m.d. de la stanga la dreapta si de sus n jos. De obicei


2.4. ANALIZA LEXICALA

45

IF

a-z
0-9

a-z
6

ID
0-9

0-9
NUM

\n\t\b

\n\t\b

/
12

11

orice
15

WS
a-z ,\b

10

16

\n
13

14

COM

ERR

Figura 2.10: Sistemul tranzitional ce recunoaste reuniunea limbajelor

46

CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

ID

IF
f

3,6,16

4,6

a-e
g-z

i
a-h
-jz

a-z
0-9

0-9
a-z

ID

a-z
0-9

6,16

0-9
ID

0-9

NUM

0-9
8,16

\n\t\b

WS

\n\t\b

10,16

ERR
12,16

ERR
orice
altceva

COM
/

\n
14

13

a-z,\b

16

Figura 2.11: Automatul finit determinist ce recunoaste reuniunea limbajelor


2.4. ANALIZA LEXICALA

Last
Final
0
2
3
0
7
0
2
3
5
0
11
0
0
0
...

Current
State
1
2
3
0
1
7
0
1
2
3
5
0
1
11
0
1
8
9
...

Current Input
|>
i f i f 8 % / / h a \n
| i>
f i f 8 % / / h a \n
| i f> i f 8 % / / h a \n
| i f > i f 8 % / / h a \n
i f |>
i f 8 % / / h a \n
i f| >
i f 8 % / / h a \n
i f | > i f 8 % / / h a \n
i f |>
i f 8 % / / h a \n
i f | i>
f 8 % / / h a \n
i f | i f> 8 % / / h a \n
i f | i f 8>
% / / h a \n
i f | i f 8> % / / h a \n
i f i f 8|>
% / / h a \n
i f i f 8| %>
/ / h a \n
i f i f 8| %> / / h a \n
i f i f 8 %|>
/ / h a \n
i f i f 8 %|> / / h a \n
i f i f 8 %|> / / h a \n
...

47

Accept Action

return cc =< if >


resume

resume

return id =< if 8 >


resume
print (illegal character: %);
resume

Figura 2.12: Evolutia analizorului lexical pentru textul if if8%// ha\n


CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

48

int edges[][] = {

/* ...

0 1 2 ...

e f g h i j ...

*/

/* state 0 */

{0,0, ...,0,0,0, ...,0,0,0,0,0,0, ... },

/* state 1 */

{0,0, ...,6,6,6, ...,4,4,4,4,2,4, ... },

/* state 2 */

{0,0, ...,5,5,5, ...,5,3,5,5,5,5, ... },

etc
}
Figura 2.13: Reprezentarea functiei de evolutie a automatului finit
functia de evolutie asociata automatului finit determinist se memoreaza sub forma
unui tablou bidimensional de ntregi, ca n figura 2.13. Starea 0 este asociata cu
blocarea automatului. Ajungerea n aceasta stare echivaleaza cu gasirea ultimei
unitati lexicale, ntre pointerii | si >. Se executa actiunea asociata starii finale
si se reia cautarea (resume) urmatoarei unitati lexicale ncepand cu caracterul
imediat urmator pointerului >.
Observatie: Cele mai costisitoare operatiuni (ca timp) din analiza lexicala
sunt ignorarea comentariilor si tratarea erorilor lexicale. Primele generatoare
automate de analizoare lexicale si sintactice au aparut n anii 0 70 si au fost incluse
n sistemul de operare Unix.

2.5

Probleme propuse

1. Construiti automate finite pentru recunoasterea limbajelor:


(a) L = {P SDR, P N L, P U N R};
(b) L = {w| siruri de 0 si 1 terminate cu 1 };
(c) L = {w|w identificator PASCAL };
(d) L = {w|w constanta ntreaga cu semn n PASCAL };
(e) L = {w {0, 1} |w multiplu de 3 };
(f) L = {ai bj |i, j > 0};
(g) L = .
2. Construiti automate finite echivalente cu gramaticile de tipul trei de la
problema 1 capitolul 1.

2.5. PROBLEME PROPUSE

49

3. Construiti automate finite deterministe echivalente cu cele nedeterministe


obtinute la problema precedenta.
4. Gasiti gramatici regulate echivalente cu automatele de la problema 1.
5. Folosind lema de pompare pentru limbaje regulate dovediti ca urmatoarele
limbaje nu sunt regulate:
2

(a) L = {0i |i 1};


n

(b) L = {02 |n 1};


(c) L = {0n |n este numar prim };
(d) L = {0m 1n 0m+n |m 1, n 1};
6. Specificati limbajele denotate de urmatoarele expresii regulate:
(a) (11|0) (00|1) ;
(b) (1|01|001) (|0|00);
(c) 10|(0|11)0 1;
(d) ((0|1)(0|1)) ;
(e) 01 |1;
(f) ((11) |101) .
7. Construiti sisteme tranzitionale ce recunosc limbajele specificate la problema precedenta. Pentru fiecare sistem tranzitional construiti un automat
finit determinist echivalent.

50

CAPITOLUL 2. LIMBAJE REGULATE SI ANALIZA LEXICALA

Capitolul 3
Limbaje Independente de
Context
3.1

Arbori de derivare

Caracterizarea familiei L2 cu arbori de derivare. Una din caracteristicile


de baza ale limbajelor independente de context este aceea ca o derivare ntr-un
astfel de limbaj poate fi reprezentata de un arbore, numit in acest context arbore
de derivare. Aceasta reprezentare este importanta n mod special pentru faptul
ca permite o imagine intuitiva simpla a unei derivari si deci posibilitatea de a
lucra usor cu limbaje de tipul 2.
Vom prezenta n primul rand cateva notiuni elementare de teoria grafurilor,
cu scopul de a preciza notatiile si terminologia.
Un graf orientat G este o pereche G = (V, ) unde V este o multime finita
iar o aplicatie : V P(V ). Multimea V se numeste multimea varfurilor
(nodurilor) grafului iar daca v2 (v1 ), perechea (v1 , v2 ) este un arc n graf; v1
este originea iar v2 este extremitatea arcului. Un drum de la vrful v 0 la varful
v 00 n graful G este o multime de arce (v1 , v2 )(v2 , v3 ) . . . (vn1 , vn ) cu v 0 = v1 si
v 00 = vn . Numarul n 1 este lungimea drumului. Un drum pentru care v1 = vn
se numeste circuit. Un circuit de lungime 1 poarta numele de bucl
a.
Definitie 3.1 Un arbore este un graf far
a circuite, cu card(V ) 2 si care satisface urmatoarele doua conditii :
1. v0 V astfel nc
at v0 6 (v), v V ; v0 se numeste r
ad
acina arborelui;
2. v V \ {v0 }, !w cu v (w); altfel spus orice varf diferit de v0 este
extremitatea unui singur arc.
Exemplu. V = {v0 , v1 , v2 , v3 , v4 } iar functia este data de:
x
(x)

v0
{v1 , v2 }

v1

51

v2
{v3 , v2 }

v3

v4

52

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

Nivel 0
v0

Nivel 1
v2

v1

v3

v4

Nivel 2

Figura 3.1: Reprezentarea grafica a arborelui G = (V, ).


Reprezentarea n plan a acestui arbore este data in figura 3.1
Nodurile v pentru care (v) = se numesc noduri terminale (finale); celelalte
se numesc interne. Multimea nodurilor terminale constituie frontiera arborelui.
In general vom nota un arbore cu litere mari, specificnd ca indici radacina si frontiera; de exemplu Av0 , v1 v2 v3 . Un arbore comporta mai multe ramuri; n exemplu
avem urmatoarele ramuri : v0 v1 , v0 v2 v3 , v0 v2 v4 .
Fie G = (VN , VT , S, P ) o gramatica de tipul 2.
Definitie 3.2 Un arbore de derivare n gramatica G este un arbore cu urmatoarele
doua propriet
ati .
(1) Nodurile sunt etichetate cu elementele din VG ;
(2) Daca un nod v are descendenti directi v1 , . . . , vn atunci
v v1 v2 . . . v n P .
Exemplu. G = ({A, B}, {a, b}, A, P ) unde
P = {A aBA|Aa|a, B AbB|ba|abb}.
Arborele AA, aabbaa reprezentat n figura 3.2 (Varianta 1) este un arbore de
derivare (poate fi desenat coborand frontiera pe nivelul ultim , Varianta 2):

Teorema 3.1 Fie G o gramatic


a de tipul 2. Atunci X p dac
a si numai daca
exista un arbore AX, p .

Demonstratie. X p implica AX, p .


Procedam prin inductie asupra lungimii derivarii l.
Daca l = 1, X p = i1 . . . in si X i1 . . . in P . Arborele din figura 3.3
corespunde cerintelor teoremei.

3.1. ARBORI DE DERIVARE

53

Varianta 2

Varianta 1
A
a

A
A

B
A

B
B

Figura 3.2: Variante de reprezentare a arborelui AA, aabbaa .

i1

i2

...

in

Figura 3.3: Arbore corespunzator unei derivari directe.

54

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

X1

p1

X2

...

p2

...

Xm

pm

Figura 3.4: Constructia arborelui AX,p1 ...pm .


Presupunem ca proprietatea este adevarata pentru derivari de lungime l si

consideram o derivare de lungime l + 1, X p. Punem n evidenta prima derivare


directa

XX1 . . . Xn p

Conform lemei de localizare, p = p1 . . . pn si Xj pj , j = 1, m. Putem face

urmatoarea constructie: conform ipotezei inductive, fiecarei derivari Xj pj i


corespunde cate un arbore AXj ,pj ; unim apoi toate nodurile Xj n nodul X plasat
la nivelul zero. Obtinem astfel un arbore AX,p1 ...pm = AX,p (vezi figura 3.4) care
corespunde cerintelor teoremei.

Pentru implicatia , AX,p X p, se parcurge o cale inversa, facand


o inductie asupra numarului de nivele. De exemplu, daca acest numar este 2,
arborele de derivare trebuie sa arate ca n 3.3 si deci avem X i1 i2 . . . in = p P

si X p, etc. 2

3.2

Ambiguitate n familia L2.

Fie G o gramatica de tipul 2. O derivare S = u0 u1 . . . un n care


la fiecare derivare directa se nlocuieste simbolul neterminal cel mai din stanga
(dreapta) se numeste derivare extrem stang
a (dreapt
a). Sa observam ca n particular ntr-o gramatica de tipul 3 orice derivare este extrem dreapta (scrierea
drept liniara).
a G de tipul 2 n care exista un cuvant p L(G) care
Definitie 3.3 O gramatic
se poate obtine cu doua derivari extrem stangi (drepte) distincte, se numeste
ambigua. In caz contrar este neambigu
a.

3.2. AMBIGUITATE IN FAMILIA L2 .

55

Exemplu. Gramatica A aBA|Aa|a, B AbB|ba|abb este ambigua. Intradevar, avem


AaBAaBaaAbBaaAbbaaaabbaa;
AAaaBAaaBaaaabbaa.
Definitie 3.4 Un limbaj este ambigu daca toate gramaticile care l genereaz
a

sunt ambigue. In caz contrar (adica daca exista o gramatic


a neambigu
a care sa
l genereze) limbajul este neambigu.
Daca G este ambigua si p L(G) este un cuvant care se poate obtine cu doua
derivari extrem stangi distincte, atunci exista arborii AS, p si A0S, p , diferiti, dar
care au aceiasi radacina si frontiera.
Teorema 3.2 Dac
a L1 si L2 sunt limbaje disjuncte neambigue, atunci L1 L2
este neambigu.
Demonstratie. Fie Gk = (VNk , VTk , Sk , Pk ), k = 1, 2 doua gramatici de tipul 2
neambigue si fie G = (VN1 VN2 , VT1 VT2 , S, P1 P2 {S S1 |S2 }) gramatica
ce genereaza limbajul L(G1 ) L(G2 ).
Sa presupunem ca L(G) este ambigua. Atunci exista p L(G) care se poate
obtine cu doua derivari extreme stangi diferite. Sa presupunem ca p L(G1 ), p 6
L(G2 ). Atunci obtinem doua derivari distincte n gramatica G

G1

G2

(1) S S1 p, deci S1 p;
G

(2) S S1 p, deci S1 p,
G

deci si doua derivari extrem stangi n gramatica G1 . Aceasta ar nsemna ca G1


este ambigua. Contradictie cu ipoteza!2
Teorema 3.3 Limbajele de tipul 3 sunt neambigue.
Demonstratie. Fie L un limbaj de tipul 3 si G gramatica care l genereaza; fie apoi
AF automatul finit care recunoaste limbajul L si AF D automatul finit echivalent
determinist. Construim gramatica G0 astfel ncat L(G0 ) = L(AF D). Reamintim
ca regulile lui G0 se construiesc astfel f (A, a) = B A aB, f (A, a) f
A a.
Sa presupunem acum ca L este ambigu; atunci orice gramatica care l genereaza,
inclusiv G0 , este ambigua. Aceasta nseamna ca exista un p L(G0 ) astfel ncat
(

Si1 A1 i1 i2 A2 . . . i1 . . . in1 An1

i1 . . . in A0n
i1 . . . in A00n

p.

Deci exista regulile An1 in A0n si An1 in A00n , adica n automatul AF D


avem
f (An1 , in ) = A0n , f (An1 , in ) = A00n ,
ceea ce contrazice faptul ca AF d este determinist.2

56

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

3.3

Forme normale pentru gramatici de tipul 2

Forma normal
a Chomsky.
a n forma normala Chomsky este o gramatic
a cu reguli
Definitie 3.5 O gramatic
de forma
A BC,
D i,
unde A, B, C, D VN si i VT . Se accept
a si regula de completare S cu
conditia ca S sa nu apar
a n dreapta vreunei reguli.
Lema 3.1 (lema substitutiei). Fie G o gramatic
a de tipul 2 si X uY v precum
si Y p1 . . . pn toate regulile din G care au Y n stanga . Atunci G este echivalenta cu o gramatic
a G0 n care am facut substitutiile; adica facem urmatoarea
nlocuire
X uY v se nlocuieste cu X up1 v| . . . |upn v
(Regulile Y p1 | . . . |pn le vom pastra neschimbate).

Demonstratie. Fie p L(G) si S p. Punem n evidenta doi pasi consecutivi


oarecare:

G : S rstp.
Daca n rs se utilizeaza regula X uY v atunci n mod necesar n pasul
urmator se utilizeaza una din regulile Y p1 | . . . |pn , sa presupunem Y pj
(evident, este posibil ca aceasta regula sa nu se aplice n pasul imediat urmator,
dar ea poate fi adusa n aceasta pozitie). Prin urmare
(A) G : r = r0 Xr00 r0 uY vr00 r0 upj vr00 = t.
Acesti doi pasi se pot obtine si n G0 (ntr-un singur pas):
(B) G0 : r = r0 Xr00 r0 upj r00 = t.

Deci S p, p L(G0 ) si L(G) L(G0 ).


G0

Invers, daca p L(G0 ) si S p, atunci daca la un pas se utilizeaza o regula


G0

nou introdusa (pasul (B)), transformarea respectiva se poate obtine si n G cu


doi pasi (pasii (A)); deci p L(G) si L(G0 ) L(G).2
a de tipul 2 este echivalent
a cu o gramatic
a de acelasi
Corolar 3.4 Orice gramatic
tip n care multimea de reguli nu contine redenumiri. (O redenumire este o regul
a
de forma A B, A, B VN ).

3.3. FORME NORMALE PENTRU GRAMATICI DE TIPUL 2

57

Intr-adevar, daca A B P este o redenumire si B p1 | . . . |pn sunt toate


regulile care au B n stanga, efectuam substitutiile, deci nlocuim regula A B
cu A p1 | . . . |pn . In cazul n care printre acestea apare o noua redenumire,
repetam procedeul.2
Exemplu. Gramatica GE care genereaza expresii aritmetice E E+T |T, T
T F |F, F (E)|i se poate pune sub urmatoarea forma (fara redenumiri) :
E E + T |T F |(E)|i
T T F |(E)|i
F (E)|i
Teorema 3.5 (teorema lui Chomsky de existent
a a formei normale). Orice gramatic
a independent
a de context este echivalent
a cu o gramatic
a n forma normala
Chomsky. ema2
Demonstratie. Putem porni de la o gramatica G care nu are redenumire si ale carei
reguli cu terminale au forma A i, A VN , i VT . De asemenea presupunem
ca G nu are reguli de stergere.
Rezulta ca regulile lui G au una din formele:
(1) A BC,
(2) D i,
(3) X X1 . . . Xn , n > 2.
Construim o gramatica G0 = (VN0 , VT , S, P 0 ) unde VN VN0 si P 0 contine toate
regulile din P de forma (1) si (2). Fiecare regula de forma (3) o nlocuim cu:
X X1 Z1 ,
Z1 X2 Z2 ,
...
Zn2 Xn1 Xn
si includem neterminalele Z1 , . . . , Zn2 (altele pentru fiecare regula de forma (3)
n VN0 .
Se poate relativ usor arata ca L(G) = L(G0 ). De exemplu, daca uv (direct)
n G si de aplica o regula de forma (1) sau (2), atunci evident derivarea respectiva
se poate obtine si n G0 ; n cazul n care se aplica o regula de forma (3), avem
00

G : u = u0 Xu00 u0 X1 . . . Xn u = v.
Aceasta derivare se poate obtine si n G0 n mai multi pasi si anume
00

G0 : u = u0 Xu00 u0 X1 Z1 u00 u0 X1 X2 Z2 u00 . . . u0 X1 . . . Xn u = v.2


Observatie. O gramatica ce are reguli de forma A BC, A B, A a
unde A, B, C VN si a VT spunem ca este n forma 2canonic
a. Este evident
ca orice gramatica de tip 2 este echivalenta cu o gramatica n forma 2canonica.
Gramatici recursive

58

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

Definitie 3.6 Un simbol neterminal X al unei gramatici de tipul 2 este recursiv


daca exista o regul
a de forma X uXv, u, v VG .
Daca u = (v = ) simbolul X este stang (drept) recursiv. O gramatica ce are
cel putin un simbol recursiv se numeste recursiva. De exemplu, gramatica GE
care genereaza expresiile aritmetice are doua simboluri stang recursive, E si T .
Existenta simbolurilor stang recursive poate provoca dificultati n aplicarea algoritmilor de analiza top-down. Intr-adevar, ntr-o astfel de gramatica, ncercarea
de a construi arborele de derivare corespunzator unui cuvant p prin aplicarea
ntotdeauna a primei reguli pentru simbolul cel mai din stanga, poate sa conduca
la un ciclu infinit (de exemplu n GE s-ar obtine EE + T E + T + T . . .).
Teorema 3.6 Orice limbaj de tipul 2 poate sa fie generat de o gramatic
a far
a
recursie stang
a.
Demonstratie. Fie G = (VN , VT , S, P ) o gramatica de tipul 2; presupunem ca G
are un singur simbol recursiv X si fie
(A) X u1 |u2 | . . . |un |Xv1 | . . . |Xvm
toate regulile care au X n stanga. Construim gramatica G0 = (VN0 , VT , S, P 0 ),
unde VN VN0 , P P 0 cu exceptia regulilor (A); acestea se nlocuiesc cu
X u1 |u2 | . . . |un |u1 Y |u2 Y | . . . |un Y,
Y v1 | . . . |vm |v1 Y | . . . |vm Y
G0 este de tipul 2 si nu are simboluri stang recursive; se vede nsa ca Y este un
simbol drept recursiv.

Fie p L(G), S p. Daca n aceasta derivare nu intervine simbolul reG

cursiv, atunci evident ca S p. Sa presupunem ca X intervine la un anumit


G0

00

pas: Sup, unde u = u0 Xu . Putem aplica, ncepand de la u spre dreapta, n


primul rand regulile pentru X si sa urmarim numai subarborele respectiv, deci
G : X Xvj1 Xvj2 vj1 . . . Xvjs . . . vj1 uj vjs . . . vj1 .
G

Aceeasi forma propozitionala o putem obtine si n gramatica G0 astfel


G0 : X uj Y uj vjs Y . . . uj vjs . . . vj1 .
G0

G0

G0

G0

Prin urmare avem S u p, adica p L(G0 ) si L(G) L(G0 ). Analog,


G0

G0

L(G ) L(G).2
Forma normal
a Greibach.

3.3. FORME NORMALE PENTRU GRAMATICI DE TIPUL 2

59

Definitie 3.7 O gramatic


a n forma normala Greibach este o gramatic
a cu reguli
de forma
A ip, unde A VN , i VT p VN .
Se accept
a si regula de completare S cu conditia ca S sa nu apar
a n dreapta
vreunei reguli.
Teorema 3.7 (Teorema de existent
a a formei normale Greibach). Orice gramatic
a de tipul 2 este echivalenta cu o gramatic
a n forma normala Greibach.
Demonstratie. Fie G o gramatica de tipul 2 n forma normala Chomsky si fie
VN = {S = X1 , X2 , . . . , Xn }. Vom construi o gramatica echivalenta care sa
satisfaca cerintele din forma normala Greibach n mai multe etape.
Etapa I. Vom modifica regulile de generare astfel ncat toate regulile care nu sunt
de forma X i sa satisfaca conditia Xj Xk p, j < k, p VN . Acest lucru l
facem cu un algoritm pe care l prezentam ntr-un limbaj nestandard de publicare
(tip PASCAL):

e1:

e2:

j := 1;
begin
Se elimina recursiile stangi; neterminalele
noi le notam cu Y1 , Y2 , . . .
end
if j = n then STOP;
j := j + 1;
l := 1;
begin
Fie Xj Xl p, p VN si Xl p1 . . . pm
toate regulile care au Xl n stanga; se efectueaza toate substitutiile.
end
l := l + 1;
if l < j 1 then goto e2
goto e1

Sa observam ca pentru j = 1 si dupa eliminarea recursiilor stangi conditia


ceruta este evident ndeplinita; n plus, daca au fost recursii, vom avea reguli cu
partea stanga neterminale noi Y1 , Y2 , . . .. Mai departe, luam toate regulile care au
n stanga X2 (j := j + 1 = 2) si efectuam substitutiile; acestea se vor transforma
n X2 Xk p cu k 2 si dupa o noua eliminare a recursiilor stangi vom avea
k > 2 plus reguli cu partea stanga neterminale noi. In felul acesta toate regulile
care au n stanga X1 si X2 satisfac conditia ceruta; n continuare j := j + 1 = 3,
etc.
Etapa II. Avem acum trei categorii de reguli:

60

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

(1) Xj i;
(2) Xj Xk p, j < k, p VN ;
(3) Y iq, q VN , i = 1, . . . , m.
Aranjam toate neterminalele ntr-un sir unic, la nceput Y1 , . . . , Ym apoi X1 , . . . , Xn
si le redenumim, de exemplu cu X1 , . . . , Xm+n :
Y1 , Y2 , . . ., Ym , X1 ,
X2 ,
. . ., Xn
X1 , X2 , . . ., Xm , Xm+1 , Xm+2 , . . ., Xm+n
Vom nota n + m = N . In felul acesta regulile gramaticii vor avea numai
formele (1) si (2).
Etapa III. Toate regulile care au XN n stanga vor avea forma (1). Fie Xn1
XN p1 | . . . |XN pn toate regulile care au XN 1 n stanga si care nu sunt de forma
(1). Efecuam substitutiile lui XN ; n acest fel regulile care au XN si XN 1 n
stanga satisfac cerintele din forma normala Greibach. In continuare, consideram
toate regulile care au XN 2 n stanga si efectuam substitutiile, etc.2
Forma normal
a operator
Una din formele importante pentru gramatici independente de context, utilizata n analiza sintactica prin metoda precedentei, este forma operator a acestor
gramatici.
Definitie 3.8 O gramatic
a independent
a de context G = (VN , VT , S, P ) se spune
ca este n forma normala operator dac
a oricare ar fi productia A P , n
nu apar doua neterminale (variabile) consecutive, adic
a
P VN [(VN VT ) \ (VN VT ) V 2 (VN VT ) ].
Teorema 3.8 Orice gramatic
a independent
a de context este echivalent
a cu o gramatica n forma normala operator.
Demonstratie. Fie G = (VN , VT , S, P ) o gramatica de tipul 2 si L(G) limbajul
generat. Fara a restrange generalitatea presupunem ca 6 L(G) si G este
n forma 2canonica (regulile sunt de forma A BC, A B, A a vezi
teorema ??). Definim o gramatica echivalenta G0 = (VN0 , VT , S, P 0 ) astfel: VN0 =
{S} (VN VT ), iar P 0 = P1 P2 P3 P4 unde
i)
ii)
iii)
iv)

P1
P2
P3
P4

= {S (S, a)a| a VT };
= {(A, a) | A VN , a VT , A a P };
= {(A, a) (B, a)| A, B VN , a VT , A B P };
= {(A, a) (B, b)b(C, a)| A, B, C VN , a, b VT , A BC P }.

Sa observam ca G0 este n forma normala operator. Pentru a demonstra ca


L(G) = L(G0 ) vom defini mai ntai o functie : P2 P3 P4 P astfel:
((A, a) ) = A a pentru (A, a) P2 ;
((A, a) (B, a)) = A B pentru (A, a) (B, a) P3 ;
((A, a) (B, b)b(C, a)) = A BC pentru (A, a) (B, b)b(C, a) P4 .

3.3. FORME NORMALE PENTRU GRAMATICI DE TIPUL 2

61

Functia se extinde n mod natural la 0 : (P2 P3 P4 ) P . Vom arata ca

n gramatica G, w VT , a VT are loc derivarea extrem dreapta A wa


G

folosind productiile 1 , 2 , . . . , n daca si numai daca exista n P 0 productiile


10 , 20 , . . . , n0 astfel ca (i0 ) = i , 1 i n si n G0 are loc derivarea extrem

dreapta (A, a) w folosind productiile 10 , 20 , . . . , n0 .


G0

Sa demonstram afirmatia prin inductie dupa n, lungimea derivarii.


Daca n = 1 atunci w = , A a P si n P 0 exista productia (A, a) ,
deci (A, a) si ((A, a) ) = A a.
Invers, daca (A, a)w n G0 atunci w = (dupa forma productiilor din G0 )
si are loc proprietatea enuntata.
Sa presupunem afirmatia adevarata pentru derivari de lungime cel mult n 1

si sa o demonstram pentru derivari de lungime n > 1. Fie asadar A wa


G

o derivare de lungime n n gramatica G si punem n evidenta prima derivare


directa. Distingem doua cazuri:
I. Prima productie utilizata n derivare este A B. Atunci,

A B wa
G

si conform ipotezei inductive avem n G0 o derivare (B, a) w (de lungine n1)


G0

cu productii satisfacand conditiile aratate. Dar cum A B P , n P 0 avem

productia (A, a) (B, a) deci (A, a) w n gramatica G0 .


G0

II. Prima productie este de forma A BC. Atunci

A BC wa.
G

In acest caz wa = ubva (conform lemei de localizare), astfel ca B


ub si
G

C va. Dupa ipoteza inductiva, vom avea n G derivarile:


G

G0

G0

(B, b) u, (C, a) v.
Cum A BC P vom avea n P 0 productia (A, a) (B, b)b(C, a) si n G0
putem scrie derivarea extrem dreapta

G0

G0

(A, a)(B, b)b(C, a) (B, b)bv ubv = w


si productiile care s-au aplicat ndeplinesc conditiile din enunt.
In mod analog se demonstreaza reciproca.

62

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT


Din aceasta afirmatie, luand n particular A = S, obtinem:

S wa
G

(S, a) w, w VT , a VT .
G0

Cum n G0 exista si productia S (S, a)a, am gasit: wa L(G) daca si numai


wa L(G0 ), deci cele doua gramatici sunt echivalente.
Pentru a ncheia demonstratia trebuie sa consideram si cazul L(G).
Aplicam constructia de mai sus unei gramatici ce genereaza L(G)\{} si obtinem
G0 = (VN0 , VT , S, P 0 ) gramatica operator corespunzatoare. Consideram acum gramatica G1 = (VN1 , VT , S1 , P1 ) unde V1 = V 0 {S1 }, P1 = P 0 {S1 , S1 S}
care este n forma normala operator si L(G1 ) = L(G).2

3.4

Lema BarHillel

Ca si n cazul limbajelor regulate, lema BarHillel pune n evidenta urmatoarea


proprietate a unui limbaj independent de context: orice cuvant al unui astfel de
limbaj, suficient de lung, contine un subcuvant (nevid) pe care multiplicandu
l de un numar arbitrar de ori, obtinem noi cuvinte care apartin de asemenea
limbajului. Mai poarta denumirea de lema de pompare sau lema uvwxy.
Ne vom referi n cele ce urmeaza la gramatici de tipul 2 n forma normala
Chomsky. Intr-o gramatica de aceasta forma arborii de derivare sunt ntotdeauna
arbori binari.

a n forma normala Chomsky si X p, p VG . Daca


Lema 3.2 Fie G o gramatic
cea mai lunga ramur
a din arborele AX,p contine m noduri, atunci |p| 2m1 .
Demonstratie. Procedam prin inductie asupra lui m.
Pentru m = 2 arborele are doua nivele si n mod evident |p| 2 = 2m1 .
Presupunem ca proprietatea este adevarata pentru un m oarecare si consideram un arbore care are pe cea mai lunga ramura m + 1 noduri. In derivarea

X p punem n evidenta prima derivare directa

XY Z p.

Conform lemei de localizare, p = p1 p2 si Y p1 , Z p2 . Arborii de derivare AY,p1


si AZ,p2 contin, fiecare pe cea mai lunga ramura cel mult m noduri; conform
ipotezei de inductie, avem |p1 | 2m1 , |p2 | 2m1 . Prin urmare
|p| = |p1 p2 | = |p1 | + |p2 | 2m1 + 2m1 = 2m .2

Observatie. Daca X p si |p| > 2m1 atunci exista n arborele AX,p cel putin
o ramura cu m + 1 noduri.

3.4. LEMA BARHILLEL

63

v 1 =A

v 2 =A
u

Figura 3.5: Descompunerea cuvantului p.

Lema 3.3 Fie G o gramatic


a de tipul 2 si fie XX1 . . . Xm p. Atunci, conform

lemei de localizare, p = p1 . . . pm si Xj pj , j = 1, . . . , m. Fie AY,q AX,p .


atunci q este subcuv
ant ntrunul din cuvintele pj .
Demonstratie. Neterminalul Y apartine unuia din subarborii AXj ,pj , fie acesta
AXk ,pk ; atunci AY,q AXk ,pk si q Sub(pk ). 2
Lema 3.4 (Lema BarHillel) Fie E un limbaj independent de context. Atunci
exist
a un numar natural k astfel nc
at, daca p E si |p| > k atunci p se poate
descompune n forma p = uvwxy cu urmatoarele propriet
ati:
1. vx 6= ;
2. |vwx| k;
3. uv j wxj y E, j N ,
Demonstratie. Fie n = card(VN ). Luam k = 2n . Cum |p| > k = 2n , conform
observatiei de la prima lema, exista n arborele AS,p cel putin o ramura cu n + 2
noduri; pe aceasta ramura ultimul nod este terminal, deci exista n + 1 noduri
etichetate cu acelasi simbol A. Descompunem cuvantul p ca n figura 3.5, p =
uvwxy.

(1) Consideram subarborele AA,vwx caruia i corespunde derivarea Avwx.


Punem n evidenta primul pas

ABC vwx,

si vwx se descompune n vwx = pB pC , B pB , C pC si pB , pC 6= . Cum AA,w


AA,vwx , rezulta ca w este subcuvant n pB sau n pC . Sa presupunem ca w
Sub(pC ); atunci pB Sub(v) si cum pB 6= rezulta v 6= .

64

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

(2)Putem alege nodurile v1 si v2 astfel ncat pe ramura punctata ncepand de


la v1 n jos pana la frontiera sa avem exact n + 1 noduri. Rezulta conform lemei
precedente, |vwx| 2n = k.

(3) putem scrie derivarile Aw, AvAx. Deci

S uAy uvAxy uv 2 Ax2 y . . . uv j wxj y.2


Problema nchiderii familiei L2 la intersectie
Teorema 3.9 Familia L2 nu este nchis
a la intersectie.
Demonstratie. Consideram limbajul L3 = {an bn cn |n 1}. Sa ratam ca L3 6 L2 .
Intradevar, sa presupunem ca L3 L2 si fie k constanta din lema BarHillel.
Luam n > k/3 si fie p = an bn cn ; avem |p| > k, deci conform acestei leme p se
descompune n forma p = uvwxy cu vx 6= si uv j wxj y L3 , j N .
Vom analiza posibilitatile de constituire a subcuvintelor v si x. Sa presupunem
ca n v (sau x) intra doua din simbolurile a, b, c; de exemplu v = aabbb. atunci
consideram cuvantul p2 = uv 2 wx2 y = uaabbaabbwx2 y care nu are structura cuvintelor lui L3 (a nu poate sa urmeze dupa b) dar conform lemei Bar-Hillel
apartine lui L3 . Deci, n v (sau x) nu pot intra doua (sau trei) din simbolurile
a, b, c. Sa presupunem ca intra un singur simbol; de exemplu v {a} si x {b} .
Atunci multiplicand n p subcuvintele v si x, puterile simbolurilor a si b se
maresc iar c ramane pe loc, contrazicanduse din nou structura cuvintelor din
L3 . In concluzie L3 nu este independent de context.
Fie acum limbajele
L03 = {am bn cn |m, n 1}
L3 = {an bn cm |m, n 1}.
Se poate vedea usor ca aceste limbaje sunt de tipul 2; gramaticile care le genereaza
sunt S aS|aA, A bAc|bc si respectiv S Sc|Ac, A aAb|ab.
Avem L03 L3 = L3 , deci intersectia a doua limbaje de tipul 2 este un limbaj
care nu apartine lui L2 .2
a la complementariere.
Corolar 3.10 Familia L2 nu este nchis
Intradevar, sa presupunem ca L2 este nchisa la complementariere si fie E1 , E2
L2 . Cum familia L2 este nchisa la reuniune, ar rezulta C(E1 ) C(E2 ) L2 . Dar
(de Morgan) C(E1 ) C(E2 ) = C(E1 C(E2 ) L2 .
Complementul limbajului C(E1 E2 ) este E1 E2 si conform presupunerii ar
trebui ca E1 E2 L2 , oricare ar fi E1 , E2 , ceea ce nu este adevarat.2
Generaliz
ari ale lemei BarHillel Lema lui BarHillel reprezinta o conditie
necesara ca un limbaj sa fie independent de context. cu ajutorul ei se poate
demonstra relativ usor ca anumite limbaje nu sunt independente de context.
Ideea este aceea ca prin multiplicarea subcuvintelor v si x, de un numar suficient
de ori, se contrazice structura limbajului.

3.5. AUTOMATE PUSH-DOWN (APD)

65

Totusi, nu orice limbaj care nu este de tipul 2 poate fi respins de lema lui
BarHillel. De exemplu, aceasta lema nu poate respinge limbajul
m

L = {an b2 |n, m 1} {b} ,


care nu este de tipul 2 (se demonstreaza pe alta cale). Intradevar, pentru orice
m
p = an b2 luam
m
u = , v = a, w = , x = , y = an1 b2 .
Putem itera subcuvintele v si x fara sa contrazicem structura cuvintelor limbajului.
O generalizare a lemei BarHillel este
Lema 3.5 (Lema lui Ogden) pentru orice limbaj independent de context L exist
a
o constant
a k astfel nc
at orice p L pentru care cel putin k simboluri sunt
marcate, se poate descompune n forma p = uvwxy astfel nc
at
1. sau u, v, w sau w, x, y contin fiecare cate un simbol marcat;
2. vwx contine cel mult k simboluri marcate;
3. uv j wxj y L, j N
Cu ajutorul acestei leme se poate arata ca limbajul de mai sus nu este de tipul
2, considerand marcate simbolurile b.

3.5

Automate push-down (APD)

Automatele push-down sunt mecanisme pentru recunoasterea limbajelor independente de context.


Un APD se compune din (vezi figura 3.6):
1. O banda de intrare care contine simboluri ale unui alfabet de intrare; aceste
simboluri constituie pe o banda un anumit cuvant peste alfabetul de intrare.
Banda se misca numai spre stanga;
2. O memorie push-down (memorie inversa, stiva, pila, etc) care contine simboluri ale unui alfabet propriu, numit alfabetul memoriei push-down. Aceasta
memorie functioneaza ca o stiva - ultimul introdus, primul extras (Last In,
First Out);
a care se afla permanent ntr-o anumita stare in3. Un dispozitiv de comand
terna apartinand unei multimi finite de stari. Dispozitivul de comanda
poseda un dispozitiv de citire de pe banda de intrare si un dispozitiv de
scriere-citire n memoria push-down.

66

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

Banda de intrare
i1

i2

i3

...

ik

i n-1

in

...

Dispozitiv de citire /scriere


Dispozitiv de citire
de pe banda

Dispoz itiv
de comanda

...

zm

s S

Memoria pushdown

z1
z0

Figura 3.6: Reprezentare schematica a unui automat push-down.


Ca si un automat finit, un automat push-down functioneaza n pasi discreti;
un pas de functionare comporta:
1. Dispozitivul de comada citeste simbolul de pe banda de intrare din dreptul
dispozitivului de citire si muta banda cu o pozitie spre stanga.
2. In functie de starea interna, de simbolul citit si de simbolul din varful
memoriei push-down dispozitivul de comanda efectueaza operatiile:
(a) Trece ntr-o noua stare;
(b) Scrie n memoria push-down un anumit cuvant peste alfabetul memoriei
push-down; n particular, acesta poate sa fie cuvantul vid, ceea ce are ca
efect stergerea simbolului din varful memoriei push-down.
Functionarea unui APD se termina n general dupa ce s-a citit ultimul simbol al
cuvantului scris pe banda de intrare dar este posibil ca el sa efectueze un anumit
numar de pasi, citind de fiecare data de pe banda cuvantul vid . De asemenea,
este posibil ca n timpul functionarii, deci nainte de a ajunge la ultimul simbol,
automatul sa se blocheze. De exemplu, automatul ajunge ntr-o configuratie
(stare, simbol pe banda, simbol n varful memoriei push-down) inadmisibila sau
se goleste memoria push-down dar nu s-a epuizat cuvantul de pe banda, etc.
Matematic, un APD se defineste astfel:
Definitie 3.9 Un automat push-down este un sistem
AP D = (, I, Z, f, s0 , z0 )
unde:

3.5. AUTOMATE PUSH-DOWN (APD)

67

este multimea de stari (finita si nevida);


I este alfabetul de intare;
Z este alfabetul memoriei push-down;
f : (I {}) Z P( Z ) este functia de evolutie;
s0 este starea initial
a;
z0 Z este simbolul initial al memoriei push-down.
Un APD are n general o functioanre nedeterminista, card f (s, i, z) 1; multimea
automatelor push-down deterministe formeaza o clasa speciala.
In termenii functiei de evolutie, un pas de evolutie comporta citirea simbolului
i de pe banda, citirea simbolului z din varful memoriei push-down, apoi, n functie
de starea interna s si de aceste doua simboluri, automatul trece ntr-o noua stare
s0 si scrie n memoria push-down un cuvant q Z astfel ncat (s0 , q) f (s, i, z).
In cazul n care f (s, i, z) = evolutia este oprita; este situatia n care automatul
se blocheza.
O stare a automatului (sau configuratie) este un sistem = (s, p, q) unde
s S este starea interna, p I este subcuvantul de pe banda de intrare ramas
de citit (inclusiv simbolul din dreptul dispozitivului de citire), iar q Z este
subcuvantul din memoria push-down.
Vom spune ca un APD trece direct din starea 1 = (s1 , p1 , q1 ) n starea 2 =
(s2 , p2 , q2 ) si vom scrie 1 72 daca se executa un pas de evolutie; daca p1 =
ip01 , q1 = zq10 putem avea (s2 , q) f (s1 , i, z) si atunci p2 = p01 , q2 = qq10 sau
(s2 , q) f (s1 , , z) si atunci p2 = p1 , q2 = qq10 .
Vom spune ca automatul evolueaza (fara specificatia direct) din starea 0 n

stare 00 si vom scrie 0 7 00 daca:


(1) 0 = 00 ;
(2) 1 , . . . , n astfel ncat 0 = 1 72 7 . . . 7n1 7n = 00 .
Limbajul recunoscut de un APD se poate defini n doua moduri:
(1) Limbajul recunoscut de un APD cu golirea memoriei push-down, este,
prin definitie

L(AP D) = {p|p I (s0 , p, z0 )7(s, , )}.


Aceata nseamna ca, pornind din starea interna s0 si avand n varful memoriei push-down simbolul z0 , cu ajutorul cuvantului p de pe banda de intrare,
automatul poate sa evolueze astfel ncat sa goleasca memoria push-down dupa
citirea cuvantului. Mentionam ca golirea memoriei push-down nu trebuie neaparat sa coincida cu citirea ultimului simbol al lui p; este posibil ca automatul
sa mai efectueze cativa pasi citind de pe banda simbolul .
(2) Limbajul recunoscut de un APD cu stari finale; n definitia automatului se
adauga o submultime f a lui numita multimea de stari finale. Prin definitie,
limbajul recunoscut de un APD cu stari finale este:

L(AP D) = {p|p I (s0 , p, z0 )7(s, , q), s f , q Z }.

68

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

Prin urmare, este necesar ca dupa citirea lui p, eventual dupa nca cativa pasi,
APD sa ajunga ntr-o stare finala. Vom vedea ca cele doua definitii sunt echivalente.
Limbaje recunoscute de automate push-down cu golirea memoriei. Vom
arata ca familia limbajelor recunoscute de APD cu stari finale coincide cu familia
limbajelor independente de context. In felul acesta, APD constituie mecanisme
analitice de definire a limbajelor de tipul 2.
Teorema 3.11 Un limbaj este independent de context daca si numai daca este
recunoscut de un automat pushdown cu golirea memoriei pushdown.
Demonstratie. Partea I E L2 E = L(AP D).
Fie G = (VN , VT , S, P ) o gramatica de tipul 2 n forma normala Greibach care
genereaza limbajul E. Construim un automat pushdown astfel:
AP D = ({s}, VT , VN , f, s, S), functia de evolutie fiind definita de:
A ip P (s, p) f (s, i, A),
altfel .

Fie p L(G), p = i1 . . . in , S p. Aceasta derivare trebuie sa aiba forma


G

(extrem stanga):
(A) Si1 X1 u1 i1 i2 X2 u2 u1 i1 i2 i3 X3 u3 u2 u1 . . . i1 . . . in ,
unde u1 , u2 , u3 , . . . VN = Z .
Observatie. Aparent, partea us us1 . . . u1 se mareste cu fiecare derivare directa. In realitate, unele din cuvintele uj sunt vide, si anume atunci cand se
aplica o regula de forma X i; n particular, n ultimele derivari directe se
aplica numai reguli de aceasta forma.
Avem
S i1 X1 u1 (s, X1 u1 ) f (s, i1 , S),
X1 i2 X2 u2 (s, X2 u2 ) f (s, i2 , X1 ),
X2 i3 X3 u3 (s, X3 u3 ) f (s, i3 , X2 ),
... .
Prin urmare automatul poate sa aiba urmatoarea evolutie:
(s, i1 i2 i3 i4 . . . in , S)7(s, i2 i3 i4 . . . in , X1 u1 )7
7(s, i3 i4 . . . in , X2 u2 u1 )7(s, i4 . . . in , X3 u3 u2 u1 )7 . . . .
Daca comparam aceasta evolutie cu derivarea (A) putem observa ca pe banda
de intrare avem la fiecare pas partea complementara a cuvantului (fata de derivare)
iar n memoria push-down se reproduce partea de neterminale din formele propozitionale

3.5. AUTOMATE PUSH-DOWN (APD)

69

ale derivarii. Cum n derivare se ajunge la i1 . . . in , n evolutie se va ajunge la


(s, , ).
Deci p L(AP D) si L(G) L(AP D).

Fie acum p L(AP D); va trebui sa aratam ca p L(G), deci ca S p.


G

Vom arata o implicatie ceva mai generala, si anume, pentru orice u VN , avem

(s, p, u)7(s, , ) u p.
G

In particular, daca u = S obtinem implicatia dorita.


Procedam prin inductie asupra lungimii lui p.
Daca |p| = 1, atunci p = i, u = X iar evolutia va avea un singur pas
(s, i, X)7(s, , ), deci (s, ) f (s, i, X) si X i P . Putem scrie u =
X i = p.
G

Presupunem ca implicatia este adevarata pentru un cuvant |p| = l si consideram un p astfel ncat |p| = l + 1. Fie i si X primele simboluri din p si u,

deci p = ip0 si u = Xu0 . In evolutia (s, p, u)7(s, , ) punem n evidenta prima


evolutie directa

(s, p, u) = (s, ip0 , Xu0 )7(s, p0 , vu0 )7(s, , ).


Din definitia evolutiei directe rezulta ca (s, v) f (s, i, X) deci X iv P . Pe

de alta parte din ipoteza inductiva rezulta ca vu0 p0 . Avem


G

u = Xu0 ivu0 ip0 = p,


G

ceea ce demonstreaza implicatia.


Prin urmare p L(G) si L(AP D) L(G), de unde L(G) = L(AP D).2
Partea II. E = L(AP D) E L2
Fie AP D = (, I, Z, f, s0 , z0 ). Construim G de forma G = (VN , VT , S, P )
unde VN = {s0 } {(s, z, s0 )|s, s0 , z Z}, VT = I, S = s0 , iar regulile de
generare le definim astfel:
(1) s0 (s0 , z0 , s), s ;
(2) Daca (s1 , z1 . . . zm ) f (s, i, z) vom introduce n P reguli de forma
(s, z, s0 ) i(s1 , z1 , s2 )(s2 , z2 , s3 ) . . . (sm , zm , s0 ),
unde s0 , s2 , . . . , sm ;
(3) Daca (s0 , ) f (s, i, z) vom introduce n P reguli de forma
(s, z, s0 ) i,

70

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

unde s0 .
Sa observam ca gramatica astfel construita este independenta de context, si
anume n forma normala Greibach.

Fie p L(AP D), deci (s0 , p, z0 )7(s0 , , ); trebuie sa aratam ca s0 p.


G

Vom arata implicatia ceva mai generala

(s, p, z)7(s0 , , ) (s, z, s0 ) p.


G

In particular pentru s = s0 , z = z0 rezulta (s0 , z0 , s0 )


p si putem scrie s0 (s0 , z0 , s0 ) p,
G

adica p L(G).
Procedam prin inductie asupra lungimii evolutiei l.
Daca l = 1 atunci (s, p, z)7(s0 , , ), deci p = i si (s0 , ) f (s, i, z) si
(s, z, s0 ) i este o regula, adica putem scrie (s, z, s0 )i = p.
Presupunem ca implicatia este adevarata pentru evolutii de lungime oarecare
l si consideram o evolutie de lungime l + 1; punem n evidenta prima evolutie
directa

(s, p, z) = (s, i1 p0 , z)7(s1 , p0 , z1 . . . zm )7(s0 , , ).


Descompunem cuvantul p0 n forma p0 = p1 . . . pm astfel ncat
(s1 , p1 , z1 )
(s2 , p2 , z2 )

7 (s2 , , ),

7 (s3 , , ),
...

(sm , pm , zm ) 7 (s0 , , ).

Observatie. Putem pune n evidenta felul n care se defineste cuvantul p1 urmarind


evolutia lui APD;
(s1 , i1 i2 . . . in , z1 z2 . . . zm )
7 (s01 , i2 i3 . . . in , qz2 . . . zm ) 7
(a)
(b)
...
7 (s2 , ij1 . . . in , z2 . . . zm )

(c)
La primul pas (situatia a) automatul este n starea s1 , pe banda este i1 iar n
memoria push-down este z1 . Dupa efectuarea unui pas, automatul trece n starea
s01 , muta banda cu o pozitie spre stanga, extrage pe z1 si scrie n memoria pushdown un cuvant q (situatia b). Se poate observa ca z2 a coborat; cum stim ca
memoria push-down se goleste (p L(AP D)), trebuie ca la un moment dat z2 sa
ajunga n varful stivei (situatia c). In acest moment partea din p citita va fi p1
iar starea n care a ajuns automatul o notam cu s2 . Este clar ca daca pe banda
am avea scris numai p1 am avea evolutia (s1 , p1 , z1 )7(s2 , , ).

3.5. AUTOMATE PUSH-DOWN (APD)

71

Analog p2 , . . . , pm .
Din definitia derivarii directe (s, i1 p0 , z)7(s1 , p0 , z1 . . . zm ) avem
(s1 , z1 . . . zm ) f (s, i1 , z) iar n P va exista regula
(s, z, s0 ) i1 (s1 , z1 , s2 )(s2 , z2 , s3 ) . . . (sm , zm , s0 )
unde luam starile s2 , . . . , sm cele rezultate la descompunerea lui p0 . Pe de alta
parte, din ipoteza inductiva, avem

(s1 , z1 , s2 )p1 ,

(s2 , z2 , s3 )p2 ,
...

(sm , zm , s0 )pm .
Putem scrie derivarea

(s, z, s0 )i1 (s1 , z1 , s2 )(s2 , z2 , s3 ) . . . (sm , zm , s0 )i1 p1 . . . pm = i1 p0 = p.


Dupa cum am vazut, rezulta mai departe p L(G) si L(AP D) L(G).
Pentru a demonstra incluziunea inversa, vom arata mai ntai implicatia

(s, z, s0 )p(s1 , z1 s2 ) . . . (sm , zm , s0 ) implica (s, p, z)7(s1 , , z1 . . . zm ).


Procedam prin inductie asupra lungimii derivarii l.
Daca l = 1 atunci p = i si se aplica regula
(s, z, s0 ) i(s1 , z1 , s2 ) . . . (sm , zm , s0 )
deci (s1 , z1 . . . zm ) f (s, i, z) si (s, i, z)7(s1 , , z1 . . . zm ).
Presupunem ca implicatia este adevarata pentru l oarecare si consideram o
derivare de lungime l + 1. Fie p = p0 i si punem n evidenta ultimul pas.

0
(s, z, s0 )p0 (s0j1 , zj1
, s0j )(sj , zj , sj+1 ) . . . (sm , zm , s0 )
0
p i(s1 , z1 , s2 ) . . . (sj1 , zj1 , sj )(sj , zj , sj+1 ) . . . (sm , zm , s0 ),
unde s0j = sj ; la ultimul pas s-a aplicat regula
0
(s0j1 , zj1
, sj ) i(s1 , z1 , s2 ) . . . (sj1 , zj1 , sj ).
0
)
Rezulta (s1 , z1 . . . zj1 ) f (s0j1 , i, zj1
0
0
(sj1 , i, zj1 )7(s1 , , z1 . . . zj1 ).

si putem scrie evolutia

Pe de alta parte, conform ipotezei inductive, avem

0
(s, p0 , z)7(s0j1 , , zj1
zj . . . z m )

Prin urmare

0
(s, p, z) = (s, p0 i, z)7(s0j1 , i, zj1
zj . . . zm )7(s1 , , z1 . . . zm )

72

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

si implicatia este demonstrata.

Fie acum p L(G), deci s0 p. T


inand seama de forma regulilor din G,
G

n aceasta derivare se va aplica prima data o regula de forma (1), apoi regula de
forma (2) iar la sfarsit reguli de forma (3). La aplicarea regulilor (2) putem rescrie
la fiecare pas simbolul neterminal cel mai din stanga, deci sa obtinem o derivare
extrem stanga. Sa observam ca n acest caz structura formelor propozitionale
intermediare este cea mentionata, p(s1 , z1 , s2 )(s2 , z2 , s3 ) . . . (sm , zm , s0 ).
Prin urmare, derivarea va avea forma

s0 (s0 , z0 , s0 )p(s1 , z1 , s2 ) . . . (sm , zm , s0 )p.


Trebuie sa avem regulile (sj , zj , sj+1 ) , j = 1, . . . , m, sm+1 = s0 si putem
scrie

(s0 , p, z0 )7(s1 , , z1 . . . zm )7(s2 , , z2 . . . zm )7 . . . 7(s0 , , )


adica p L(AP D) si L(G) L(AP D).2
Automate pushdown cu st
ari finale. Vom nota un automat push-down
cu stari finale cu AP Df .
Teorema 3.12 Un limbaj este recunoscut de un automat pushdown daca si numai daca este recunoscut de un automat pushdown cu stari finale.
Demonstratie. Partea I E = l(AP D) E L(AP Df ).
Daca AP D = (, I, Z, f, s0 , z0 ) construim un automat pushdown cu stari
finale astfel
AP Df = ( {s00 , sf }, I, Z {z00 }, f 0 , s00 , z00 )
unde multimea de stari finale este {s} iar functia de evolutie este definita de:
f 0 (s, i, z) = f (s, i, z), s , i I {}, z Z;
f 0 (s00 , , z00 ) = (s0 , z0 z00 );
f (s, , z00 ) = (sf , ), s ;
n rest .

Fie p L(AP D); atunci (s0 , p, z0 )7(s, , ). Evident ca aceiasi evolutie o


poate avea si automatul pushdown cu stari finale. Putem scrie n AP Df evolutia
(AP Df ) :

(s00 , p, z00 )7(s0 , , z00 )7(s, , ),

deci p L(AP Df ) si L(AP D) L(AP Df ).


Invers, fie p L(AP Df ), atunci (n AP Df )

(s00 , p, z00 )7(s, p, z0 z00 )7(sf , , q).


Ultimul pas trebuie sa fie de forma (s, , z00 )7(sf , , ) pentru ca nu exista alta
valoare a lui f care sa ne duca ntr-o stare finala. Deci (n AP Df )

(s00 , p, z0 z00 )7(s, , z00 )7(sf , , )

3.6. AUTOMATE PUSHDOWN DETERMINISTE

73

si putem scrie n APD evolutia (s0 , p, z0 )7(s, , ), adica p L(AP D) si


L(AP Df ) L(AP D).2
Partea II E = L(AP Df E L(AP D).
Fie AP Df = (, I, Z, f, s0 , z0 , f ) un automat pushdown cu stari finale
(multimea starilor finale este f ) si construim un APD astfel
AP D = ( {s00 , s0 }, I, Z {z00 }, f 0 , s00 , z00 )
unde
f 0 (s, i, z) = f (s, i, z), s , i I {}, z Z;
f (s00 , , z00 ) = (s, z0 z00 );
f (s, , z) = (s0 , ), s f {s0 }, z Z {z00 };
n rest .

Fie p L(AP Df ), atunci (s0 , p, z0 )7(s, , q), s f . Este evident ca n

APD avem evolutia (s0 , p, z0 )7(s, , q). Putem scrie

AP D : (s00 , p, z00 )7(s0 , p, z0 z00 )7(s, , qz00 )7(s0 , , ),


deci p L(AP D) si L(AP Df ) L(AP D).
Invers, fie p L(AP D). Avem

AP D : (s00 , p, z00 )7(s0 , p, z0 z00 )7(s, , ).


Simbolul z00 nu poate fi sters decat cu o regula de forma f (s, , z) = (s0 , ),
s f {s0 }, deci APD trebuie sa ajunga ntr-o stare s f , apoi sa ramana n
s0 .

AP D : (s0 , p, z0 z00 )7(s, , qz00 ), s f .


Putem scrie

AP Df : (s0 , p, z0 )7(s, , q), s f


si deci p L(AP Df ), adica L(AP D) L(AP Df ).2

3.6

Automate pushdown deterministe

Functionarea unui APD este n general nedeterminista, card f (s, i, z) 1. Pentru ca un APD sa aiba o functionare determinista nu ete suficient sa impunem
conditia card f (s, i, z) = 1, deoarece daca pentru un anumit s si z Z avem
f (s, , z) 6= si f (s, i, z) 6= , putem face un pas citind sau citind i.
Definitie 3.10 Un automat pushdown este determinist daca
(1) card f (s, i, z) 1, s , i I {}, z Z;
(2) daca f (s, , z) 6= , atunci f (s, i, z) = , i I.

74

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

Un limbaj recunoscut de un APD determinist l vom numi limbaj independent


de context (sau de tipul doi) determinist. Familia limbajelor independente de
context deterministe este inclusa (strict) n familia limbajelor de tipul 2 (dupa
cum vom vedea).
Un APD se poate bloca n urmatoarel doua situatii
1. Automatul ajunge n starea s, n varful memoriei pushdown se afla simbolul z, pe banda de intrare urmeaza i si f (s, i, z) = f (s, , z) = ;
2. Intra ntr-un ciclu infinit citind de pe banda ; de exemplu f (s, , z) = (s, z)
si f (s, i, z) = pentru o anumita pereche (s, z).
Definitie 3.11 Un APD determinist este neblocabil dac
a pentru orice cuvant

p I exist
a o evolutie de forma (s0 , p, z0 )7(s, , q).
Intr-un APD determinist neblocabil orice cuvant peste I poate fi citit. Evident, de aici nu rezulta ca orice cuvant este recunoscut de APD.
Lema 3.6 Un APD determinist cu stari finale este echivalent cu un APD determinist cu stari finale neblocabil (relativ la prima situatie de blocare).
Demonstratie.Fie AP Df = (, I, Z, f, s0 , z0 , f ). Construim AP Df0 = (
{s00 , s0 }, I, Z {z00 }, f 0 , s00 , z00 , f ) unde:
(1) f 0 (s, i, z) = f (s, i, z) daca f (s, i, z) 6= , s , i I {}, z Z;
(2) f 0 (s, i, z) = (s0 , z) daca f (s, i, z) = f (s, , z) = , s , i I, z Z;
(3) f 0 (s0 , i, z) = (s0 , z), i I, z Z;
(4) f 0 (s0 , , z00 ) = (s0 , z0 z00 ).
Avem
p L(AP Df ) (s0 , p, z0 )
(s00 , p, z00 )

AP Df0

|=

(s0 , p, z0 z00 )

AP Df

|= (s, , q), s f

AP Df0

|= (s, , qz00 ), s f p L(AP Df0 ).

Deci L(AP Df ) = L(AP Df0 .2


Observatie. Intr-o situatie de blocare (s, ip, zq) si f (s, i, z) = f (s, , z) =
putem scrie
AP Df0

AP Df0

AP Df0

(s, ip, zq) |= (s , p, zq) |= . . . |= (s0 , , zq).


Teorema 3.13 Orice limbaj independent de context determinist este recunoscut
de un APD determinist neblocabil.

3.6. AUTOMATE PUSHDOWN DETERMINISTE

75

Demonstratie. Fiind dat un APD determinist vom construi un APD determinist neblocabil echivalent. Conform lemei anterioare putem presupune ca nu
are loc prima situatie de blocare.
Daca are loc a doua situatie de blocare, putem avea doua cazuri:
1. continutul memoriei pushdown se mareste nelimitat;
2. lungimea cuvintelor scrise n memoria pushdown nu depaseste un anumit
numar.
Fie card() = n, card(Z) = k, l = max{|q|, q Z | (s0 , q) f (s, i, z)}.
Cazul 1. Exista n total un numar nk de perechi de forma (s, z). Daca n
evolutia lui APD s-ar succede numai configuratii cu perechi de forma (s, z) distincte atunci lungimea cuvantului din memoria pushdown ar creste la maximum

nkl simboluri. Prin urmare, daca (s0 , , 0 )7(s , , ) si | | |0 | > nkl,


atunci n aceasta evolutie trebuie sa existe doua configuratii cu aceiasi stare s si
cu acelasi simbol z n varful memoriei pushdown. Deci

(s0 , , 0 )7(s, , zr)7(s, , zqr)7(s , , ),


de unde urmeaza ca

(s0 , , 0 )7(s, , zr)7(s, , q m r), m N.


Cazul II Lungimea cuvantului scris n memoria pushdown nu depaseste nkl,
caci daca | | |0 | > nkl, ar rezulta ca n memoria pushdown am avea
zq m , m N si lungimea cuvantului nu ar fi finita.2
Teorema 3.14 Dac
a E este un limbaj independent de context determinist atunci
limbajul complementar I \ E este de asemenea independent de context determinist.
Demonstratie. Fie AP Df = (, I, Z, f, s0 , z0 , f ) automatul pushdown determinist care recunoaste limbajul E. Construim un automat pushdown determinist care va recunoaste limbajul I \ E n modul urmator
AP Df0 = ( {1 , 2 , 3 }, I, Z, f 0 , s00 , z0 , 0f )
unde

s00

(s0 , 1 ) pentru s0 f ,
(s0 , 2 ) pentru s0 6 f ,

multimea de stari finale este 0f = {(s, 3 )|s } iar functia de evolutie este
definita de

76

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

(1) daca f (s, i, z) = (s0 , q) atunci


f 0 ((s, 1 ), i, z) = ((s0 , k 0 ), q),
f 0 ((s, 2 ), i, z) = ((s, 3 ), q),
f 0 ((s, 3 ), i, z) = ((s0 , k 0 ), q);
(2) daca f (s, , z) = (s0 , q) atunci
f 0 ((s, 1 ), , z) = ((s0 , k 0 ), q),
f 0 ((s, 3 ), , z) = ((s0 , k 0 ), q);
unde k 0 = 1 daca s0 f si k 0 = 2 daca s0 6 f .

Fie p L(AP Df0 ), atunci ((s0 , k ), p, z0 )7((s, 3 ), , q), k = 1, 2. In mod


necesar, ultima configuratie trebuie sa fie precedata de o configuratie de forma
((s0 , 2 ), , q), deci

(A) ((s0 , k ), p, z0 )7((s0 , 2 ), , q)7((s, 3 ), , q)

de unde rezulta ca (s0 , p, z0 )7(s0 , , q) si s0 6 f . Deci p I \E si L(AP Df0 )


I \ E.

Invers, fie p I \ E, atunci n AP Df0 avem evolutia (s0 , p, z0 )7(s, , q), s 6


f si putem scrie evolutia (A). Prin urmare p L(AP Df0 ), adica I \ E
L(AP Df0 ).2
Consecint
a. Putem enunta proprietatea de mai sus astfel: Familia limbajelor
independente de context deterministe este nchisa la complementariere. Cum
familia limbajelor independente de context nu este nchisa la complementariere
si cum ea coincide cu familia limbajelor recunoscute de automatele pushdown
nedeterministe putem mai departe obtine urmatorul rezultat:
APD nedeterministe nu sunt echivalente cu APD deterministe.

3.7

Probleme propuse

1. Sa se arate ca L(G) = {(ab)n a|n 0} unde G are productiile S


SbS, S a. Sa se construiasca o gramatica echivalenta cu G care sa
fie neambigua.
2. Eliminati redenumirile din gramatica GE ce genereaza expresiile aritmetice
simple.
3. Aduceti la forma normala Chomsky gramaticile ce au regulile:
(a) S T bT, T T aT |ca;
(b) S aAC, A aB|bAB, B b, C c;
(c) S A.A, A 0A|1A| . . . 9A|.
4. Gasiti forma normala Greibach pentru gramaticile:

3.7. PROBLEME PROPUSE

77

(a) A1 A2 A3 , A2 A1 A2 |1, A3 A1 A3 |0.


(b) GE care genereaza expresiile aritmetice simple.
5. Construiti un automat pushdown pentru recunoasterea limbajului:
(a) L = {w|w {a, b} , numarul literelor a n w este egal cu numarul
literelor b n w };
(b) L = {w|w {a, b} , w = w};

(c) L = {w|w {(, )} , w este un cuvant n care fiecare paranteza deschisa


are o pereche, paranteza nchisa }.
6. Folosind lema de pompare sa se arate ca urmatoarele limbaje nu sunt independente de context:
(a) L = {ai bj ck |i < j < k};
(b) L = {ai bj |j = i2 };
(c) L = {an bn cn |n 1};
(d) L = {ai |i prim };
(e) L = {ai bi cj |j i};

78

CAPITOLUL 3. LIMBAJE INDEPENDENTE DE CONTEXT

Capitolul 4
Analiza Sintactic
a
Analiza sintactica este o faza a procesului de compilare care are urmatoarele doua
obiective principale:
Stabileste daca un cuvant dat apartine sau nu limbajului, deci daca cuvantul
este corect din punct de vedere sintactic. In particular limbajul poate
fi definit de o gramatica generativa de tip Chomsky si deci termenul de
analiza sintactica trebuie nteles n sensul teoriei limbajelor formale. Mai
mentionam ca prin cuv
ant ntelegem orice structura constituita cu simbolurile acceptate de limbaj, n particular un ntreg program, dar de obicei
ne vom margini la anumite entitati, de exemplu, o linie sau un rand.
Determina derivarea (arborele de derivare) corespunzator cuvantului. Odata
cu aceasta operatie sunt degajate anumite structuri pentru care se poate
genera cod intermediar, structuri pe care le vom numi unitati sintactice.
Pe langa aceste obiective principale se mai efectuaza si alte operatii, de exemplu, analiza si tratarea erorilor, prelucrarea tabelelor, etc. Rezultatul analizei sintactice va fi un fisier care contine derivarile (arborii de derivare) corespunzatoare unitatilor sintactice n care este descompus programul: expresii aritmetice, declaratii, etc. Acest fisier este utilizat n faza de generare a formatului
intermediar. In mod curent nsa, generatoarele de format intermediar sunt niste
rutine, apelate de analizorul sintactic, astfel ncat formatul intermediar se obtine
succesiv.
Teoretic, problema analizei sintactice este rezolvata de automatele corespunzatoare
diverselor tipuri de limbaje; aceasta cale conduce nsa la algoritmi cu complexitate mare (numar mare de stari, functie de tranzitie conmplexa, etc.). Exista
algoritmi speciali de analiza sintactica cu eficienta supe- rioara. In continuare ne
vom ocupa cu doua clase de astfel de algoritmi:
Algoritmi top-down (de sus n jos);
Algoritmi bottom-up (de jos n sus).
79


CAPITOLUL 4. ANALIZA SINTACTICA

80

4.1
4.1.1

Algoritmi TOP-DOWN
Algoritmul general de analiz
a top-down

Algoritmul general de analiza top-down are un principiu foarte simplu: se aplica


n mod sistematic regulile de generare, ncep
and cu simbolul de start; n cazul unui
esec se revine n sus si se ncearc
a o alta regul
a. Regulile se aplica n ordinea
n care sunt scrise n gramatic
a, far
a sa existe o anumita ordine preferential
a
de scriere, ntruc
at natura algoritmului nu permite nici un fel de ierarhizare a
regulilor din punctul de vedere al frecventei de utilizare.
Pentru descrierea riguroasa a acestui algoritm am urmat modelul din cartea
lui D. Gries, Compiler construction for digital compters.
Fie G = (VN , VT , x0 , P) o gramatica de tipul 2 si p VT . Ne intereseaza
urmatoarele doua probleme:
(a) p L(G)?,
(b) Daca p L(G) atunci sa se determine derivarea x0 p.
Consideram toate regulile care au X0 n stanga:
x0 x11 . . . x1n1 |x21 . . . x2n2 | . . . |xp1 . . . xpnp
Initial x0 devine activ si alege prima regula x0 x11 . . . x1n1 . Daca aceasta

alegere este corecta trebuie sa avem x0 x11 . . . x1n1 p si n conformitate cu


lema de localizare a gramaticilor de tipul 2, cuvantul p se poate descompune n

forma p = p1 p2 . . . pn1 , unde x1j pj , j = 1, . . . n1 .

Simbolul x0 l activeaza pe x11 si i cere sa gaseasca derivarea x11 p1 ; daca x11


reuseste, transmite lui x0 succes. Simbolul x0 l dezactiveaza pe x11 , l activeaza pe

x12 si i cere sa gaseasca derivarea x12 p2 , etc. Daca toate simbolurile activate de
x0 transmit succes, constructia este terminata. Sa presupunem ca x1j transmite
esec; atunci x0 l dezactiveaza pe x1j , l reactiveaza pe x1j1 caruia i transmite:
Mi-ai dat o derivare, dar aceasta nu este buna, ncearc
a alta. Daca x1j1 reuseste,
procesul se continua spre dreapta; daca nu, atunci x0 l dezactiveaza pe x1j1 ,
l reactiveaza pe x1j2 caruia i cere o alta derivare. Procesul se continua n
acest mod fie spre dreapta, fie spre stanga. Daca se ajunge la x11 si acesta nu
reuseste sa gasasca o alta derivare, x0 decide ca prima regula aleasa nu este buna
si ncearca cu urmatoarea regula, adica x0 x21 . . . x2n2 , s. a. m. d.
Observatii
Fiecare simbol devenit activ, procedeaza exact ca si parintele sau, alege
prima regula, activeaza primul simbol, etc.
Nu se cunoaste anticipat descompunerea p = p1 p2 . . . pn1 . Deci x1j trans
mite succes daca reuseste sa gaseasca o derivare x1j pj , unde pj este un
subcuvant oarecare al lui p, cu singura conditie ca p1j sa nceapa din punctul
unde s-a terminat p1j1 . De exemplu, daca p = i1 i2 . . . i8 . . . si p1 = i1 i2 i3 i4 ,

4.1. ALGORITMI TOP-DOWN

81

p2 = i5 i6 , atunci x13 trebuie sa gaseasca o derivare de forma x13 i7 i8 . . ..


In particular, daca x1j VT decizia de succes sau esec depinde de faptul
daca x1j coincide sau nu cu simbolul din p care urmeaza (In exemplul de
mai sus, daca x13 coincide sau nu cu i7 ).
Cand se reactiveaza un simbol si i se cere o noua derivare, acesta reactiveaza
ultimul simbol fiu si i cere acelasi lucru.
Exemplu Consideram urmatoarea gramatica GE care genereaza expresii aritmetice simple. Operanzii sunt notati simbolic cu a, operatorii sunt + si * iar
ordinea naturala a operatiilor este completata de paranteze.

E T + E|T

T F T |F
F (E)|a

Procesul de analiza sintactica top-down pentru cuvantul p = aa este prezentat n figura 4.1.
In aceasta figura, revenirile n sus au fost marcate prin ncadrarea ntr-un
dreptunghi a subarborelui care a condus la un esec. Dreptunghiurile interioare
au semnificatia unor esecuri realizate mai devreme (este vorba de timpul de
desfasurare al procesului). Arborele corespunzator cuvantului este cel nencadrat
n vreun dreptunghi (n figura acesta este situat n partea dreapta).

4.1.2

Analiza top-down f
ar
a reveniri

In cazul unor gramatici cu o forma speciala se poate face o analiza de tip top-down
fara reveniri. Principala conditie este ca n cazul mai multor alternative (reguli cu
acelasi simbol n stanga), sa se poata decide cu precizie ramura corecta. In general
o astfel de decizie se poate realiza prin analiza unor simboluri care urmeaza n
cuvantul de analizat.
Exemplu Consideram urmatoarea gramatica G care genereaza secvente de
declaratii si instructiuni cuprinse intre cuvintele cheie Program si EndProgram. Declaratiile sunt notate simbolic cu d,iar instructiunile cu i. Fiecare
instructie sau declaratie se ncheie cu ;, exceptand cazul celei ce precede EndProgram.

< program > P rogram D I EndP rogram

D d; X

X d; X|

I iY

Y ; iY |

Sa consideram urmatorul cuvant de analizat


CAPITOLUL 4. ANALIZA SINTACTICA

82

E
7

5
1
(

*
3

F
2
(

F
8
(

10
E

F
9
(

i
F
4
(

F
E

11
(

i
i
F
6
(

Figura 4.1: Arborele sintactic pentru p = i i

4.1. ALGORITMI TOP-DOWN

83

Program
d;
d;
i;
i;
i;
EndProgram
O derivare extrem stanga pentru acest cuvant este
< program > P rogram D I EndP rogram P rogram d; X I EndP rogram
P rogram d; d; X I EndP rogram P rogram d; d; I EndP rogram
P rogram d; d; iY EndP rogram P rogram d; d; i; iY EndP rogram
P rogram d; d; i; i; iY EndP rogram P rogram d; d; i; i; i EndP rogram
Pentru constructia derivarii extrem stangi se procedeaza astfel: initial se considera simbolul de start < program > pentru care se alege singura regula disponibila (daca primul simbol din sirul de analizat nu coincide cu primul terminal al
regulii se poate decide imediat eroare sintactica).Urmatorul simbol neterminal
pentru care trebuie aleasa o regula este D iar sirul ramas de analizat (de generat)
ncepe cu d, astfel ca regula aleasa va fi D d; X. Din cuvantul initial trebuie
generata n continuare secventa d; i; i; i; EndP rogram ce ncepe cu d iar neterminalul cel mai din stanga este X, astfel ca se alege regula ce ncepe cu d. In
continuare, din cuvantul initial ramane de generat secventa i; i; i; EndP rogram
ce ncepe cu i iar neterminalul cel mai din stanga este X, astfel ca se alege regula
ce X , s.a.m.d.
Daca se considera gramatica ce genereaza expresii aritmetice simple, n forma
considerata la algoritmul general top-down (4.2.9), atunci la primul pas al unei
derivari extrem stangi pentru cuvantul (a + a a) + a nu se poate decide regula
de ales prin citirea primului terminal ( deoarece ar fi necesar sa consultam sirul
rezultat pana la ntalnirea operatorului + aflat dupa paranteza nchisa.
O gramatica pentru care alegerea regulii de aplicat este unic determinat
a
de urmatorul simbol terminal din sirul de analizat se numeste gramatica LL(1)
(Left to right parsing, Leftmost derivation, 1 symbol lookahead). In multe cazuri
exista posibilitatea de a transforma gramatica ntr-una echivalenta de tip LL(1).
Pentru cazul particular al gramaticii pentru generarea expresiilor aritmetice, o
gramatica echivalenta este urmatoarea:

E T E0

0
0
0

E +T E | T E |

T FT0

T 0 F T 0 |/F T 0 |

F (E)|id|num


CAPITOLUL 4. ANALIZA SINTACTICA

84

< bloc > {< lista >}


< lista >< instr > L
L ; < instr > L |
< instr > id = E|if (E)then < instr > |while(E)do < instr > |{< lista >}
E T E0
E 0 +T E 0 | T E 0 |
T FT0
T 0 F T 0 |/F T 0 |
F (E)|id|num
Figura 4.2: Gramatica pentru generarea blocurilor de instructiuni.

{
a = 2;
b = b + 1;
if ( b-a ) then { x = x-1;
a = 3 };
c = b*72
}
Figura 4.3: Program sursa de analizat sintactic

4.1.3

Programarea unui analizor sintactic. Studiu de caz

Programarea unui analizor sintactic top-down fara reveniri se poate face relativ
usor asociind cate o functie la fiecare neterminal. Analiza unui cuvant revine
la un sir de apeluri corespunzatoare tratarii simbolurilor ce apar pe parcursul
constructiei derivarii extrem stangi. Fiecare functie asociata contine o singura
instructiune switch cu clauze ce corepund regulilor gramaticii. Alegerea regulii
se face dupa urmatoarea unitate lexicala din textul de analizat.
Sa consideram urmatoarea gramatica (vezi figura 4.2) ce genereaza un bloc
de instructiuni de atribuire, conditionale de tip if (expresie aritmetica) then
instructiune sau repetitive de tip while. Instructiune poate fi o instructie simpla
sau bloc de instructiuni separate prin delimitatorul ;(SEMICOLON).
Un text sursa ce poate fi analizat de aceasta gramatica este cel din figura 4.3.
Lista de unitati lexicale furnizate de analizorul lexical este pentru acest caz
LBRACE id LET num SEMI id LET id PLUS num SEMI if LPAR id MINUS id
RPAR then LBRACE id LET id LET id minus num SEMI id LET num RBRACE
SEMI id LET id ORI num RBRACE.

4.1. ALGORITMI TOP-DOWN

85

Un program pentru analiza sintactica top-down fara reveniri corespunzator


gramaticii din figura 4.2 este reprezentat partial n figura 4.4. Lista codurilor
de unitati lexicale (terminalele gramaticii) contine SEMI LPAR RPAR s.a.m.d.
Presupunem ca analizorul lexical functioneaza ca functie ce returneaza codul
urmatoarei unitati lexicale din textul sursa. Variabila de tip ntreg token contine
codul returnat de analizorul lexical ALEX(). S-au mai definit doua functii: err()
pentru tratarea erorilor de sintaxa depistate si eat(int tok) ce consuma din textul
sursa unitatea lexicala tok pe care ne asteptam sa o gasim n text.
Rularea programului pentru exemplul din figura 4.3 va produce o secventa de
apeluri recursive ca n figura 4.5.
Un pic de algebr
a
Vom da n cele ce urmeaza o definitie riguroasa a gramaticilor LL(k) (k simboluri citite n avans) vom da n cele ce urmeaza , mpreuna cu conditiile necesare
si suficiente ca o gramatica sa intre n aceasta categorie.
Definitie Fie G = (VN , VT , S, P) o gramatica independenta de context. G se
zice de tip LL(k) daca si numai daca oricare ar fi doua derivari extrem stangi

S uXv uv u

S uXv uv u unde X P, X P, , VT+


din k = k rezulta = (notatia k nseamna primele k simboluri din sirul ).
Pentru k = 1 se obtine cazul gramaticilor din sectiunile precedente. Restrictia
asupra numarului de simboluri citite n avans restrange drastic multimea limbajelor ce por fi analizate cu astfel de gramatici. Un inconvenient major pentru
k > 1 este cresterea exponentiala a dimensiunii tabelei de predictie (cate o intrare n tabel pentru fiecare combinatie de k simboluri. O varianta mai eficienta
de analiza se obtine cu gramatici LR(1) (Left to right parsing, Rightmost derivation, 1 symbol lookahead).
Pentru orice VG+ , X VN , X P vom considera urmatoarele
multimi:

P rim() = {a VT |a, VG }

U rm() = {a VT |S uXv, a P rim(v)}

SD(X, ) = {a VT | a P rim() sau ( si a U rm(X) )}

N U LL(G) = {X VN |X }
Daca un terminal a P rim() atunci a poate aparea pe prima pozitie ntr-un
sir derivat din . Multimea SD(X, ) poarta denumirea de multimea simbolurilor
directoare asociate regulii X , iar N U LL(G) contine neterminalele ce se pot
sterge (n unul sau mai multi pasi) cu reguli din G.
Teorem
a.
G LL(k) SD(X, ) SD(X, ) = , X , X P, 6=


CAPITOLUL 4. ANALIZA SINTACTICA

86

final int if=1, then=2, LPAR=3, RPAR=4, LBRACE=5, RBRACE=6,


PLUS=7, MINUS=8, ORI=9, DIV=10, SEMI=11, id=12,
while=13, do=14, LET=15;
void err();
int ALEX();
int token = ALEX();
void eat(int tok){
if (tok==token) token=ALEX else err()
};
void bloc(){
eat(LBRACE); lista(); eat(RBRACE)
};
void lista(){
instr();L()
};
void L(){
switch(token){
case SEMI: eat(SEMI); instr(); L(); break;
default: break }
};
void instr(){
switch(token){
case if: eat(if); eat(LPAR); E(); eat(RPAR); eat (then); instr(); break;
case id: eat(id); eat(LET); E(); break;
case while: eat(while); eat(LPAR); E(); eat(RPAR); eat(do); instr(); break;
case LBRACE: eat(LBRACE); instr(); eat(RBRACE); break;
default: printf("syntax error: if, identif, while or left brace expected");
err()}
};
...
void E(){
T(); Eprime();
};
void Eprime(){
switch(token) {
case PLUS: eat(PLUS);T();Eprime();break;
case MINUS: eat(MINUS);T();Eprime();break;
default: break;
}
};
...
Figura 4.4: Cod C corespunzator analizorului sintactic

4.1. ALGORITMI TOP-DOWN

bloc()
eat(LBRACE);
lista()
instr()
eat(id);
eat(LET);
E()
T()
F()
eat(num);
return_F;
Tprime()
return_Tprime;
return_T;
Eprime()
return_Eprime;
return_E;
return_instr;
L()
eat(SEMI)
instr()
.... aici se recunoaste ; b = b + 1
return_instr;
L()
eat(SEMI);
instr()
.... aici se recunoaste ; if ( ... }
return_instr;
L()
.... aici se recunoaste ; c = b * 72
return_L();
return_L;
return_L;
return_lista;
eat(RBRACE);
return_bloc;
Figura 4.5: Executia analizei lexicale pentru textul sursa

87


CAPITOLUL 4. ANALIZA SINTACTICA

88

Determinarea multimilor definite anterior se poate face usor. Pentru N U LL(G),


se poate aplica algoritmul definit la eliminarea regulilor de stergere pentru o gramatica independenta de context.
N U LL = {X VN |X P}
repeat
(1) AU X = N U LL;
(2) N U LL = N U LL {X VN |X p, p AU X + };
until N U LL = AU X2
Calculul multimilor P rim(X) si U rm(X) se poate face cu algoritmul urmator:
Pas 1: { Initializare }
P rim(a) = {a}; a VT
P rim(X) = U rm(X) = ; X VN
Pas 2: Repeat
Pentru fiecare regula X Y1 Y2 . . . Yk Do
For(i = 1; i k; i + +)
(2.1)if (i = 1 sau Y1 Y2 . . . Yi N U LL+ )
P rim(X) = P rim(X) P rim(Yi );
(2.2)if (i = k sau Yi+1 . . . Yk N U LL+ )
U rm(Yi ) = U rm(Yi ) U rm(X);
(2.3)For (j = i + 1 j k; j + +)
if (j = i + 1 sau Yi+1 . . . Yj1 N U LL+ )
U rm(Yi ) = U rm(Yi ) P rim(Yj );
end for
end for
end do
Until P rim(X), U rm(X) nu se schimba la o iteratie.2
Calculul multimilor P rim() revine la definitia recursiva
(

P rim(X) =

P rim(X)
dac0 a X
/ N U LL(G)
P rim(X) P rim() dac0 aX N U LL(G)

Daca se considera gramatica ce genereaza expresii aritmetice 4.1.2, atunci


rezultatul aplicarii algoritmilor este prezentat n tabelul urmator:
E
E0
T
T0
F

N U LL P rim
U rm
(, i
)
DA
+,
)
,
(, i +, , )
DA
, / +, , )
(, i
, /, )

4.1. ALGORITMI TOP-DOWN

89

iar multimile simbolurilor directoare sunt


SD(E, T E 0 ) = {( , i}
SD(E 0 , +T E 0 ) = {+}
SD(E 0 , ) = {)}
SD(T, F T 0 ) = {( , i}
SD(T 0 , F T 0 ) = {}
SD(T 0 , ) = {+ )}
SD(F, (E)) = {(}
SD(F, id) = {id}
SD(F, num) = {num}
Functiile C sau Java corespunzatoare neterminalelor se modifica putin, n sensul ca vom avea clauze corespunzatoare simbolurilor terminalelor ce se regasesc
n multimile simbolurilor directoare asociate regulilor. Daca la reconstructia derivarii trebuie aplicata o regula pentru X si urmatorul terminal din textul de
analizat nu face parte din multimea simbolurilor directoare asociate vreunei reguli cu X n stanga, atunci se apeleaza modulul de tratare a erorilor sintactice.
Pentru cazul gramaticii anterioare, cateva din secventele de cod asociate neterminalelor sunt prezentate n continuare.
...
void E(){
switch(token) {
case LPAR:
case id:
case num: T(); Eprime(); break;
default: printf("syntax error: (,identifier or number expected");
err()
}
}
void Tprime(){
switch(token) {
case ORI: eat(ORI);F();Tprime();break;
case DIV: eat(DIV);F();Tprime();break;
case PLUS:
case RPAR: break;
default: printf("syntax error: *,/,+,) expected");
err()
}
}
Tratarea erorilor este dependenta de proiectantul compilatorului si limbaj.
Principial, exista trei modalitati de tratare.


CAPITOLUL 4. ANALIZA SINTACTICA

90

Se opreste analiza sintactica n punctul unde s-a depistat o eroare, cu transmiterea unui mesaj prietenos catre utilizator, de exemplu: Eroare sintactic
a: asteptam sa urmeze delimitator de instructiune. Mai nvat
a sintaxa
limbajului! BYE!.
Se ncearca repararea greselii de sintaxa inserand n textul sursa un simbol
din multimea de simboluri directoare asociate regulii ce s-a aplicat. Desigur
ca este suficient sa presupunem ca am inserat n text, astfel ncat analiza
poate continua (desigur nu vom uita sa anuntam utilizatorul ca nu cunoaste
regulile de sintaxa si l-am corectat noi!). Inserarea poate conduce la cicluri
infinite, astfel ca nu este recomandabila totdeauna.
Se ncearca gasirea unui simbol ce se potriveste ignorand toate terminalele
textului sursa pana se ntalneste un simbol din multimea simbolurilor directoare. Se transmite acelasi mesaj prietenos catre autorul textului sursa,
apoi se continua analiza.

4.2
4.2.1

Algoritmi BOTTOM-UP
Gramatici cu precedent
a simpl
a

Fie G = (VN , VT , x0 , P) o gramatica de tipul doi si p L(G) o forma propozitionala,

adica un cuvant peste alfabetul general VG astfel ncat x0 p. Vom nota cu Ax0 ,p
arborele de derivare care are radacina x0 si frontiera p.
Definitia 1. Vom spune ca f este o fraza simpla a lui p daca f este un
subcuvant al lui p si n plus:
x VN , cu x f P;
Ax,f Ax0 ,p .
Exemplu. Consideram gramatica GE 4.2.9 si forma propozitionala p = T F +
a (E + T ). Arborele de derivare este prezentat n figura 4.6. Se poate observa
ca frazele simple sunt T F, a, E + T .
Observatie. Subcuvantul F respecta prima conditie dar nu este fraza simpla,
ntrucat nu este satisfacuta conditia a doua din definitie.
Definitia 2. Fraza simpla cea mai din stanga poarta denumirea de fraz
a
simpla stang
a.
Vom nota fraza simpla stanga corespunzatoare lui p cu fp n exemplul nostru,
fp = T F . Dupa cum vom vedea n continuare, fraza simpla stanga are un
rol important n algoritmii de analiza sintactica bottom-up. In principiu, acesti
algoritmi prevad urmatorii pasi (descrisi de figura 4.7):
Regulile determinate la pasul (3), aplicate n ordine inversa, ne vor da derivarea
corespunzatoare lui p. Sa mai observam ca n acest mod arborele de derivare se

4.2. ALGORITMI BOTTOM-UP

91

T
F

F
+

Figura 4.6: Arborele de derivare corespunzator derivarii lui p = T F +a(E +T )

(1) Initializare p;
(2) Se determina fp , fraza simpla stanga a lui p;
(3) Se determina regula x fp ;
(4) Se reduce fraza simpla stanga, adica daca p = rfp s, se pune p = rxs;
GOTO(2).
Figura 4.7: Algoritmul bottom-up


CAPITOLUL 4. ANALIZA SINTACTICA

92

construieste de jos n sus (bottom-up). Problema cea mai dificila este desigur
determinarea frazei simple stangi de la pasul (2). In principiu ar trebui cunoscut
anticipat arborele de derivare corespunzator lui p, dar tocmai acesta este scopul
analizei sintactice. Dupa cum vom vedea, aceasta dificultate se poate elimina,
deci putem determina fraza simpla stanga fara a cunoaste acest arbore. De fapt,
fraza simpla stanga este legata de anumite proprietati ale gramaticii pe care le
tratam n continuare.

4.2.2

Relatii de precedent
a

Definitia 3. Fie x, y VG doua simboluri oarecare ale gramaticii.


Vom spune ca:
(1) x y (x precede pe y) daca p astfel ncat p = rxys, x
/ fp , y fp ;
(2) x y (x este egal cu y) daca p astfel ncat p = rxys, x fp , y fp ;
(2) x y (y succede lui x) daca p astfel ncat p = rxys, x fp , y
/ fp ;
Relatiile se numesc relatii de precedent
a simple (atunci cand nu exista
posibilitatea de confuzie se folosesc denumirile mai mic, egal, mai mare pentru
relatiile de precedenta). Sa observam ca aceste relatii nu se exclud reciproc, deci
ca putem avea, de exemplu, x y si n acelasi timp x y, ntrucat pot exista
cazuri de gramatici n care putem gasi doua forme propozitionale p1 , p2 astfel
ncat sa avem simultan cele doua relatii. Sa mai facem de asemenea observatia
ca exista mai multe tipuri de astfel de relatii, cu definitii asemanatoare, ntrucat
relatiile trebuie sa satisfaca conditii suplimentare care depind si de gramatica;
pentru toate aceste tipuri de relatii vom utiliza aceleasi notatii.
Definitia 4. O gramatica de tipul 2 spunem ca este cu precedent
a simpla
daca ntre oricare doua simboluri ale gramaticii exist
a cel mult o relatie de
precedenta.
Pentru algoritmul de analiza sintactica ascendenta este important ca sa nu
existe reguli cu partile drepte identice; altminteri, n cadrul pasului (4) din algoritmul de analiza sintactica nu se poate decide la cine sa se faca reducerea frazei
simple stangi. De asemenea regulile de stergere nu sunt admise, pentru acest
caz notiunea de fraza simpla neavand sens. Aceste conditii presupunem n mod
sistematic ca sunt satisfacute.
Fie acum VG = {x1 , x2 , . . . , xn } alfabetul general, unde am adoptat o anumita
ordine a simbolurilor. Definim matricea de precedenta a gramaticii,

daca xi xj

M = (aij ), unde aij = daca xi xj

daca xi xj
Exemplu. Consideram urmatoarea gramatica

G = ({A, B}, {0, 1}, A, {A A0|1B, B 1}).

4.2. ALGORITMI BOTTOM-UP

93

Matricea de precedenta va fi
A B
A
B
0
1

4.2.3

0 1

Propriet
ati ale gramaticilor cu precedent
a simpl
a

Proprietatea 1. Fie p = a1 . . . an o forma propozitionala ntr-o gramatica cu


precedenta simpla (ai sunt simboluri neterminale sau terminale ale gramaticii).
Atunci fp = ai . . . aj daca si numai daca

a1 a2 . . . ai1 ai ai+1 . . . aj aj+1 ()


Demonstratia acestei proprietati se efectueaza considerand toate structurile
de arbori de derivare posibile ntr-o situatie data. Vom exemplifica aceasta idee
pentru cuvanul p = a1 . . . a7 . Daca presupunem ca fp = a3 a4 a5 , atunci, conform
definitiei frazei simple stangi, avem
a2 a4 , a4 a5 , a5 a6

Mai trebuie aratat ca a1 a2 . In acest scop vom considera toate posibilitatile


de structuri arborescente; o parte din ele sunt prezentate n figura 4.8.
Se poate observa ca n ipoteza ca fp = a3 a4 a5 , singurele situatii posibile sunt
(a) si (b). Celelalte situatii contrazic aceasta ipoteza, de exemplu, n cazurile (c)
si (d) fraza simpla stanga ar fi , respectiv, a1 a2 sau a2 . Acum, n cazul (a), prin
reducerea succesiva a frazei simple stangi, vom obtine un arbore n care fraza
simpla stanga va fi a1 a2 , adica a1 a2 iar n cazul (b), fraza simpla stanga va fi
a2 si atunci a1 a2 .
Implicatia inversa se bazeaza pe cea directa; se presupune ca fp = al . . . ak cu
l 6= i si k 6= j si se considera n continuare toate posibilitatile de pozitionare a
indicilor l, k fata de i, j. De exemplu, daca fp = a2 a3 atunci, conform implicatiei
directe, avem

a1 a2 a3 a4
ceea ce contrazice relatia (*), conform careia a3 a4 iar gramatica are precedenta
simpla.
Observatie La delimitarea frazei simple stangi se procedeaza astfel: parcurgem
sirul de simboluri de la stanga la dreapta pana se gaseste relatia (sau marginea
dreapta a formei propozitionale) pentru determinarea ultimului simbol din fp ,
apoi se parcurge sirul spre stanga, trecand peste relatii , pana la gasirea unei


CAPITOLUL 4. ANALIZA SINTACTICA

94

a1 a2 a3

a4

a5

a6

a7

a1 a2 a3

a4

a4

a6

a7

a6

a7

(b)

(a)

a1 a2 a3

a5

a5

a6

a1 a2 a3

a7

a4

a5
(d)

(c)

Figura 4.8: Arbori de derivare posibili

x0

a1

a2

...

an

Figura 4.9: Arborele de derivare pentru ni = 1


relatii (sau marginea dreapta a formei propozitionale) pentru determinarea
primului simbol din fp .
Proprietatea 2. O gramatica cu precedenta simpla este neambigua.
Schita de demonstratie. Fie p o forma propozitionala si Ax0 ,p arborele de
derivare corespunzator. Vom arata ca acest arbore este unicul arbore de derivare
care are radacina x0 si frontiera p. Procedam prin inductie asupra numarului de
noduri interne ni. Daca ni = 1 atunci arborele de derivare va avea forma din
figura 4.9 si unicitatea acestuia este evidenta. Presupunem acum ca proprietatea
este adevarata pentru un ni oarecare si consideram cazul ni + 1. Sa presupunem
ca ar exista doi arbori diferiti cu radacina x0 si frontiera p; fie acestia A0x0 ,p si
Ax0 ,p .
Deoarece gramatica este cu precedenta simpla, rezulta ca fraza simpla stanga,
care este aceiasi n cei doi arbori, este situata n aceiasi pozitie, p = rfp s.
Efectuam reducerea frazei simple fp (conform regulii aplicate x fp ) si vom

4.2. ALGORITMI BOTTOM-UP

95

obtine arborii A0x0 ,q si Ax0 ,q unde q = rXs iar cei doi arbori trebuie sa fie diferiti.
Dar numarul de noduri interne este ni, n contrazicere cu ipoteza.

4.2.4

Determinarea relatiilor de precedent


a pentru gramatici cu precedent
a simpl
a

Asa cum s-a precizat deja, relatiile de precedenta sunt proprietati intrinseci ale
gramaticii, nu depind de contextul n care se afla cele doua simboluri. Prin urmare, cunoasterea anticipata a acestor relatii mpreuna cu proprietatea 1, rezolva
complet problema pasului 2 de la algoritmul de analiza bottom-up, adica determinarea frazei simple stangi. In acest subparagraf vom prezenta o teorema de
caracterizare pe baza careia se pot determina relatiile de precedenta simple si
implicit faptul daca gramatica este sau nu cu precedenta simpla.
Vom defini doua relatii specifice gramaticilor si care vor fi utilizate n continuare, numite, respectiv, F (First) si L (Last). Fie x VN si y VG doua
simboluri ale gramaticii. Vom spune ca
xF y daca x yu P, u VG
xLy daca x uy P, u VG
Inchiderile tranzitive, respectiv, tranzitive si reflexive ale acestor relatii le vom
nota cu F + , L+ si respectiv, F , L . Exista numerosi algoritmi directi care
permit calcularea acestei nchideri,cu complexitate redusa.
Teorema 2. Avem
(1) x y u . . . xv . . . P, vF + y;
(2) x y u . . . xy . . . P;
(3) x y u . . . vw . . . P, vL+ x, wF y;
Schita de demonstratie. Se analizeaza posibilitatile de arbori de derivare care
raspund cerintelor teoremei. De exemplu, pentru cazul (1), trebuie sa existe
structura de arbore ca n figura 4.10.
Este clar ca daca x y, atunci conform definitei frazei simple stangi, trebuie sa existe p astfel ncat p = rxys, x
/ fp , y fp , adica sa existe structura din 4.10. Invers, daca exista o astfel de structura, atunci fie o forma
propozitionala care contine u. Efectuam reduceri succesive pana cand vom obtine
o forma propozitionala pentru care u apartine frazei simple stangi; la arborele
astfel obtinut, adaugam subarborele de mai sus. Vom avea n mod evident
x
/ fp , y fp .

4.2.5

Studiu de caz

Sa consideram cazul gramaticii pentru generarea expresiilor aritmetice simple


GE , cu regulile obisnuite


CAPITOLUL 4. ANALIZA SINTACTICA

96

u
v
Ramificatii
spre dreapta
... x

...

Figura 4.10: Arborele de derivare corespunzator cazului x y


E

E
T
F
+

(
)
a

F +

) a

Figura 4.11: Matricea de precedenta pentru GE

E E + T |T

T T F |F
F (E)|a

Relatiile First, Last si nchiderile acestora sunt:


E F {E, T } E F + {E, T, F, (, a} E F {E, T, F, (, a}
T F {T, F } T F + {T, F, (, a}
T F {T, F, (, a}
+
F F {(, a} F F {(, a}
F F {F, (, a}
E L {T }
T L {F }
F L {a, )}

E L+ {T, F, a, )}
T L+ {F, a, )}
F L+ {a, )}

E F {E, T, F, a, )}
T F {T, F, a, )}
F F {F, a, )}

Conform teoremei de calcul a relatiilor de precedenta vom obtine matricea de


precedenta (vezi figura 4.11) asociata simbolurilor gramaticii GE .

4.2. ALGORITMI BOTTOM-UP

G:

A A0 | B1
B1

97

S
S
a
b

a b


Figura 4.12: Exemplu de gramatica cu precedenta simpla


Regula

F orma propozitionala
a a a b aababbbabb
S ab
a a S a a b abbbabb
S ab
a a S a S a b bbabb
S ab
a a S a S S b babb
S aSSb a a S S b abb
S aSSb a S a b b
S ab
aSSb
S aSSb S
Figura 4.13: Reconstructia derivarii cuvantului p = aaabaababbbabb
Deci gramatica GE nu are proprietatea de precedenta simpla, astfel ca nu
poate fi aplicat direct algoritmul de analiza sintactica bottom up.
Vom exemplifica algoritmul de analiza pentru gramatica din figura 4.12, matricea de precedenta asociata este cea alaturata.
Reconstituirea derivarii cuvantului p = aaabaababbbabb este prezentata n
tabelul 4.13, unde fiecare linie corespunde formei propozitionale, n care fraza
simpla stanga este subliniata, precedata de regula identificata.

4.2.6

Gramatici operatoriale

Gramaticile operatoriale sunt gramatici cu o structura speciala a regulilor de


rescriere, n care anumite simboluri sunt considerate operatori iar celelalte operanzi, operatorii trebuind sa separe operanzii. Aceasta structura este preluata de
la gramaticile care genereaza expresiile aritmetice iar principiul de analiza este
de asemenea preluat de la algoritmul de evaluare a expresiilor aritmetice. In continuare vom prezenta acest principiu pentru evaluarea expresiilor aritmetice fara
paranteze, cazul expresiilor cu paranteze putandu-se reduce la cel fara paranteze,
de exemplu utilizand tehnica de modificare a ponderilor operatorilor la ntalnirea
parantezelor.
In primul rand se atribuie operatorilor anumite ponderi care vor defini ordinea
de efectuare a operatiilor. De obicei, se considera p(+) = p() = 1 < 2 = p() =


CAPITOLUL 4. ANALIZA SINTACTICA

98

p(/), ceea ce nseamna ca mai ntai se fac adunarile si scaderile, apoi nmultirile
si mpartirile, etc. Efectuarea unei operatii depinde de contextul n care se afla
operatorul respectiv, si anume, daca ponderea operatorului precedent este mai
mare sau egala cu ponderea operatorului curent, atunci se poate efectua operatia
definita de operatorul precedent. Din acest motiv, acest tip de gramatici se
numesc cu operator de precedent
a (operator precedence grammars).
Putem realiza un algoritm simplu de evaluare utilizand doua stive
P- stiva operatorilor;
S- stiva operanzilor.
Vom utiliza indicii i si k pentru a indica nivelele celor doua stive. Prin urmare,
notatia pi , respectiv sk au sensul de operatorul, respectiv operandul din stiva aflat
pe nivelul i, respectiv k. Pentru simplificare, vom utiliza aceiasi notatie pi atat
pentru operator cat si pentru ponderea operatorului respectiv.
Algoritmul de evaluare:
PAS 1: Initializ
ari: Se introduce primul operator si primul operand n stivele P
si S si se initializeaza nivelele celor doua stive, i = k = 2;
PAS 2: Se introduce urmatorul operator n stiva P si se actualizeaza nivelul,
i = i + 1;
PAS 3: Daca pi1 < pi atunci se introduce urmatorul operand n lista S, se
actualizeaza nivelul stivei, k = k + 1, si se revine la pasul 2;
PAS 4: Daca pi1 pi atunci:
n stiva P : pi1 se nlocuieste cu pi ;
n stiva S: sk1 se nlocuieste cu sk1 pi1 sk ;
se actualizeaza nivelele celor doua stive, i = i 1; k = k 1 si se revine la
pasul 3.
Observatie. Pentru uniformitatea algoritmului se introduce operatorul marcaj, notat cu # , cu ponderea cea mai mica; orice expresie se ncadreaza ntre doua
marcaje iar oprirea algoritmului are loc la pasul 4 n cazul n care p1 = p2 = #.
Schematic, acest algoritm este prezentat n figura 4.14.
Exemplu. Tabelul 4.15 contine starea dinamica a celor doua stive pentru
expresia #a + b c/d f #. Mentionam ca n cadrul pasilor 2 si 4 s-a completat
cate un rand nou n tabel.
Observatie. Ponderile operatorilor sunt legate de ierarhia lor n gramatica, cu
cat un operator este mai jos cu atat ponderea lui este mai mare. Acest fapt este
ilustat n figura 4.16.
Pentru cazul expresiilor aritmetice cu paranteze algoritmul se pastreaza, dar
este aplicat dupa preprocesarea expresiei prin modificarea dinamica a ponderilor operatorilor si renuntarea la paranteze. Se parcurge expresia de la stanga la
dreapta alocand ponderi operatorilor; la ntalnirea unei paranteze deschise ponderile se incrementeaza cu 10, iar la ntalnirea unei paranteze nchise se decrementeaza ponderile operatorilor cu 10. In continuare parantezele sunt ignorate.

4.2. ALGORITMI BOTTOM-UP

99

p1

1.

s1

i=2, k=2

pi
2.

p i-1

i=i+1
sk
s k-1

3.

p i-1 < p i

k=k+1

p i-1 p i
4.

p i-1

pi

s k-1

inainte de
prelucrare

sk

dupa
prelucrare

s k-1 p i-1 s k

pi
i=i+1, k=k+1

Figura 4.14: Prelucrarile efectuate asupra celor doua stive

1
2
3
4
5
6
7
8
9
10

1
#0
#0
#0
#0
#0
#0
#0
#0
#0
#0

2
+1
+1
1
1
1
1
1
1
#0

1
2
2 /2
/2
/2 #0
#0

1
a
a
a
a+b
a+b
a+b
a+b
a+b
a+b
a + b c d/f

2
b
b
c
c
c
cd
cd
c d/f

3 4

d
d
f
f

Figura 4.15: Evaluarea expresiei #a + b c d/f #


CAPITOLUL 4. ANALIZA SINTACTICA

100

E +T

E + T
T

T * F

p(+)<p(*)

T * F
p(*)>p(+)

Figura 4.16: Ierarhia operatorilor


De exemplu, expresia
a (b c d) (x + y/(z t)) h
devine prin preprocesare
a 2 b 11 c 12 d 1 x +11 y/12 z 21 t2
ceea ce va asigura ordinea corecta de evaluare.

4.2.7

Gramatici operatoriale

Fie G = (VN , VT , x0 , P) o gramatica de tipul 2. Vom considera ca simbolurile


neterminale VN sunt operanzii limbajului iar simbolurile terminale VT sunt operatorii. Sa observam ca n cazul gramaticii GE care genereaza expresii aritmetice
simple o asemenea conventie este justificata, deoarece oricare din neterminalele
E, T, F deriveaza n terminalul a (generic, acest terminal reprezinta operanzii),
sau ntr-o expresie (eventual ntre paranteze) care are rolul de operand.
Definitia 1. Vom spune ca o gramatica este operatoriala daca regulile de
rescriere au forma
X Ni Ti Ni+1 Ti+1 . . . Tj Nj+1 ,
unde Nk sunt neterminale (operanzi), inclusiv cuvantul vid, iar Tk sunt terminale
(operatori).
Observatie. Intr-o gramatica operatoriala orice forma propozitionala are structura:
p = N1 T1 N2 T2 . . . Tn Nn+1

4.2. ALGORITMI BOTTOM-UP

101

N' i T i N' i+1 T i+1

Ni

N i+1

Tj

N' j+1

N j+1

Figura 4.17: Structura subarborelui


Aceasta nseamna ca ntr-o forma propozitionala a unei gramatici operatoriale
ntre oricare doi operanzi exista cel putin un operator; pot nsa exista mai multi
operatori alaturati, de exemplu, . . . ((a . . ..
Definitia 2. Fie p = N1 T1 N2 T2 . . . Tn Nn+1 o forma propozitionala ntr-o
gramatica operatoriala. Vom spune ca f este o fraz
a simpla a lui p daca f =
Ni Ti Ni+1 Ti+1 . . . Tj Nj+1 este un subcuvant al lui p care contine cel putin un simbol
terminal si n plus:

0
0
(1) x Ni0 Ti Ni+1
Ti+1 . . . Tj Nj+1
P, si Nk0 Nk k = i, . . . , j.
(2) Ax,f Ax0 ,p .
Structura de arbore corespunzatoare unei fraze simple este prezentata n figura
4.17.
Ca si n cazul gramaticilor cu precedenta simpla, fraza simpla cea mai din
stanga poarta denumirea de fraz
a simpla stang
a. Principiul de analiza sintactica
este identic cu cel de la gramatici cu precedenta simpla. Problema principala
este si aici determinarea frazei simple stangi. Aceasta operatie poate fi facuta
utilizand relatiile de precedenta dintre simbolurile gramaticii care pentru gramatici operatoriale au o definitie putin modificata.
Definitia 3. Fie x, y VT . Vom spune ca:

(1) x<y (x precede pe y) daca p astfel ncat p = rxN ys, N VN , x


/ fp , y fp ;

(2) x=y (x este egal cu y) daca p astfel ncat p = rxN ys, N VN , x


/ fp , y
fp ;

(2) x>y (y succede lui x) daca p astfel ncat p = rxys, N VN , x fp , y


/ fp ;
Matricea de precedenta se defineste numai pe multimea simbolurilor terminale, ceea ce conduce la o simplificare a algoritmului de analiza.
Definitia 4. O gramatica operatoriala se spune ca are precedent
a simpla daca
ntre doua simboluri ale gramaticii exista cel mult o relatie de precedenta.
Ca si la celelalte tipuri de gramatici, n vederea efectuarii pasului 3 din algoritmul de analiza, vom presupune ca nu exista reguli cu partile drepte identice.


CAPITOLUL 4. ANALIZA SINTACTICA

102

Ramificatii
spre dreapta

N 1 T 1 N 2 T 2 N' 3 T 3 N' 4 T 4

N3

N' 5 T 5

N5

N4

Ramificatii
spre dreapta

N 1 T 1 N 2 T 2 N' 3

T 3 N' 4 T 4 N' 5 T 5

N3

N4

N5

(b)

(a)

Figura 4.18: Structurile posibile de arbori


De asemenea, sunt valabile proprietatile de caracterizare si de neambiguitate.
Proprietatea 1. Fie p = N1 T1 N2 T2 . . . Tn Nn+1 o forma propozitionala ntr-o
gramatica cu precedenta simpla. Atunci fp = Ni Ti Ni+1 Ti+1 . . . Tj Nj+1 daca si
numai daca

<
<

T1 =T2 . . . =Ti1 <Ti =Ti+1 . . . =Tj >Tj+1 ()

Schita de demonstratie. Presupunem ca p = N1 T1 N2 T2 . . . Tn Nn+1 si ca fraza


simpla stanga este fp = N3 T3 N4 T4 N5 T5 . Atunci din definitia frazei simple stangi,

rezulta T2 <T3 =T4 =T5 >T6 . Mai trebuie sa aratam ca T1 <T2 sau T1 =T2 . In acest
scop analizam structurile posibile de arbori (figura 4.18).

Efectuam reduceri succesive pana cand T2 fp . In acest moment avem T1 <T2

pentru cazul (a) si T1 =T2 pentru cazul (b). Pentru implicatia inversa presupunem
ca fp = Nk Tk Nk+1 Tk+1 . . . Tl Nl+1 , l 6= j, k 6= i si consideram toate cazurile de
pozitionare a indicilor k, l n raport cu i, j. De exemplu, daca l < j atunci, n

conformitate cu implicatia directa, rezulta Tl >Tl+1 iar conform relatiei () din

ipoteza, avem Tl <Tl+1 sau Tl =Tl+1 ceea ce contrazice ipoteza initiala conform
careia gramatica este cu precedenta simpla.
Proprietatea 2. O gramatica operatoriala cu precedenta simpla este neambigua.
Schita de demonstratie. Fie p o forma propozitionala si Ax0 ,p arborele de
derivare corespunzator. Vom arata ca acest arbore este unicul arbore de derivare
care are radacina x0 si frontiera p. Procedam prin inductie asupra numarului de
noduri interne ni. Daca ni = 1 atunci arborele de derivare va avea forma din
figura 4.19 si unicitatea acestuia este evidenta. Presupunem acum ca proprietatea

4.2. ALGORITMI BOTTOM-UP

103

x0

N1 T1

...

Tn

Nn

Figura 4.19: Arborele de derivare pentru ni = 1


este adevarata pentru un ni oarecare si consideram cazul ni + 1. Sa presupunem
ca ar exista doi arbori diferiti cu radacina x0 si frontiera p; fie acestia A0x0 ,p si
Ax0 ,p .
Deoarece gramatica este cu precedenta simpla, rezulta ca fraza simpla stanga,
care este aceiasi n cei doi arbori, este situata n aceiasi pozitie, p = rfp s.
Efectuam reducerea frazei simple fp (conform regulii aplicate x fp ) si vom
obtine arborii A0x0 ,q si Ax0 ,q unde q = rXs iar cei doi arbori trebuie sa fie diferiti.
Dar numarul de noduri interne este cel mult ni, ceea ce contrazice ipoteza inductiva.

4.2.8

Determinarea relatiilor de precedent


a pentru gramatici operatoriale

Vom defini mai ntai relatiile F1,2 si L1,2 ,analoage cu F si L de la gramaticile cu


precedenta simpla.
Definitie Fie x VN si y VG . Vom spune ca
xF1,2 y daca x yu P, sau x N yu P, u VG , N VN
xL1,2 y daca x uy P, sau x uyN P, u VG , N VN
Inchiderile tranzitive, respectiv, tranzitive si reflexive ale acestor relatii le
+

vom nota cu F1,2


, L+
si respectiv, F1,2
, L1,2 . Acum, determinarea relatiilor de
1,2
precedenta operatoriale se poate face cu ajutorul urmatoarei teoreme.
Teorema (determinarea relatiilor de precedent
a). Avem

+
y;
(1) x<y u . . . xv . . . P, vF1,2

(2) x=y u . . . xN y . . . P;

(3) x>y u . . . vy . . . P, vL+


1,2 x;

Schita de demonstratie. Demonstratia se poate face prin analiza structurilor


posibile ale arborilor de derivare Pentru cazul (1), trebuie sa existe structura de
arbore ca n figura 4.20.


CAPITOLUL 4. ANALIZA SINTACTICA

104

v
N' i

Ni

N' j+1

N j+1

Figura 4.20: Structura posibila de arbore


Aceasta teorema ne permite sa determinam matricea de precedenta a gramaticii pe baza careia putem apoi aplica algoritmul de analiza bottom-up. Problema neterminalelor de la capetele frazei simple stangi se poate rezolva analizand
partile drepte ale regulilor de rescriere. Intr-adevar, teorema ne da numai terminalele care intra n fraza simpla stanga si neterminalele interioare; cele doua
eventuale neterminale de la capete vor apartine sau nu frazei simple stangi depinzand de forma partii drepte ale regulii respective. Evident, se pot face si
ipoteze de neambiguitate suplimentare pentru gramatica, similare cu conditia de
a nu exista reguli cu partile drepte identice.

4.2.9

Studiu de caz

Sa consideram cazul gramaticii pentru generarea expresiilor aritmetice simple


GE , cu regulile obisnuite

E E + T |T

T T F |F
F (E)|a

Relatiile F1,2 , L1,2 si nchiderile acestora sunt:


+

{E, T, F, +, , (, a}
{E, T, F, +, , (, a} E F1,2
E F1,2 {E, T, +} E F1,2
+

T F1,2 {T, F, , (, a}
T F1,2 {T, F, } T F1,2 {T, F, , (, a}
+

{F, (, a}
{(, a}
F F1,2
F F1,2 {(, a}
F F1,2

E L1,2 {T, +}
T L1,2 {F, }
F L1,2 {a, )}

E L+
1,2 {T, +, F, , a, )}
T L+
1,2 {F, , a, )}
F L+
1,2 {a, )}

{E, T, +, F, , a, )}
E F1,2

T F1,2 {T, F, , a, )}

{F, a, )}
F F1,2

4.2. ALGORITMI BOTTOM-UP

+ >

>

( <

) >

a >

105

( ) a

< < > <

> < > <

< < = <

>
>

>
>

Figura 4.21: Matricea de precedenta operatoriala pentru GE


Regula

F orma propozitionala

a> + <(a + a) a a

F a
F + <(<a> + a) a a


F a
F + <(<F + <a>) a a

F a
F + <(<F + F >) a a


T T F ,T F
F + <(T =)> a a


F (E) , E T
F + <F <a> a

F a
F + <F F > a

T T F ,T F
F + <T < <a

F a
F + <T F
T T F
F +T
E E T ,E T ,T F E
Figura 4.22: Reconstructia derivarii cuvantului p = a + (a + a) a a
Conform teoremei de calcul a relatiilor de precedenta vom obtine matricea de
precedenta (vezi figura 4.21) asociata simbolurilor gramaticii GE .
Deci gramatica GE are proprietatea de precedenta operatoriala simpla, astfel
ca se poate aplica direct algoritmul de analiza sintactica bottom up.
Reconstituirea derivarii cuvantului p = a + (a + a) a a este prezentata
n tabelul 4.22, unde fiecare linie corespunde formei propozitionale, n care fraza
simpla stanga este subliniata, precedata de regula identificata.

106

CAPITOLUL 4. ANALIZA SINTACTICA

Capitolul 5
Sinteza Programelor
5.1
5.1.1

Forme interne ale programelor


Tabelele compilatorului

Compilatoarele prelucreaza un numar important de informatii, variabile de diverse tipuri, date organizate n anumite structuri standard sau definite de utilizator, etc. De cele mai multe ori aceste informatii sunt stocate n tabele si memorate
pe suporturile de informatii ale sistemului. Organizarea si prelucrarea tabelelor
constituie o problema distincta, cu infuenta importanta asupra performantelor
unui compilator, mai ales daca acestea sunt memorate pe un suport extern. In
cele ce urmeaza vom prezenta pe scurt principalele tabele utilizate n mod obisnuit
n cadrul unui compilator si modul de organizare a informatiilor stocate n aceste
tabele. Mentionam ca structura acestor tabele este definita de proiectantul de
compilator si ca prin urmare exista un anumit grad de subiectivitate n modul de
organizare al acestora.
Tabelul de variabile. Contine variabilele utilizate ntr-un program si informatii asupra lor. Mentionam ca variabilele contin datele prelucrate de
program, n conformitate cu tipul acestora, continut care se modifica n
mod dinamic pe parcursul evolutiei programului. Informatiile din fiecare
linie a tabelului pot fi:
numele variabilei; asa cum s-a precizat la analiza lexicala, numele unei
variabile este de obicei un sir de caractere, litere sau cifre, primul
caracter trebuind sa fi o litera.
tipul variabilei; relativ la tipurile de variabile utilizate n programare
trebuie sa facem mentiunea ca acestea depind n mod esential de domeniul de aplicabilitate al limbajului. De exemplu, pentru un limbaj de
tip matematic (Pascal), tipul unei variabile este caracterizat n general
de trei atribute: structura (scalar, tablou), calitatea (intreg, flotant,
107

108

CAPITOLUL 5. SINTEZA PROGRAMELOR


logic), dimensiunea ( simpla precizie, dubla precizie, etc). In principiu, fiecare variabila poseda toate aceste trei caracteristici, putand
exista si anumite restrictii, de exemplu, variabilele ntregi pot avea
dimensiunea numai simpla precizie sau dubla precizie.
adresa; adresa de nceput a zonei de memorie rezervata variabilei;
Alte informatii: sunt informatii de tip semantic, utilizate la depanarea
programului; de exemplu, daca variabila a fost sau nu initializata
(adica daca nainte de prima utilizare i s-a atribuit valoare), daca a
fost utilizata sau nu, etc.
Pentru uniformitatea prelucrarii tabelului se poate prevedea o anumita
lungime fixa pentru elementele tabelului, chiar daca spatiul nu este folosit
n ntregime. De exemplu, n cazul variabilelor de tip tablou, se pot utiliza doua sau mai multe linii pentru a stoca valorile maxime ale indicilor
(aceste dimensiuni vor fi utilizate atat la rezervarea zonei de memorie cat
si la calculul deplasamentului unui element.
Observatie asupra functiilor. Denumirile functiilor sunt deseori utilizate ca
variabile care contin valoarea pe care functia respectiva o returneaza. Este
natural ca n acest caz numele functiei sa fie considerat variabila si sa fie
stocat n acest tabel mpreuna cu atributele respective; de exemplu, unul
din aceste atribute trebuie sa fie contorul de amplasare, (CA), adica adresa
primei instructii executabile a rutinei corespunzatoare functiei.

Tabelul de etichete. Contine etichetele utilizate ntr-un program si adresele


primelor instructii ale secventelor de program corespunzatoare. In esenta,
etichetele nu difera de variabilele obisnuite, dar exista anumite particularitati; de exemplu, numele unei etichete trebuie sa fie constituit dintr-un
identificator urmat de un delimitator special (doua puncte, etc.) sau numai
din caractere numerice (cazul limbajului BASIC) iar valoarea unei etichete
este ntodeauna o valoare de adresa. De asemenea, n cazul etichetelor trebuie facuta analiza compatibilitatii dintre etichetele definite si etichetele
referite.
Tabelul de variabile temporare. Contine variabile ale compilatorului necesare pastrarii unor rezultate intermediare. Avand n vedere ca rezultatele
intermediare, la fel ca si variabilele definite de utilizator, pot avea tipuri
diferite, se pot constitui zone separate n care se vor memora rezultate de
un anumit tip bine precizat. In acest caz, variabilele temporare pot avea o
structura liniara iar adresa unei astfel de variabile se determina cu o formula
de tipul
adr = adr0 + c i

5.1. FORME INTERNE ALE PROGRAMELOR

109

unde adr0 este adresa de nceput a zonei, c este lungimea elementelor iar i
numarul de ordine al variabilei temporare. Se poate adopta un sistem de
alocare dinamica a variabilelor temporare n scopul economisirii memoriei.
Tabelul de constante. Contine constantele de diverse tipuri utilizate ntr-un
program. In general este un tabel de mai mici dimensiuni, de aceea nu
comporta probleme deosebite de organizare si prelucrare.

5.1.2

Cvadruple si triplete

Cvadruplele si tripletele sunt forme intermediare ale programelor n care fiecare


operatie elementara mpreuna cu operanzii ei se stocheaza ntr-o secventa de
patru sau trei elemente.
Cvadruple
Ne vom referi n continuare numai la operatii binare, pentru celelalte operatii
putandu-se proiecta structuri similare. Consideram deci o secventa de text de
forma A op B, unde A si B sunt operanzi (variabile, constante, variabile temporare, etc.) iar op este un operator binar. Cvadrupul corespunzator acestei
secvente va fi
op, A, B, ti
unde op, A, B sunt codurile unitatilor lexicale respective iar ti este o variabila
temporara. Semnificatia acestui cvadruplu este urmatoarea: se executa operatia
definita de operatorul op ntre operanzii A si B, n aceasta ordine, iar rezultatul
este memorat la ti . In continuare vom folosi aceiasi notatie pentru un operand
si pentru codul operandului, posibilitatea de confuzie fiind redusa, deci nu vom
mai utiliza notatii de forma A, etc.
Exemplu. Cvadruplele corespunzatoare expresiei aritmetice a b + (c + d)/e
sunt
(1)
(2)
(3)
(4)

, a, b, t1
+, c, d, t2
/, t2 , e, t3
+, t1 , t3 , t4

In cazul altor operatii, chiar de n-aritate diferita de doi, se stabilesc structurile


specifice ale cvadruplelor; pentru operatii cu mai mult de doi operanzi, se pot
utiliza doua sau chiar mai multe cvadruple. Un exemplu de cvadruple pentru
structurile uzuale ale limbajelor de programare este prezentat n tabelul 5.1.
Observatie asupra instructiei if. Presupunem ca structura instructiei este
if (expresie logica) then instructiune bloc;

110

CAPITOLUL 5. SINTEZA PROGRAMELOR

Text Sursa
Cvadruple
a+b
+,a,b,t, idem -,*,/
a=b
=,a,b,
goto i
BR, i, ,
if (a==b) then BE, a,b, n
Figura 5.1: Exemplu de codificare prin cvadruple

Expresie logica
rezultatul in t

Expresie

fals

r,a,b, n

adevarat
Instructie
Bloc

Instructie
Bloc
if,_,_,_

(a) Schema logica

(b) Cvadruple

Figura 5.2: Instructiunea If logic

5.1. FORME INTERNE ALE PROGRAMELOR

111

Semantica acestei instructii este prezentata n figura 5.2. Mentionam ca expresie logica va avea forma particulara E1 rE2 , unde r este un operator relational.
In figura (a) prezinta schema logica a instructiei iar (b) cvadruplele corespunzatoare. Partea de cod corespunzatoare expresiei logice va stoca valoarea
(logica ) a expresiei ntr-o variabila temporara t; aceasta valoare va fi utilizata n
instructia de salt, n conformitate cu tipul de salt prevazut n programul sursa (<,
=, etc.). In consecinta, cvadrupul de salt r va trebui sa prevada aceasta variabila
temporara, plus numarul de ordine n al primului cvadruplu care urmeaza dupa
cvadruplele corespunzatoare instructiei sau blocului. De exemplu, acest cvadruplu poate avea urmatoarea forma r, a, b, n unde n este numarul cvadruplului la
care trebuie sa se faca saltul.
Triplete
Este o alta posibilitate de format intermediar, asemanator cu cvadruplele, singura deosebire fiind accea ca nu se prevede explicit o variabila temporara pentru
stocarea rezultatului. Prin urmare, tripletul corespunzator unei operatii binare
de forma A op B va fi op, A, B. In cazul n care ca operand al unui triplet
trebuie specificat rezultatul unui triplet anterior, se va scrie numarul de ordine
al tripletului respectiv.
Exemplu. Pentru secventa de program xx = a b + (c + d)/e sirul de triplete
generat va fi
(1)
(2)
(3)
(4)
(5)

, a, b
+, c, d
/, (2), e
+, (1), (3)
=, xx, (4)

Notatia polonez
a
Notatia poloneza a fost introdusa initial pentru a se putea evalua expresii aritmetice printr-o singura parcurgere secventiala. Din punctul de vedere al proiectarii
compilatoarelor, aceasta notatie poate fi utilizata ca un format intermediar al
programelor, n mod special pentru limbajele de programare algoritmice, Fortran, Pascal. In continuare vom ilustra ideea de evaluare secventiala a expresiilor
aritmetice printr-un exemplu.
Consideram expresia aritmetica ab+(cde)f . Ideea sirului polonez consta
n scrierea operanzilor si a operatorilor acestei expresii (fara a utiliza paranteze)
ntr-un sir cu urmatoarea proprietate: se parcurge sirul secvential de la stanga la
dreapta si fiecare operator ntalnit provoaca efectuarea operatiei respective ntre
cei doi operanzi din fata, n ordinea aparitiei lor. Pentru exemplul considerat, un

112

CAPITOLUL 5. SINTEZA PROGRAMELOR

sir care satisface aceasta conditie este


ab cde f +
Vom numi acest sir notatia poloneza corespunzatoare expresiei, sau notatia
polonez
a inversa. Evaluarea se poate face utilizand o stiva cu urmatoarea prelucrare: se parcurge secvential sirul, operanzii se introduc n stiva fara nici un
control, iar fiecare operator citit provoaca efectuarea operatiei ntre operanzii
aflati n penultimul si ultimul element al stivei, n aceasta ordine si memorarea
rezultatului n penultimul element. Starea dinamica a stivei pentru exemplul
considerat este urmatoarea:
(1)
(2)
(3)
(4)

a a*b
b
c
d
e

a*b a*b
c
c-d*e
d*e
f

a*b
(c-d*e)*f

a*b+(c-d*e)*f

Continutul stivei a fost rescris atunci cand un operator provoaca efectuarea


unei operatii. Se poate observa ca sirul considerat de noi (notatia poloneza a
expresiei) satisface conditia de evaluare secventiala. De fapt, aceasta conditie
este esentiala si ea poate fi luata chiar ca o definitie a sirului polonez.
Fie V un alfabet si B o multime de operatori binari.
Definitia 1. Vom numi sir polonez orice cuvant peste alfabetul V B obtinut
recursiv cu ajutorul regulilor:
(1) daca a V atunci a este sir polonez;
(2) daca p si q sunt siruri poloneze si b B, atunci pqb este sir polonez.
Sa observam ca utilizand aceste doua reguli, putem sa obtinem succesiv toate
sirurile poloneze avand operanzii V si operatorii binari B. De exemplu, daca V =
{a, b, c} si B = {+, }, atunci sirurile poloneze vor fi a, b, c, ab+, ac+, bc+, ab,
. . . , aab + +, aac + +, . . ..
In cele ce urmeaza vom da o alta definitie, tot constructiva, folosind gramaticile generative Chomsky. Este necesar sa precizam expresiile aritmetice pentru
care introducem aceste siruri.
Definitia 2. Fie gramatica Gexp = ({E, T, F }, {a, +, }, E, P) unde regulile
de rescriere sunt

E E + T |T

T T F |F
F a

Observatie. Terminalul a desemneaza operanzii, deci a este de fapt o notatie


simbolica pentru variabile de forma a, b, c, etc. Este usor de vazut ca aceasta gramatica genereaza expresii aritmetice fara paranteze, n care singurele operatii
sunt + si . Utilizarea a trei neterminale E, T, F se face numai pentru a preciza
ponderea operatiilor, cresterea facandu-se odata cu adancimea, deci p(+) < p().

5.1. FORME INTERNE ALE PROGRAMELOR

113

Acelasi limbaj al expresiilor aritmetice fara paranteze poate fi generat cu o gramatica cu un singur neterminal, fie acesta A, si avand regulile
A A + A|A A|a
Dar n acest caz trebuie introduse alte conventii pentru a preciza ordinea operatiilor;
de exemplu, pentru expresia a+bc, n acest ultim caz, nimic nu arata ca operatia
trebuie facuta nainte de +. Trebuie sa precizam ca prin considerarea a numai
doi operanzi nu se impune o constrangere asupra notiunii de expresie aritmetica,
foarte usor putem generaliza aceasta gramatica la un numar oarecare de operatori
binari, de exemplu
A1 A1 op1 A2 |A2
A2 A2 op2 A3 |A3
etc.
De asemenea, putem considera operatori de n-aritate oarecare precum si reguli
de rescriere n concordanta cu sintaxa pe care dorim sa o satisfaca acestia. Utilizarea unor paranteze pentru a indica o anumita ordine de efectuare a operatiilor,
iarasi nu difera esential de cazul expresiilor fara paranteze. Putem folosi algoritmul de modificare dinamica a ponderilor descris la gramatici operatoriale: parcurgem expresia de la stanga la dreapta si atasam fiecarui operator ponderea sa;
n momentul n care ntalnim o paranteza deschisa, marim toate ponderile cu o
constanta mai mare decat cea mai mare pondere iar la ntalnirea unei paranteze
nchise, scadem aceasta constanta. Apoi eliminam toate parantezele. Este evident ca n acest fel operatiile din interiorul parantezelor vor avea prioritatae mai
mare, mergandu-se spre parantezele din interior.
Definitia 3. Fie Gp = (VN , VT , x0 , P), unde VN = {A}, VT = {a, +, },
x0 = A iar regulile sunt
A AA + |AA |a
Orice cuvant p L(Gp ) va fi numit sir polonez. Este natural ca aceste
siruri poloneze sa fie puse n legatura cu expresiile aritmetice fara paranteze
prezentate mai sus. Gramatica Gp nu stabileste o ordine intrinseca de efectuare
a operatiilor, ntocmai ca si gramatica cu un singur neterminal de generare a
expresiilor. Convenim nsa ca aceasta ordine sa fie cea secvential
a.
Daca p L(Gp ) atunci convenim sa notam cu aes(p) cuvantul obtinut din p
cu ajutorul algoritmului de evaluare secventiala.
Urmatoarea teorema stabileste legatura ntre cele doua entitati.
Teorem
a. Pentru orice cuvant e L(Gexp ) exista un pe L(Gp ) astfel ncat
aes(pe ) = e.
Demonstratie. Procedam prin inductie asupra numarului n de operatori din
e. Daca n = 1 atunci e = a + b sau e = a b si sirul polonez care satisface conditia
din teorema va fi pe = ab+ sau pe = ab. Sa presupunem ca proprietatea este

114

CAPITOLUL 5. SINTEZA PROGRAMELOR

E
E
T
E

T
T

e1

e2
(a)

e1
(b)

Figura 5.3: Structurile posibile ale arborelui de derivare


adevarata pentru o expresie care contine un numar de operatori mai mic sau egal
cu n si consideram o expresie e cu n operatori. Arborele de derivare al acesteia
va avea una din formele prezentate n figura 5.3.
In cazul (b) putem considera e2 = a. In ambele cazuri expresiile e1 si e2 au
un numar de operanzi inferior lui n si n conformitate cu ipoteza inductiva avem
aes(pe1 ) = e1 si aes(pe2 ) = e2 . Luam pe = pe1 pe2 + pentru cazul (a) si pe = pe1 pe2
pentru cazul (b). Este evident ca aes(pe ) = e.

5.2

Generarea formatului intermediar

In aceasta sectiune vom analiza problema generarii formatului intermediar pentru


limbaje algoritmice de tip Fortran, Pascal, Basic. Formele intermediare avute n
vedere sunt cvadruplele si notatia poloneza, ntr-un singur caz ne vom referi si
la triplete, avand n vedere ca principial generarea acestora nu difera esential de
cea a cvadruplelor.
Schema generala a algoritmilor este urmatoarea.
Fie G gramatica (de tipul 2) care genereaza limbajul de programare. Prima
faza consta n stabilirea unor elemente semantice n concordanta cu structura
limbajului; astfel, fiecarui simbol x VG i se atribuie un anumit sens semantic, notat S(x), sens care contine o anumita informatie depinzand de simbolul
respectiv, de contextul n care acesta apare, etc. De asemenea, fiecarei reguli
de generare i se ataseaza o anu- mita rutina semantica. Operatiile obisnuite
care se efectueaza n aceste rutine sunt: analize specifice, atribuirea unui sens
semantic simbolului din stanga, generarea unui cvadruplu sau a unei secvente
de sir polonez, etc. Faza a doua este faza de generare propriuzisa si ea comporta n principiu urmatoarele operatii: Se efectueaza analiza sintactica a tex-

5.2. GENERAREA FORMATULUI INTERMEDIAR

115

tului sursa cu un algoritm de analiza pe care proiectantul de compilator a decis


sa l utilizeze. Indiferent de algoritmul ales, analiza poate fi conceputa n doua
etape, mai ntai constructia arborelui de derivare si apoi reducerea lui succesiva
prin eliminarea unor subarbori. In mod natural acesti subarbori sunt cei corespunzatori frazelor simple stangi asa ncat actiunile care se realizeaza cu acest
prilej sunt cele corespunzatoare rutinelor semantice din prima faza. Mentionam
ca frontierele subarborilor care se reduc vor constitui, prin definitie, unitatile sintactice ale limbajului. In momentul n care se ajunge la simbolul de start (s-a
efectuat ntreaga reducere) ntr-un fisier de iesire se obtine programul n format
intermediar, cvadruple, sir polonez, etc. Se poate observa ca analiza sintactica
joaca n acest proces un rol central. In cele ce urmeaza vom presupune ca analiza
sintactica se efectueaza cu un algoritm de tip bottom-up si deci subarborele care
se reduce are drept frontiera fraza simpla stanga.

5.2.1

Generarea cvadruplelor

Gramatica care genereaza expresiile aritmetice GE este cunoscuta; pentru a ne


situa ntr-un context cat mai apropiat de cazul real, vom completa aceasta gramatica cu operatiile - si / (diferenta si mpartire). Prin urmare regulile acestei
gramatici vor fi

E E + T |E T |T

T T F |T /F |F
F (E)|a

Sensul semantic este prestabilit numai pentru simbolul terminal a, si anume,


S(a) este adresa zonei de memorie atasata identificatorului desemnat de a. Pentru
celelalte simboluri neterminale, E, T, F sensul semantic se atribuie pe parcursul
efectuarii analizei. Rutinele semantice corespunzatoare regulilor sunt prezentate
n tabelul 5.4. Mentionam ca actiunile prevazute n aceste rutine sunt stabilite
n conformitate cu ntelesul pe care proiectantul doreste sa l atribuie diverselor
structuri si nu au o ratiune intrinseca. Ca o regula generala nsa, putem sa
facem precizarea ca n cazul cvadruplelor, variabila temporara n care se retine
rezultatul intermediar, va fi transmisa ca sens semantic simbolului din stanga.
Exemplu. Consideram urmatoarea expresie aritmetica (a + b) c d (e f ).
Arborele de derivare corespunzator este prezentat n figura 5.5.
In dreapta fiecarui nod al arborelui (nodurile sunt etichetate cu simboluri ale
gramaticii), se afla nscris sensul semantic corespunzator variabilei si contextului
n care aceasta se afla. Procesul de generare al cvadruplelor se desfasoara astfel:
la nceputul procesului, dupa cum se poate vedea pe arborele de generare, fraza
simpla stanga este a. Se efectueaza reducerea F a si se aplica rutina semantica
corespunzatoare acestei reguli (n tabelul rutinelor pozitia (8) ); singura operatie
care se face este transmiterea sensului semantic lui F . In continuare, acest sens

116

CAPITOLUL 5. SINTEZA PROGRAMELOR

Regula
(1) E1 E2 + T
(2) E1 E2 T
(3) E T
(4) T1 T2 F
(5) T1 T2 /F
(6) T F
(7) F (E)
(8) F a

Cvadruplu
Sens
+, S(E2 ), S(T ), ti S(E1 ) = ti
, S(E2 ), S(T ), ti S(E1 ) = ti
S(E) = S(T )
, S(T2 ), S(F ), ti S(T1 ) = ti
/, S(T2 ), S(F ), ti S(T1 ) = ti
S(T ) = S(F )
S(F ) = S(E)
S(F ) = Adr(a)

Figura 5.4: Rutine semantice asociate regulilor

E,t
T,t

T,t

T,d
T,t

F,t

F,t

E,t

E,e

F,c

F,d

c
(
E,a

E,t

T,e

T,b

T,f
F,f

F,e
T,a

F,b

f
e

F,a
b
a

Figura 5.5: Arborele de derivare

5.2. GENERAREA FORMATULUI INTERMEDIAR

Regula
(1) E1 E2 + T
(2) E1 E2 T
(3) E T
(4) T1 T2 F
(5) T1 T2 /F
(6) T F
(7) F (E)
(8) F a

117

Cvadruplu
Sens
+, S(E2 ), S(T ) S(E1 ) = (n)
, S(E2 ), S(T ) S(E1 ) = (n)
S(E) = S(T )
, S(T2 ), S(F ) S(T1 ) = (n)
/, S(T2 ), S(F ) S(T1 ) = (n)
S(T ) = S(F )
S(F ) = S(E)
S(F ) = Adr(a)

Figura 5.6: Rutine semantice pentru generarea tripletelor


se transmite pana la E, apoi fraza simpla stanga este b si se transmite sensul
semantic pana la T . In acest moment fraza stanga este E + T iar cele doua
simboluri au sensurile S(E) = a, S(T ) = b; se efectueaza reducerea E E + T
si se genereaza cvadruplul +, a, b, t1 iar sensul semantic care se transmite lui E
este t1 . Procesul continua n acelasi mod si se obtine n final sirul de cvadruple:
+, a, b, t1
, t1 , c, t2
, e, f, t3
, d, t3 , t4
, t2 , t4 , t5

5.2.2

Generarea tripletelor

Modificarea ceva mai importanta intervine la rutinele semantice precum si la


faptul ca dupa generarea unui triplet, sensul semantic care se transmite va fi
numarul de ordine al tripletului generat. Aceste rutine sunt prezentate n tabelul
5.6.
Generarea tripletelor se desfasoara la fel cu cea a cvadruplelor. Pentru expresia considerata la generarea cvadruplelor se obtine urmatorul sir de triplete

(1)
(2)
(3)
(4)
(5)

+, a, b
*, (1), c
-, e, f
*, d, (3)
-, (2), (4)

118

CAPITOLUL 5. SINTEZA PROGRAMELOR

(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)

Regula
E E+T
E ET
ET
T T F
T T /F
T F
F (E)
F a

Notatia poloneza
pi = +
pi =
pi =
pi = /
pi = Adr(a)

Figura 5.7: Metoda rutinelor semantice

5.2.3

Generarea sirului polonez

Tehnica rutinelor semantice


Dupa cum s-a precizat, notatia poloneza constituie o interesanta si utila forma
intermediara a programelor. In paragraful precedent aceasta notatie s-a introdus
numai pentru expresii aritmetice fara paranteze, dar aceasta constructie se poate
face pentru majoritatea structurilor sintactice ale limbajelor de programare. Desigur ca cea mai naturala tehnica de generare a notatiei poloneze pentru o expresie
este procedura generala prezentata la nceputul capitolului, bazata pe rutinele semantice atasate regulilor de generare. Spre deosebire de procedura de generare a
cvadruplelor si a tripletelor, pentru sirurile poloneze nu mai avem nevoie de sensul
semantic al neterminalelor; acestea sunt utilizate n momentul aparitiei lor si deci
nu mai este necesara stocarea unor informatii suplimentare. In continuare sunt
prezentate rutinele semantice pentru generarea notatiei poloneze corespunzatoare
expresiilor aritmetice cu paranteze (vezi figura 5.7), generate de gramatica GE .
Notatia pi o utilizam pentru a desemna elementul i din sirul polonez; indicele i
se actualizeaza dupa fiecare prelucrare a sirului.
Exemplu. Vom aplica rutinele semantice de mai sus pentru generarea sirului
polonez corespunzator expresiei aritmetice a b + (c d e) f . Analiza sintactica
se efectueaza cu un algoritm de tip bottom-up, asa ncat trasarea explicita a
arborelui de derivare nu mai este necesara. Prelucrarea efectiva se poate organiza
ntr-un tabel ca n figura 5.8; mentionam ca fraza simpla stanga este indicata prin
sublinierea secventei corespunzatoare de text.
Tehnica parantezelor
Ideea de baza consta n aceea ca se plaseaza ntre doua paranteze fiecare operator
mpreuna cu cei doi operanzi ai sai; apoi generarea notatiei poloneze se poate face
simplu, folosind o stiva de operatori.

5.2. GENERAREA FORMATULUI INTERMEDIAR

Textul sursa
Regula aplicata
a * b + (c - d * e) * f F a
F * b + (c - d * e) * f F b
F * F + (c - d * e) * f T T F, T F
T + (c - d * e) * f
F c
T + (F - d * e) * f
F d
T + (F - F * e) * f
F e
T T F, T F
T + (F - F * F) * f
T + (F - T) * f
E E T, E T, T F
T + (E) * f
F (E)
F f
T+F*f
T+F*F
T T F, T F
T+T
E E + T, E T
E

119

Notatia poloneza
a
ab
ab*
ab*c
ab*cd
ab*cde
ab*cde*
ab*cde*ab*cde*ab*cde*-f
ab*cde*-f*
ab*cde*-f*+
ab*cde*-f*+

Figura 5.8: Generarea sirului polonez: tehnica analizei sintactice


Plasarea parantezelor. Se atribuie fiecarui operator cate o pondere n conformitate cu conventia de prioritati sau cu gramatica care genereaza expresiile
considerate. In cazul unei expresii aritmetice fara paranteze se poate proceda n
urmatorii pasi:
(1) Se ataseaza fiecarui operator ponderea sa.
(2) Se parcurge expresia de la stanga la dreapta pana cand ntre doi operatori se gaseste relatia ; de exemplu . . . a b + c . . . si, cu conventia
uzuala, +. Se plaseaza ntre paranteze operatorul mpreuna cu cei
doi operanzi ai sai, adica . . . (a b) + c . . ..
(3) Se sterge ponderea operatorului curent (cel care a fost inclus ntre paranteze) si se reia procesul de la punctul (2) ncepand cu operatorul urmator
(n exemplul nostru de la +).
De exemplu, expresia a/b c + d e va avea forma ((((a/b)*c)+d)-e).
In cazul unor expresii aritmetice cu paranteze se foloseste un algoritm asemanator
n care se modifica pasul (1) si anume: se parcurge expresia de la stanga la dreapta
atasand fiecarui operator ponderea sa. La ntalnirea unei paranteze deschise se
modifica provizoriu ponderile prin adaugarea unei constante ntregi (aceasta constanta trebuie sa fie mare decat cea mai mica pondere) si se atribuie n continuare noile ponderi. La ntalnirea unei paranteze nchise, aceasta constanta
este scazuta, astfel ncat operatorii din interiorul parantezelor vor avea ponderi
superioare. Apoi toate parantezele se sterg. De exemplu, n expresia
(a + b) (c/(d e) f ),

120

CAPITOLUL 5. SINTEZA PROGRAMELOR

dupa efectuarea acestei operatii, presupunand ca initial ponderile operatorilor


+, , , / sunt, respectiv, 1, 2, 3, 4 si constanta de majorare are valoarea 10, operatorilor li se vor atribui ponderile:
a

+ b
11

* c
3

/ d
14

- e
22

- f
12

Generarea sirului polonez. Pornind de la expresiile aritmetice n care au fost


plasate parantezele n conformitate cu prima parte, sirul polonez poate fi construit
cu ajutorul algoritmului:
Se parcurge expresia de la stanga la dreapta, parantezele deschise sunt
ignorate si se executa operatiile
operanzii se scriu succesiv n sirul polonez;
operatorii se scriu ntr-o stiva.
La citirea unei paranteze nchise, operatorul din varful stivei se scrie n sirul
polonez.
Tehnica stivei de operatori
Este probabil cea mai raspandita metoda de generare a sirului polonez pentru
expresii aritmetice. Se utilizeaza doua liste liniare si o stiva. Prima lista contine
expresia aritmetica data iar n cealalta se obtine succesiv sirul polonez corespunzator. Operatorii sunt plasati n stiva tinandu-se cont de ponderile lor,
apoi sunt extrasi si scrisi n sir conform cu un algoritm care n esenta reproduce actiunea rutinelor semantice. Mecanismul care realizeaza acest proces este
prezentat n figura 5.9.
Algoritmul este urmatorul:
(1) Operanzii se scriu direct n sirul polonez.
(2) Operatorii si parantezele deschise se scriu n stiva respectandu-se urmatoarele
reguli
Parantezele deschise au pondere 0 si se scriu fara conditii;
Pentru ceilalti operatori, se compara ponderea operatorului de introdus
cu ponderea operatorului din varful stivei; daca aceasta este mai mare,
introducerea are loc; daca este mai mica sau egala, se extrage varful stivei
(acesta trece n sirul polonez), se reia comparatia cu operatorul din varful
stivei pana la prima paranteza deschisa sau pana la baza stivei, si apoi se
introduce noul operator;

5.3. GENERAREA FORMATULUI INTERMEDIAR PENTRU INSTRUCT


II CLASICE121

Intrare
(Expresie aritmetica )

Iesire
(Sir polonez )

Varful stivei

Stiva

Figura 5.9: Structura dispozitivului


(3) Citirea unei paranteze nchise provoaca extragerea operatorilor din stiva
pana la prima paranteza deschisa; aceasta este extrasa si ea din stiva (dar paranteza extrasa nu trece n sirul polonez) iar n continuare cele doua paranteze sunt
ignorate.
(4) In finalul procesului, deci dupa ce ultimul operand a fost trecut n sirul
polonez, se extrag toti operatorii din stiva si se scriu n sirul polonez.
Exemplu. Pentru expresia a * b + (c - d * e) * f, stare dinamica a stivei de
operatori este prezentata n figura 5.10.

5.3
5.3.1

Generarea formatului intermediar pentru instructii


clasice
Instructiunea de atribuire

to fill

5.3.2

Instructiunea If

to fill

5.3.3
to fill

Variabile indexate

122

CAPITOLUL 5. SINTEZA PROGRAMELOR

ab*cde*-f*+

a*b+( c-d*e)*f

2 *
4
3
2

*
(

Figura 5.10: Starea dinamica a stivei

Capitolul 6
Masina Turing
6.1

Limbaje de tipul zero

Limbajele de tipul 0 sunt generate de gramatici Chomsky fara restrictii asupra


regulilor de derivare. Se poate arata ca orice gramatica de tipul zero accepta
urmatoarea forma normala
S SA,
B C|i|,
DE F H,
unde A, C, F, H 6= S. Se observa ca singura deosebire fata de gramaticile dependente de context este aceea ca putem avea si reguli.
Demonstratia existentei formei normale se face prin transformari succesive ale
regulilor. In prealabil gramatica se completeaza cu neterminale noi astfel ncat
orice regula u v care nu este de stergere sa respecte conditia de monotonie,
adica |u| |v|. Acest lucru se poate realiza dupa cum urmeaza. Fie
X1 . . . Xn Y1 . . . Ym , n > m,
o regula care nu respecta conditia de monotonie. Vom pune
X1 . . . Xn Y1 . . . Ym Zm+1 . . . Zn , Zm+1 , . . . , Zn .
Este clar ca orice derivare directa uv n gramatica initiala se poate obtine
si n gramatica modificata si reciproc (neterminalele Z nu pot aparea n stanga
altor relatii). In acest fel, gramatica se va transforma astfel ncat sa contina doua
categorii de reguli: reguli care respecta conditia de monotonie si reguli.
In continuare reducem lungimea partii drepte a regulilor folosind urmatoarea
transformare. Fie u v P, |v| > 2; atunci v = Y1 Y2 Y3 v 0 .
1. daca u = X1 atunci regula se nlocuieste cu
X 1 Z1 Z2 ,
Z1 Y1 ,
Z2 Y2 Y3 v 0 .
123

124

CAPITOLUL 6. MASINA TURING

2. daca u = X1 X2 u0 atunci regula se nlocuieste cu


X1 X2 Z1 Z2 ,
Z1 Y1 ,
Z 2 u0 Y 2 Y 3 v 0 .
In ambele cazuri Z1 , Z2 sunt neterminale noi.
Este clar ca noile lungimea partii drepte a regulilor se reduce cu o unitate
pentru cazul n care exista minim 3 simbolurin dreapta. repetand procedura se
poate obtine o gramatica echivalenta n care regulile au una din formele:
1. B C|i|,
2. DE F H,
3. X Y Z.
Regulile (1) si (2) satisfac conditiile de la forma normala, iar cele de forma (3)
presupunem ca nu satisfac aceste conditii, deci ca X 6= S sau Y 6= S. In general,
putem avea mai multe astfel de reguli; pentru simplificare presupunem ca exista
doua reguli de forma (3):
(30 ); X1 Y1 Z1 , X2 Y2 Z2 .
Construim o gramatica echivalenta G0 = (VN {S 0 , X1 , X2 }, VT , S 0 , P 0 ), unde P 0
contine toate regulile care convin (de formele (1) si (2)) precum si
S 0 S,
S 0 S 0 X1 |S 0 X2 ,
X1 X1 Y1 Z1 , X2 X2 Y2 Z2 .
De asemenea vom include n P 0 urmatoarel reguli de comutare (relativ la simbolurile nou introduse X1 , X2 ):
AX1 X1 A,
, A VN .
AX2 X2 A,
Se vede ca G0 este o gramatica n forma normala. Este trivial sa aratam ca
L(G) = L(G0 ).

Fie p L(G), deci S p. Presupunem ca n aceasta derivare exista o


G

singura secventa uv n care se aplica reguli de forma (30 ), adica

G : S uv p.

6.1. LIMBAJE DE TIPUL ZERO

125

Presupunem ca secventa uv are forma

u = u1 X1 u2 X2 u3 X2 u4 u1 Y1 Z1 u2 Y2 Z2 u2 Y2 Z3 u4 = v,
unde u1 , u2 , u3 , u4 VN . In G0 putem scrie
S 0 S 0 X2 S 0 X2 X2 S 0 X1 X2 X2 S X1 X2 X2

uX1 X2 X2 = u1 X1 u2 X2 u3 X2 u4 X1 X2 X2 u1 X1 X1 u2 X2 X2 u3 X2 X2 u4

u1 Y1 Z1 u2 Y2 Z2 u3 Y2 Z2 u4 = v p

Prin urmare, S 0 p si p L(G0 ).


G0

G0

G0

Invers, fie p L(G0 ), deci S 0 p. Daca n derivarea S 0 p apar simbolurile X1 , X2 ele nu pot aparea dacat n urma aplicarii regulilor S 0 S 0 X1
si S 0 S 0 X2 , deci la nceputul derivarii, apoi singura posibilitate de continuare
este S 0 S; de asemenea, aceste simboluri nu pot fi eliminate decat cu regulile
X1 X1 Y1 Z1 si X2 X2 Y2 Z2 , etc. Astfel derivarea noastra trebuie sa aiba

forma descrisa mai sus, de unde rezulta S p, p L(G).2


G

Relativ la puterea generativa a gramaticilor de tipul zero se poate arata ca


L1 L0 (strict). Demonstratia se face pe o cale indirecta.
Mentionam si urmatoarea teorema a spatiului de lucru. Fie G o gramatica
de tipul zero. Pentru o derivare
D : S = u0 u1 . . . un = p VT
definim
W SD (p) = max|ui |
i = 1, . . . , n
si
W S(p) = min{W SD (p)}.
D
Observatie. W S este prescurtare de la working space.
Spunem ca o gramatica de tipul zero G are spatiul de lucru marginit daca
exista k N astfel ncat pentru p L(G) sa avem W S(p) k|p|. Sa observam
ca orice gramatica care nu are reguli de stergere (exceptie S si atunci S nu
apare n dreapta) satisface aceasta conditie cu k = 1.
a G are spatiul de
Teorema 6.1 (teorema spatiului de lucru) daca o gramatic
lucru marginit, atunci L(G) L1 .

126

CAPITOLUL 6. MASINA TURING

p=i 1i 2i 3i 4i 5, n=4
i1

i2

i3

i4

i5

Banda de intrare /iesire

Dispozitiv de citire /scriere

s S

Dispozitiv de comanda

Figura 6.1: Reprezentarea schematica a masinii Turing

6.2

Masina Turing

Conceptul de masin
a Turing. Masina Turing este un mecanism de recunoastere
a limbajelor de tipul zero. In felul acesta, familiilor de limbaje din clasificarea
Chomsky le corespund automate specifice de recunoastere.
Familia L3 - automate finite,
Familia L2 - automate pushdown,
Familia L1 - automate liniar marginite,
Familia L0 - masina Turing.
O masina Turing (prescurtat MT) se compune dintrun dispozitiv de comanda
care poseda un dispozitiv de scrierecitire si o banda de intrare. Banda de intrare
se considera marginita la stanga si nemarginita la dreapta; ea contine simboluri
ale unui alfabet de intrare, ncepand din prima pozitie. Alfabetul are un simbol special numit blanc si notat [ (sau spatiu), care se considera nregistrat n
toata partea neocupata a benzii. Indicele simbolului din dreptul dispozitivului de
scrierecitire l notam cu n si el va constitui un element al starii masinii Turing.
Dispozitivul de comanda se afla ntr-o anumita stare interna, element al unei
multimi finite de stari.
Schema unei masini Turing este data n figura 6.1. O masina Turing functioneaza
n pasi discreti. Un pas de functionare consta din:
Dispozitivul de comanda citeste simbolul aflat n dreptul dispozitivului de
scrierecitire; n functie de simbolul citit, masina Turing trece ntr-o noua stare
interna, scrie pe banda un nou simbol (ntotdeauna diferit de blanc) n locul
simbolului citit si muta banda cu o pozitie (spre stanga sau dreapta) sau o lasa

6.2. MASINA TURING

127

pe loc. Conventional, vom nota cu +1 o miscare spre stanga, cu 1 spre dreapta


si cu 0 pe loc.
Din punct de vedere matematic, o masina Turing este un sistem
M T = (, I, f, s0 , f )
unde:
este multimea de stari;
I este alfabetul de intrare;
f : ( I)0 (I {[}) {1, 0, 1}, ( I)0 I,
este functia de evolutie;
s0 este simbolul de start;
f este multimea de stari finale.
Observatie. Functia f nu este definita pe ntregul produs I; daca masina
ajunge ntr-o stare s iar n dreptul dispozitivului de scrierecitire se afla simbolul i
si (s, i) 6 (I)0 spunem ca masina se blocheaza. Exista si alte cazuri de blocare,
de exemplu situatia n care dispozitivul de scrierecitire se afla n dreptul primului
simbol, iar pasul de functionare prevede o miscare a benzii spre dreapta.
O stare (sau configuratie) a unei masini Turing este un triplet de forma =
(s, p, n) unde s este starea interna, p este cuvantul scris pe banda iar n este
indicele simbolului din dreptul dispozitivului de scrierecitire.
Vom spune ca starea 1 = (s1 , p1 , n1 ) evolueaz
a direct n starea 2 = (s2 , p1 , n2 )
si vom scrie 1 72 daca se efectueaza un pas de evolutie. In termenii functiei
de evolutie, avem
(1)f (s1 , in1 ) = (s2 , i, +1), p2 = i1 . . . in1 1 iin1 +1 . . . im , n2 = n1 + 1;
(2)f (s1 , in1 ) = (s2 , i, 1), p2 = i1 . . . in1 1 iin1 +1 . . . im , n2 = n1 1;
(3)f (s1 , in1 ) = (s2 , i, 0), p2 = i1 . . . in1 1 iin1 +1 . . . im , n2 = n1 ;
(4)f (s1 , [) = (s2 , i, +1), p2 = p1 i, n2 = n1 + 1;
(5)f (s1 , [) = (s2 , i, 1), p2 = p1 i, n2 = n1 1;
(6)f (s1 , [) = (s2 , i, 0), p2 = p1 i, n2 = n1 ;

Vom spune ca 0 evolueaz


a (fara specificatia direct) n 00 si vom nota 0 7 00
daca 0 = 00 sau daca exista 1 , . . . , n astfel ncat
0 = 1 72 7 . . . 7n = 00 .
Limbajul recunoscut de o masina Turing este prin definitie

L(M T ) = {p|p I , (s0 , p, 1)7(s, q, ), s f }.


Observatie. Este posibil ca masina sa ajunga ntr-o stare finala nainte de
citirea integrala a lui p; analiza starii finale trebuie facuta numai dupa parcurgerea
cuvantului.
Exemplu. Consideram masina turing M T = (, I, f, s0 , f ) unde = {s0 , s1 , s2 },
I = {0, 1}, f = {s1 } iar functia de evolutie este data de

128

CAPITOLUL 6. MASINA TURING


f
[
0
1

s0
s1
(s2 , 1, 1)
(s1 , 0, 1)
(s0 , 1, 1) (s0 , 0, 1)

s2
(s0 , 0, 1)

Evolutia masinii pentru p = 001 este


(s0 , 011, 1)7(s1 , 011, 2)7(s0 , 001, 3)7(s0 , 001, 4)7
(s2 , 0011, 5)7(s0 , 0011, 4)7(s0 , 00110, 5)7(s1 , 00110, 6)
Se poate observa ca dupa citirea ntregului cuvant masina poate sa efectueze
un numar de pasi suplimentari pana la ajungerea ntr-o stare finala, deci este
posibil ca |p| < |q|.
Situatii n care o masina Turing se blocheaza (n aceste situatii cuvantul scris
pe banda nu este recunoscut):
1. MT ajunge ntr-o stare s, n dreptul dispozitivului de citirescriere se afla
simbolul i si (s, i) 6 ( I)0 ;
2. MT este n starea s, a citit simbolul din prima pozitie i si f (s, i) = (s0 , i0 , 1);
3. MT efectueaza un ciclu infinit n interiorul cuvantului.
Definitie 6.1 Vom spune ca o masin
a Turing este nestationar
a daca
f : ( I)0 (I \ {[}) {1, +1}.
Prin urmare, o masina Turing nestationara nu lasa n nici o situatie banda pe
loc.
a Turing este echivalent
a cu o masin
a Turing nestatioLema 6.1 Orice masin
nara.
Demonstratie. Pornind de la o M T data construim o M T 0 nestationara astfel:
Daca f (s, i) = (s0 , i0 , 1) vom pune f 0 (s, i) = f (s, i);
Daca f (s, i) = (s0 , i0 , 0) vom pune f 0 (s, i) = (s00 , i0 , 1) si f 0 (s00 , j) = (s0 , j, +1), j
I, unde s00 este o stare nou introdusa.
Astfel, n cazul unei ramaneri pe loc a lui MT, noua masina va face un pas
spre stanga si unul spre dreapta, fara sa modifice nici starea si nici continutul
benzii. Evident, cele doua masini sunt echivalente.
Limbajele recunoscute de masini Turing.
a Turing daca si numai daca
Teorema 6.2 Un limbaj este recunoscut de o masin
este de tipul zero.

6.2. MASINA TURING

129

Demonstratie. Partea I. E = L(M T ) E L0 .


Fie M T = (, I, f, s0 , f ) o masina Turing astfel ncat E = L(M T ). Putem
presupune ca M T este nestationara. Fie I = (I \ {[}) {}.
Construim o gramatica de tipul zero astfel: G = (VN , VT , S, P ) unde
VN = {(i, j)|i I , j I} {S, X1 , X2 }; VT = I \ {[}.
Definitia lui P :
S s0 X1 , X1 (i, i)X1 , i I \ {[},
X1 X2 , X2 (, [)X2 , X2 ,
daca f (s, i) = (s0 , i0 , 1) atunci s(i1 , i) (i1 , i0 )s0 , i1 I ,
daca f (s, i) = (s0 , i0 , 1) atunci (i1 , i2 )s(i3 , i) s0 (i1 , i2 )(i3 , i0 ), i1 , i3 I , i2
I,
daca s f , atunci s(i1 , i2 ) si1 s si (i1 , i2 )s si1 s.
Fie p L(M T ), p = i1 . . . in . Presupunem ca M T utilizeaza n recunoastere
m pozitii de pe banda situate la dreapta cuvantului p. In G avem

Ss0 X1 s0 (i1 , i1 ) . . . (in , in )X2 s0 (i1 , i1 ) . . . (in , in )(, [)m .


Cuvantul p fiind recunoscut de M T avem

(1) (s0 , i1 . . . in , 1)7(sf , i01 . . . i0h , k), h n.


Vom arata ca (1) implica existenta unei derivari de forma

2)s0 (i1 , i1 ) . . . (in , in )(, [)m (i1 , i01 ) . . . (ik1 , i0k1 )sf (ik , i0k ) . . . (in+m , i0n+m ),
unde

i1 , . . . , in I \ {[}, in+1 , . . . , in+m = ,


i01 , . . . , i0h I \ {[}, i0h+1 , . . . , i0n+m = .

Demonstratie prin inductie asupra lungimii l a evolutiei.


Pentru l = 0 avem

(s0 , i1 . . . in , 1)7(s0 , i1 . . . in , 1), k = 1, h = n, i0j = ij .


Partea dreapta a lui 2) va avea forma s0 (i1 , i1 ) . . . (in , in )(, [)m si deci 2) este
adevarata.
Presupunem ca implicatia este adevarata pentru l oarecare si consideram o
evolutie de lungime l + 1. Punem n evidenta ultima evolutie directa

(s0 , i1 . . . in , 1)7(s, i001 . . . i00g , j)7(sf , i01 . . . i0h , k).


In general h = g sau h = g + 1 n conformitate cu urmatoarele doua cazuri
(figura 6.2).

130

CAPITOLUL 6. MASINA TURING

i"1

i"3

i"2

...

i"g

i"1

i"3

i"2

...

i"g
s

h=g

h= g+1

Figura 6.2: Configuratii posibile ale masinii Turing


Intotdeauna k = j 1. apoi i00 = i0 , t = 1, . . . , g, t 6= j, adica
t
t
i001 , i002 , . . . , i00j1 , i00j , i00j+1 , . . . , i00g ;
i01 , i02 , . . . , i0j1 , i0j , i0j+1 , . . . , i0g .
In urma ultimei evolutii directe vor diferi numai simbolurile i00j , i0j .
Din ipoteza inductiva rezulta

s0 (i1 , i1 ) . . . (in , in )(, [)m (i1 , i001 ) . . . (ij1 , i00j1 )s(ij , i00j ) . . . (in+m , i00n+m ).
In conformitate cu definitia evolutiei directe avem
f (s, i00j ) = (sf , i0j , 1), k = j + 1, s(ij , i00j ) (ij , i00j )sf ;
f (s, i00j ) = (sf , i0j , 1), k = j 1, (ij1 , i00j1 )s(ij , i00j ) sf (ij , i00j1 )(ij , i0j ).
In ambele cazuri

s0 (i1 , i1 ) . . . (in , in )(, [)m (i1 , i01 ) . . . (ik1 , i0k1 )sf (ik , i0k ) . . . (in+m , i0n+m ).
Acum, deoarece sf f , putem scrie

S s0 (i1 , i1 ) . . . (in , in )(, [)m

(i1 , i01 ) . . . (ik1 , i0k1 )sf (ik , i0k ) . . . (im+n , i0m+n )


0
)
(i1 , i01 ) . . . (ik1 , i0k1 )sf ik sf (ik+1 , i0k+1 ) . . . (im+n , im+n
0
0
0
(i1 , i1 ) . . . (ik2 , ik2 )sf ik1 sf ik sf ik+1 sf (ik+2 , ik+2 ) . . . (im+n , i0m+n )

sf i1 sf i2 sf . . . sf in sf i1 . . . in = p.
Prin urmare p L(G) si L(M T ) L(G). Analog se arata si incluziunea inversa
si deci L(M T ) = L(G).2

Bibliografie

1. Octavian C. Dogaru, Bazele informaticii. Limbaje formale, Tipografia Universitatii din Timisoara, 1989.

6.2. MASINA TURING

131

2. Gheorghe Grigoras, Limbaje formale si tehnici de compilare, Tipografia


Universitatii Alexandru Ioan Cuza, Iasi, 1984.
3. J. E. Hopcroft si J. D. Ullman, Introduction to Automata Theory, Languages
and Computation, Reading Mass., 1979.
4. Solomon Marcus, Gramatici si automate finite, Editura Academiei, Bucuresti, 1964.
5. Stefan Maruster, Curs de Limbaje formale si tehnici de compilare, Tipografia Universitatii din Timisoara, 1980.
6. Gheorghe Orman, Limbaje formale, Editura tehnica, Bucuresti, 1982.
7. Gheorghe Paun, Probleme actuale n teoria Limbajelor formale, Editura
Stiintifica si Enciclopedica, Bucuresti, 1984.
8. Teodor Rus, Mecanisme formale pentru specificarea limbajelor, Editura Academiei,
Bucuresti, 1983.
9. Arto Salomma, Formal languages, Academic Press, New York, 1973.
10. Dan Simovici, Limbaje formale si tehnici de compilare, Editura didactica si
pedagogica, Bucuresti, 1978.
11. Luca Dan Serbanati, Limbaje de programare si compilatoare, Editura Academiei,
Bucuresti, 1987.

S-ar putea să vă placă și