Sunteți pe pagina 1din 10

Cursul nr.

6
6 noiembrie 2008

Capitolul III

Generarea limbajelor. Gramatici

1. Gramatici

După cum vom vedea în capitolul următor, maşinile au fost concepute iniţial ca
instrumente de recunoaştere şi acceptare a limbajelor. Gramaticile, în schimb, sunt
instrumente de generare a cuvintelor care aparţin unui limbaj. Motivaţia conceptului de
gramatică provine din lingvistică. Pentru învăţarea unui limbaj, trebuie să învăţăm, în
primul rând, două lucruri: vocabularul limbajului şi regulile de aşezare a cuvintelor din
vocabular.
Pe această idee s-a mers şi în cazul conceperii unui limbaj de programare.

1.1.Exemplu. În cele ce urmează vom încerca să arătăm ce ar însemna o gramatică


pentru “limbajul programelor “while“” (un fragment de limbaj de tip PASCAL).
Să considerăm următoarele date:
- simbol de start <program>
- mulţime de neterminali: <program>, <şir de afirmaţii>, <afirmaţie>,
<asignare>, <test>, <variabilă>, <cifră>, <alpha>
- mulţime de terminali: “begin“, “end“, “pred“, “succ“, “while“, “do“, :=, ≠, ;,
(, ), 0,1,…,9, A, B,….,Z.
- Mulţime de reguli de generare (sau producţii):
(1) <program> → begin end | begin < şir de afirmaţii> end.
(2) <şir de afirmaţii> → <afirmaţie> | < şir de afirmaţii> <afirmaţie>
(3) <afirmaţie> → < asignare> | while <test> do <afirmaţie> | <program>
(4) <test> → <variabilă> ≠ <variabilă>
(5) <asignare> → <variabila> := 0 |<variabila> := succ(<variabila>) |
<variabilă> := pred(<variabilă>)
(6) <variabilă> → <alpha> | <variabilă> <alpha> |<variabila> <cifră>
(7) <cifră> → 0 |1 |2 |…|9
(8) <alpha> → A | B| ….| Z.

Să vedem ce înseamnă cuvânt generat. Pornind de la simbolul de start, prin


aplicarea succesivă a regulilor de generare şi concatenare trebuie să ajungem la un cuvânt
format numai din terminali.
Pentru a uşura scrierea, vom utiliza următoarele prescurtări:
afirmaţie = af., şir de afirmaţii = sir af., variabilă = var.
Vom folosi simbolul “⇒” pentru a arăta generarea unui cuvânt şi vom pune ca
exponent, între paranteze, regula aplicată. Avem succesiv:
<program> ⇒(1) begin <sir af.> end ⇒(2) begin <af> end ⇒(3)
begin while<test>do<af> end ⇒(4) begin while <var> ≠ <var>do<af>end ⇒(6)
begin while<alpha>≠<alpha>do<af>end ⇒(8) begin while A≠<alpha>do<af>end ⇒(8)
begin while A≠B do <af> end ⇒(3) begin while A≠B do <program> end ⇒(1)
begin while A≠B do begin <sir af.> end end ⇒(2) begin while A≠B do begin <af>end end
⇒(3) begin while A≠B do begin <asignare>end end ⇒(5)
begin while A≠B do begin <var> := succ(<var>) end end ⇒(6)
begin while A≠B do begin <alpha> := succ(<var>) end end ⇒(6)
begin while A≠B do begin <alpha> := succ(<alpha>) end end ⇒(8)
begin while A≠B do begin A := succ(<alpha>) end end ⇒(8)
begin while A≠B do begin A:= succ(A) end end,
care este un cuvânt format numai din terminali
Este momentul să definim, din punct de vedere formal, noţiunea :
1.1 Definiţie. Se numeşte gramatică un 4-uplu G = ( N , Σ , s 0 , P) unde:

(i) N este mulţimea finită, nevidă, elementele sale numindu-se simboluri


neterminale (sau, simplu, neterminali);
(ii) Σ este o mulţime finită, nevidă, disjunctă de N ( N ∩ Σ = ∅), elementele
sale numindu-se simboluri terminale (sau terminali);
(iii) s0 ∈ N este un simbol distins din N, numit simbol iniţial sau simbol de
start;
(iv) P este o mulţime finită de producţii sau reguli de generare,
P ⊆ ( N + Σ ) * N ( N + Σ ) * ×( N + Σ ) * .
Se numeşte regulă în gramatica G orice pereche (u,v) din P. Regula (u,v) va fi
notată prin u → v .

1.1 Observaţii.
i) În orice regulă u → v , u conţine cel putin un simbol neterminal
ii) Atragem atenţia încă o dată că ( N + Σ) înseamnă ( N ∪ Σ) în teoria
mulţimilor.

1.2 Definiţie. Se numeşte relaţie de derivare directă peste ( N + Σ)* relaţia notată
cu “⇒G” definită prin:
w⇒G w' dacă (∃) u → v ∈ P astfel încât w = xuy şi w' = xvy.
Cu alte cuvinte, w şi w' sunt în relaţie de derivare directă dacă w' se obţine din w
prin înlocuirea membrului stâng al unei reguli cu membrul drept al regulii. Pentru
a putea pune în evidenţă limbajul generat de gramatica G (care este limbaj peste
alfabetul terminalilor, Σ ) mai avem nevoie şi de:

1.3 Definiţie. Se numeşte relaţie de derivare în gramatica G, notată “ ⇒G* ”,


închiderea reflexivă şi tranzitivă a relaţiei de derivare directă ” ⇒G ”.
În cazul în care nu există pericol de confuzie, se poate omite G de la “⇒G” şi
“⇒G* ”.

1.2 Observaţii :
1) Din definiţie este clar că w⇒G* w' dacă şi numai dacă w = w' sau există şirul
de cuvinte din ( N + Σ ) * , w1 = w, w2,…, wn = w' (n ≥ 2) astfel încât

wi ⇒ G wi +1 , (∀)i ∈ 1, n − 1.

2) Dacă w ⇒ G w' sau w = w', şirul de cuvinte de mai sus este numit derivare în

gramatica G. Rezultă că, într-o derivare, cu excepţia primului termen, fiecare


cuvânt din şir se obţine din precedentul prin aplicarea unei reguli din G.
Numărul de reguli care se aplică pentru a obţine ultimul cuvânt dintr-o
derivare se numeşte lungimea derivării (în cazul prezentat la 1) avem deci o
derivare de lungime (n-1)).
3) Prin convenţie, w ⇒*w printr-o derivare de lungime 0. Notăm lungimea unei
derivări prin l(w ⇒*w').

1.4 Definiţie. Limbajul generat de gramatica G = ( N , Σ , s 0 , P) este limbajul

L(G ) = {w ∈ Σ * | (∃) s 0 ⇒ *w}


Un limbaj L se numeste numărabil recursiv dacă există o gramatică G
astfel încât L = L(G).

Să exemplificăm :
1.2 Exemplu.
Fie G = ({s0}, {a,b}, P, s0) unde P = {s0 → as0b, s0 → ε}. Puteam să fi
scris, de exemplu, P : s0 → as0b | ε, “|” însemnând “sau”.
Să demonstrăm că L(G) = L', unde L' = {anbn| n∈N}.
Vom demonstra aceasta in doua etape:
I. Fie M = {w∈(N + Σ )*| (∃)s0 ⇒* w}şi M '={w∈(N +Σ)* | (∃)n∈N : w = ans0bn

sau w= anbn }.
Pentru a demonstra că M = M ' vom arăta dubla incluziune, adică M ⊆ M ' şi
M ⊇ M'.
“⊇”: Fie w ∈ M '. Avem două cazuri:
1) w = a n s0 b n , n ≥ 0.
Dacă n = 0, atunci w = s0 pentru care avem derivarea de lungime 0
s 0 ⇒ * s 0 deci w ∈ M .

Dacă n ≥1, avem derivarea s0 ⇒ as0 b ⇒ a 2 s0 b 2 ⇒ ... ⇒ a n s0 b n , aplicând

regula s 0 → as 0 b de n ori. Deci s 0 ⇒ * a n s 0 b n , de unde w∈ M .

2) w = a n b n , n ≥ 0.
Dacă n = 0, w = ε şi avem derivarea s0 ⇒ *ε prin aplicarea regulii

s0 → ε . Aşadar w∈ M .

Dacă n ≥ 1, avem derivarea s 0 ⇒ as 0 b ⇒ a 2 s 0 b 2 ⇒ ... ⇒ a n s 0 b n ⇒ a n b n

aplicând de n ori regula s 0 → as 0 b şi odată regula s0 → ε . Deci s0 ⇒ *w , de

unde w∈ M .
“⊆”: Vom demonstra că M ⊆ M ' prin inducţie.
Fie P(n) propoziţia care afirmă: “(∀)n ∈N şi (∀) s0⇒* w cu l(s0⇒* w) = n
atunci w ∈ M '”.
P(0): w = s0 = a0s0b0, deci P(0) este adevărată.
Presupunem că P(k) este adevărată şi fie s 0 ⇒ * w cu l ( s 0 ⇒ * w) = k + 1. Vom

pune în evidenţă ultimul pas al derivării şi anume: s 0 ⇒ *w' ⇒ w. Deoarece

l ( s 0 ⇒ *w' ) =k, conform ipotezei inductive, w'∈ M '. Deoarece w' ⇒ w este
derivare de lungime 1, trebuie să putem aplica o singură regulă din P; aşadar w'
trebuie să conţină şi simboluri neterminale. Rezultă că w'= aks0bk, de unde w=
ak+1s0bk+1 (prin aplicarea primei reguli) sau w = akbk (prin aplicarea regulii
“ s0 → ε . ”). În ambele cazuri w ∈ M ' deci P(k+1) adevărată.
Conform principiului inducţiei matematice vom avea atunci că P(n) este adevărată
pentru orice n∈N, deci M ⊆ M ' .
II Conform etapei I, singurele cuvinte din Σ * care se pot obţine printr-o
derivare din s0 sunt de forma anbn, n ≥ 0, deci L(G) ⊆ L'. Pe de altă parte, orice
cuvânt de forma a n b n , n ≥ 0, se poate obţine printr-o derivare din s0, şi
obţinem şi cealaltă incluziune L' ⊆ L(G). Aşadar L' = L(G).

1.5 Definiţie. Două gramatici, G1 = ( N 1, Σ 1 , s 0 , P1 ) şi G2 = ( N 2 , Σ 2 , s 0 , P2 ) se


1 2

numesc echivalente dacă ele generează acelaşi limbaj (adică L(G1) = L(G2)).
De multe ori suntem interesati de legăturile existente între limbajele
generate de două gramatici distincte. Întrucât, pentru comparatie, limbajele
generate ar trebui să fie formate din cuvinte peste un acelaşi alfabet, nu
restrângem cu nimic generalitatea dacă presupunem că gramaticile au acelaşi
alfabet al terminalilor.
Mai mult, se poate presupune că alfabetele neterminalilor sunt disjuncte.
Pentru aceasta, să demonstrăm următoarea :

1.1 Propoziţie. Fie G = ( N , Σ , s 0 , P ) o gramatică. Există o gramatică

G ' = ( N ' , Σ , s 0 ' , P ' ) astfel încât N ∩N ' = ∅ şi L(G) = L(G').

Demonstraţie. Fie N ' o mulţime cardinal echivalentă cu N (putem considera aşa


ceva ori de căte ori avem nevoie, punând de exemplu, oricărui element x ∈ N o
bară deasupra) şi fie f : N → N ' bijecţia corespunzătoare. Ea se poate extinde la
o bijecţie de la N + Σ la N '+Σ pe care o notăm tot cu f, astfel
⎧ f ( x) daca x ∈ N
f ( x) = ⎨ .
⎩x daca x ∈ Σ
Conform proprietăţii de universalitate a monoizilor liberi, există şi este unic un
izomorfism, notat tot cu f, f : ( N + Σ )* → ( N '+Σ ) * , care prelungeşte pe f.
Fie s 0 ' = f ( s 0 ) şi fie mulţimea P ' = { f (u ) → f (v) / u → v ∈ P}. Dorim ca
această mulţime să fie mulţime de reguli pentru gramatica pe care o construim;
pentru aceasta, trebuie să verificăm faptul că în stânga fiecărei “reguli” din P'
avem măcar un simbol care este un neterminal ( adică din N '); acest lucru se
obţine în mod clar datorită definiţiei lui f. Tot din modul de definire al lui f ca şi
faptului că f este izomorfism, avem
w ⇒ *G w' ⇔ f ( w) ⇒ *G ' f ( w' ).
Obţinem atunci că
w ∈ L(G ) ⇔ (∃) s 0 ⇒ *G w, w ∈ Σ * ⇔ (∃) f ( s 0 ) ⇒ *G ' f ( w), w ∈ Σ * ⇔

(∃) s 0 ' ⇒ *G ' w, w ∈ Σ * (deoarece din f ( x) = x, x ∈ Σ , avem că f ( w) = w, w ∈ Σ * )


⇔ w ∈ L(G ' ).

Putem observa că, până acum, nu am impus nici o restricţie asupra


mulţimii regulilor dintr-o gramatică. Datorită necesităţilor de ordin practic, legate
de teoria calculabilităţii, a apărut ca necesitate problema clasificării. Cea mai
cunoscută clasificare a gramaticilor este “Ierarhia lui Chomsky”.

1.6 Definiţii. Fie G = ( N , Σ , s 0 , P ) o gramatică.

i) Spunem că G este gramatică de tip 0 (sau gramatică recursiv numărabilă)


dacă nu avem nici o restricţie asupra alcătuirii regulilor lui P.
ii) Spunem că G este gramatică de tip 1 (sau gramatică sensibilă la context)
dacă regulile sale sunt de forma uxv → urv, unde u, v ∈ ( N + Σ ) * ,

x ∈ N , r ∈ ( N + Σ ) + sau de forma s 0 → ε , caz în care simbolul iniţial s0


nu apare în dreapta vreunei reguli.
iii) Spunem că G este gramatică de tip 2 (sau gramatică independentă de
context) dacă regulile sale sunt de forma x → r , x ∈ N , r ∈ ( N + Σ ) * .
iv) Spunem că G este gramatică de tip 3 (sau gramatică regulată) dacă
regulile sale sunt de forma x → wx' , sau x → w, unde x, x'∈ N şi

w∈Σ *.
v) Un limbaj L este de tip n, n ∈{0,1,2,3} dacă există o gramatică G de tip n
care să-l genereze (adică L = L(G)).
1.3 Observaţii. Să notăm prin Ln clasa limbajelor de tipul n. Este clar că L1 ⊆ L 0

şi L 3 ⊆ L 2 Se poate demonstra că, L 2 ⊆ L1 iar incluziunile sunt stricte.

Să vedem ce se poate spune despre clasa limbajelor cu un număr finit de


cuvinte, L f . Este clar că limbajul vid este în L f

1.1 Teoremă L f ⊆ L 3

Demonstraţie. Gramatica G = ( N , Σ , s 0 , P ) , unde N = {s 0 , x}, Σ este o

mulţime nevidă disjunctă de N, şi P = {s0 → x} nu generează nici un cuvânt pe

Σ , deci L(G ) = ∅. Pe de altă parte, regula s0 → x se mai poate scrie s0 → εx, ε


fiind cuvântul vid din Σ *, ceea ce indică faptul că G este de tip 3. Aşadar
∅ ∈ L3 .

Fie acum L = {w1 , w2 ,..., wn } ⊆ Σ * un limbaj finit peste Σ şi N = {s0}, cu

s0∉Σ. Fie G = ( N , Σ , s 0 , P ) gramatica având mulţimea de reguli

P = ( s 0 → w1 , s 0 → w2 ,..., s 0 → wn }.

Deoarece wi ∈ Σ * , i = 1, n gramatica G este de tip 3 şi L = L(G) deci L ∈ L3 .

Din cele arătate mai sus, avem L f ⊆ L 3

1.4 Observaţie. Din observaţiile 1.3 şi teorema precedentă rezultă că familia


limbajelor finite este conţinută în oricare dintre clasele de limbaje Ln , n ∈ 0,3 .

2. Proprietăţi la închidere

Am definit în primul capitol, pentru limbaje, operaţiile raţionale : suma a două


limbaje (care era, în fond, reuniunea lor) produsul a două limbaje şi iteratul (sau “steaua
Kleene”) unui limbaj. După definiţia acestor operatii am vorbit despre închidere la
operatii rationale, ceea ce ne-a condus la o clasă de limbaje, limbajele raţionale.
În cadrul acestui paragraf vom încerca să studiem proprietăţile de închidere ale
claselor de limbaje Ln, n ∈ 0,3 .

2.1 Teoremă. Oricare dintre familiile de limbaje L n , n ∈ 0,3 este închisă la sumă.

Demonstraţie. Aşadar, trebuie să demonstrăm că, dacă n ∈ 0,3 şi L1, L2 ∈ Ln, atunci

L1+ L2 ∈ Ln. Fie G1 = ( N 1 , Σ1 , s 01 , P1 ), G2 = ( N 2 , Σ 2 , s 02 , P2 ) gramatici de tipul n astfel

încât Li = L(Gi), i=1,2.


Conform propoziţiei 1.1, putem presupune că N1∩N2 = ∅. Fie s0 un simbol,
s 0 ∉ N 1 ∪ N 2 . Construim gramatica G = ( N , Σ , s 0 , P ), fiecare element de definire al

gramaticii fiind dat astfel:


N = N 1 ∪ N 2 ∪ {s 0 }
Σ =Σ 1∪Σ 2
P = P1 ∪ P2 ∪ {s 0 → s 01 , s 0 → s 02 }.

Deoarece regulile s0 → s01 , s0 → s02 pot fi văzute ca fiind s 0 → ε s 01 , s 0 → ε s 02 ,


care sunt reguli de tip 3, ele nu schimbă tipul gramaticii (adică dacă P1, P2 conţin reguli
care fac ca G1, G2 să fie de tip n, n ∈ 0,3, P1 ∪ P2 ∪ {s0 → s01 , s0 → s02 } va conţine reguli
care fac ca G să fie de acelaşi tip n).
Rămâne să demonstrăm că L1 + L2 = L(G).
"⊆": Fie w ∈ L1 + L2 . Rezulta că w ∈ L1 sau w ∈ L2 . Dacă w ∈ L1 rezultă că există

derivarea s 01 ⇒ *G1 w. Deoarece P1 ⊂ P, această derivare poate fi scrisă şi s 01 ⇒ *G w . În

P, avem şi regula s 0 → s 01 , deci există derivarea directă s 0 ⇒ G s 01 , deci s 0 ⇒ *G w

ceea ce indică faptul că w ∈ L(G ). În mod asemănător, se demonstrează că, dacă


w ∈ L2 , atunci w ∈ L(G ). Aşadar, L1 + L2 ⊆ L(G ).

" ⊇ " : Reciproc, fie w ∈ L(G ). Rezultă că există derivarea în G, s 0 ⇒ *G w . Întrucât

singurele reguli din G cu s0 în partea stângă sunt s 0 → s 01 şi s 0 → s 02 iar

s 01 , s 02 ∉ Σ *, (deoarece sunt simboluri neterminale din N) derivarea s 0 ⇒ *G w este de

lungime cel puţin 2, primul pas al derivării fiind s 0 ⇒ G s 01 sau s 0 ⇒ G s 02 .


Putem presupune, fără a restrânge generalitatea, că derivarea considerată este
s 0 ⇒ G s 01 ⇒ *G w.

Deoarece N1∩N2 = ∅ rezultă că s 01 ∉ N 2 . Urmează că, în derivarea s 01 ⇒ *G w

se vor aplica numai reguli din P1, de unde rezultă că există derivarea
s 01 ⇒ *G1 w deci w ∈ L1 . În mod analog, dacă am fi presupus că derivarea considerată

este s 0 ⇒ G s 02 ⇒ *G w. , am fi obţinut că w ∈ L2 . În orice caz, w ∈ L1 + L2 , ceea ce

încheie demonstraţia teoremei.

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