Sunteți pe pagina 1din 13

Curs 5

Limbaje Independente de Context

În cele două cursuri precedente au fost prezentate două metode diferite ı̂nsă echivalente
de a descrie limbaje: automatele finite şi expresiile regulate. În final au fost identificate
limbaje simple care nu pot fi descrise ı̂n acest fel, de exemplu limbajul {0n 1n | n ≥ 0}.
Începând cu acest curs vor fi prezentate gramaticile independente de context. Vom
vedea că ele sunt o metodă mai puternică de descriere a limbajelor. O caracteristică impor-
tantă a lor este că pot descrie proprietăţi care au o structură recursivă.
Prima oară, gramaticile independente de context au fost folosite ı̂n studiul lim-
bajelor umane. De exemplu, ele pot descrie recursiv relaţiile dintre substantiv, verb şi
prepoziţie ı̂n fraze.
Gramaticile independente de context au aplicaţii multe ı̂n specificarea şi compi-
larea limbajelor de programare. Gramatica unui limbaj de programare este foarte utilă
pentru cei care vor să-i ı̂nveţe sintaxa. De obicei, primul pas al proiectanţilor de compila-
toare şi interpretoare pentru limbaje de programare este să-i definească sintaxa. Cele mai
multe compilatoare şi interpretoare conţin un analizor gramatical (numit şi parser) care
extrage semnificaţia unui program ı̂nainte de a trece ı̂n faza de compilare sau interpetare. În
prezent se cunosc numeroase metodologii de construire a parserelor precum şi tooluri care
generează automat un parser din o gramatică.
Limbajele care pot fi descrise cu o gramatică independentă de context se numesc limbaje
independente de context. Vom vedea că ele includ toate limbajele regulate precum şi
numeroase limbaje neregulate.
În prima parte a acestei prezentări vor fi descrise gramaticile independente de context
şi proprietăţile limbajelor independente de context. În partea a doua vor fi prezentate
automatele push-down. Acestea sunt o clasă de automate care pot recunoaşte limbaje
independente de context. Deasemenea, automatele push-down ne vor permite să aflăm mai
multe despre gramaticile şi limbajele independente de context.

1 Gramatici Independente de Context


Exemplul ilustrativ următor este o gramatică independentă de context numită G1 .

A → 0A1
A→B
B→#

1
O gramatică este formată din reguli de substituţie numite şi producţii. Fiecare regulă
este o linie separată a gramaticii formată dintr-un simbol urmat de o săgeată şi apoi un şir.
• Simbolul din stânga săgeţii se numeşte variabilă.
• Şirul din dreapta săgeţii este o secvenţă de variabile şi alte simboluri numite termi-
nale. Variabilele se scriu cu litere mari iar terminalele cu litere mici. Terminalele
corespund alfabetului de intrare şi sunt adesea litere mici, numere sau simboluri spe-
ciale.
• Una din variabile este desemnată să fie variabila de start. De obicei, variabila de
start este cea care apare ı̂n partea stângă a primei reguli din gramatică.
De exemplu, gramatica G1 are trei reguli. Variabilele lui G1 sunt A şi B. A este variabila
de start. Simbolurile terminale sunt 0, 1 şi #.
O gramatică independentă de context descrie un limbaj prin generarea de şiruri ı̂n felul
următor:
1. Se scrie mai ı̂ntâi starea de start care este de obicei simbolul din stânga primei reguli
din gramatică.
2. Se alege o variabilă care apare scrisă şi o regulă care ı̂ncepe cu variabila aleasă. Se
ı̂nlocuieşte variabila aleasă cu partea dreaptă a regulii alese.
3. Se repetă pasul 2 până când se obţine un şir care conţine doar simboluri terminale.
We exemplu, gramatica G1 poate genera şirul 000#111. Secvenţa de substituţii care generează
un şir se numeşte derivaţie. O derivaţie a şirului 000#111 ı̂n gramatica G1 este

A ⇒ 0A1 ⇒ 00A11 ⇒ 000A111 ⇒ 000B111 ⇒ 000#111.

Alternativ, derivarea unui şir poate fi reprezentată şi cu un arbore generator, ca cel de mai
jos. Toate şirurile generate ı̂n acest fel constituie limbajul gramaticii. În general, limbajul

0 0 0 # 1 1 1

Figure 1: Arbore generator pentru gramatica G1 .

unei gramatici G este denotat L(G). Ese uşor de observat că L(G1 ) = {0n #1n | n ≥ 0}.

2
Limbajele care pot fi generate de o gramatică independentă de context se numesc limbaje
independente de context (sau CFL, abreviere de la Context-Free Languages).
O abreviere convenabilă pentru mai multe reguli care au aceeaşi parte stângă este să se
scrie o singură dată simbolul din partea stângă urmat de săgeată, urmat de părţile drepte
ale regulilor separate cu simbolul ,,|”. De exemplu, regulile A → 0A1 şi A → B se pot scrie
abreviat A → 0A1 | B ı̂n o singură linie.

1.1 Definiţia formală a unei gramatici independente de context


O gramatică independentă de context este un 4-tuplu (V, Σ, R, S) unde
1. V este o mulţime finită de variabile.
2. Σ este o mulţime finită de terminale. Se presupune că mulţimile V şi Σ sunt disjuncte,
adică V ∩ Σ = ∅.
3. R este o mulţime finită de reguli de forma X → w cu X ∈ V şi w un şir de simboluri
din V ∪ Σ.
4. S ∈ V este variabila de start.
Dacă u, v, w ∈ (V ∪ Σ)∗ şi A → w este o regulă a gramaticii, vom spune că uAv produce
uwv şi vom scrie uAv ⇒ uwv. Deasemenea, spunem că u derivează v şi scriem u ⇒∗ v
dacă u = v sau dacă există o secvenţă de şiruri u1 , . . . , uk astfel ı̂ncât
u ⇒ u1 ⇒ u2 ⇒ . . . ⇒ uk ⇒ v.
Limbajul gramaticii este mulţimea de şiruri {w ∈ Σ∗ | S ⇒∗ w}.
Cel mai adesea, o gramatică se specifică scriindu-i regulile. Variabilele sunt simbolurile
care apar ı̂n partea stângă a regulilor iar terminalele sunt celelalte simboluri care apar ı̂n
reguli. Implicit, variabila de start este variabila din partea stângă a primei reguli.

1.2 Exemplu de gramatică independentă de context


Gramatica G = (V, Σ, R, hEXPRi) cu regulile
hEXPRi → hEXPRi + hTERMi | hTERMi
hTERMi → hTERMi × hFACTORi | hFACTORi
hFACTORi → (hEXPRi) | a
Arborii generatori din Figura 2 indică faptul că şirurile a + a × a şi (a + a) × a pot fi generaţi
de gramatica G.
Un compilator translatează codul scris ı̂n un limbaj de programare ı̂n o altă formă care
este mai convenabilă pentru execuţie. Acest proces se numeşte parsing şi se bazează adesea
pe construirea unui arbore generator pentru programul citit. Construcţia arborelui generator
se bazează pe gramatica independentă de context a limbajului de programare.
Gramatica G descrie un fragment din un limbaj de programare cu expresii aritmetice. Se
poate remarca felul ı̂n care arborii generatori ilustraţi ı̂n Figura 2 grupează operaţiile. De
exemplu, arborele pentru a + (a × a) grupează operatorul × şi operanzii lui (ultimii doi a)
ca pe un operand al operatorului +. În arborele pentru (a + a) × a, ordinea este inversată.

3
Figure 2: Arbori generatori pentru şirurile a + a × a şi (a + a) × a.

1.3 Designul gramaticilor independente de context


La fel ca şi designul automatelor finite, şi designul gramaticilor independente de context
necesită creativitate. Vom descrie aici câteva tehnici care pot fi folosite independent sau ı̂n
combinaţii pentru a construi gramatici independente de context (sau CFG-uri).
Reuniunea de limbaje. Dacă se cunosc gramaticile G1 = (V1 , Σ, R1 , S1 ) şi G2 =
(V2 , Σ, R2 , S2 ) pentru limbajele L1 şi L2 atunci putem construi uşor CFG pentru limbajul
L1 ∪ L2 : G = (V, Σ, R, S) unde S este un neterminal nou, V = V1 ∪ V2 ∪ {S} şi R =
R1 ∪ R2 ∪ {S → S1 |S2 }.
De exemplu, pentru a obţine o gramatică pentru limbajul {0n 1n | n ≥ 0}∪{1n 0n | n ≥ 0}
construim mai ı̂ntâi gramatica
S1 → 0S1 1 | 
pentru limbajul {0n 1n | n ≥ 0} şi gramatica

S2 → 1S2 0 | 

pentru limbajul {1n 0n | n ≥ 0}. Dacă adăugăm regula S → S1 | S2 obţinem gramatica

S → S1 | S2
S1 → 0S1 1 | 
S2 → 1S2 0 | .

Conversia unui AFD ı̂n CFG. Uneori este mai uşor să se construiască un AFD
pentru un limbaj. Conversia unui AFD ı̂n gramatică independentă de context se face astfel.
Se consideră o variabilă nouă Ri pentru fiecare stare qi a AFD-ului. Apoi se adaugă regula
R1 → aRj la CFG dacă δ(qi , a) = qj este o tranziţie a AFD-ului. Dacă qi este stare finală a
AFD-ului, se adaugă regula Ri → . Variabila de start a gramaticii se alege să fie R0 , unde
q0 este starea de start.

4
Tehnici de memorare. Anumite limbaje independente de context conţin şiruri cu două
subşiruri ,,legate” ı̂n sensul că o maşină pentru un astfel de limbaj ar trebui să reţină un
număr nelimitat de informaţie despre un subşir pentru a verifica dacă al doilea subşir este
cel corespunzător. Această situaţie apare pentru limbajul {0n 1n | n ≥ 0} deoarece maşina
trebuie să ţină minte numărul de 0 ca să verifice că este egal cu numărul de 1 din şirul
următor. O gramatică independentă de context care tratează correct o situaţie de acest gen
are o regulă de forma R → uRv care generează şiruri ı̂n care porţiunea ce conţine secvenţe
de u corespunde porţiunii care conţine secvenţe de v.

În final, ı̂n limbaje mai complexe şirurile pot conţine structuri care apar recursiv ca
părţi ale altor structuri sau ca părţi de structuri de acelaşi fel. Gramatica pentru expresii
aritmetice ilustrată mai devreme este un exemplu tipic de acest fel. În acel exemplu, orice
apariţie a simbolului a poate fi ı̂nlocuită recursiv cu orice expresie aritmetică ı̂ntre paranteze.
Pentru a obţine acest efect, se plasează variabila care generează structura ı̂n locaţia din
regulă unde poate să apară recursiv structura respectivă.

1.4 Ambiguitate
Uneori, a gramatică poate genera acelaşi şir ı̂n mai multe feluri. Un astfel de şir va avea
mai mulţi arbori generativi şi deci mai multe semnificaţii. Este de dorit să se evite astfel de
situaţii ı̂n aplicaţii. De exemplu ı̂n limbajele de programare un program dat trebuie să aibă
o singură interpretare.
Dacă o gramatică generează un şir ı̂n mai multe feluri spunem că şirul ese derivat am-
biguu ı̂n gramatica respectivă. Dacă o gramatică generează un şir ambiguu spunem că
gramatica este ambiguă.
De exemplu, gramatica G5 definită de regula

hEXPRi → hEXPRi + hEXPRi | hEXPRi × hEXPRi | (hEXPRi) | a

generează ambiguu şirul a + a × a. Figura următoare prezintă doi arbori generativi diferiţi
pentru acest şir.

Această gramatică nu ţine cont de precedenţa operatorilor aritmetici şi deci poate grupa +
ı̂naintea lui ×, sau invers. În schimb, gramatica G din Secţiunea 1.2 generază acelaşi limbaj
ca şi G5 şi fiecare şir generat are un arbore generativ unic. Prin urmare gramatica G este
neambiguă ı̂n timp ce gramatica G5 este ambiguă.
Definiţia generală a noţiunii de ambiguitate este următoarea. Spunem că o gramatică
generează ambiguu un şir dacă şirul are doi arbori generativi diferiţi. Se poate ı̂ntâmpla
ca pentru acelaşi arbore generativ să putem scrie derivaţii diferite deoarece putem modifica

5
ordinea de rescriere a variabilelor. Putem ı̂nsă să definim un tip de derivaţie care ı̂nlocuieşte
variabilele ı̂n o ordine predefinită. O derivaţie a unui şir w ı̂n o gramatică G este o derivaţie
la stânga dacă la fiecare pas se ı̂nlocuieşte variabila cea mai din stânga.
Definiţia 1 Un şir este derivat ambiguu ı̂n gramatica independentă de context G dacă are
2 sau mai multe derivaţii la stânga care sunt diferite. Gramatica G este ambiguă dacă
generează ambiguu un şir.
Uneori, când avem o gramatică ambiguă putem găsi o gramatică neambiguă care generează
acelaşi limbaj. Există limbaje independente de context pentru care nu există gramatici
neambigue. Un astfel de limbaj se numeşte inerent ambiguu. De exemplu, limbajul
{ai bj ck | i = j sau j = k} este inerent ambiguu.

1.5 Forma normală Chomsky


Când se lucrează cu gramatici independente de context, este convenabil să le avem scrise ı̂n
o formă simplificată. O formă foarte simplă şi convenabilă este forma normală Chomsky.
Vem vedea că forma normală Chomsky este utilă pentru a defini algoritmi care să lucreze
cu gramatici independente de context.
Definiţia 2 O gramatică independentă de context este ı̂n forma normală Chomsky dacă
este alcătuită din reguli de forma

A → BC
A→a

unde a poate fi orice terminal iar A, B şi C pot fi orice variabile, cu excepţia faptului că B
şi C nu pot fi variabila de start. De asemenea, este permis să avem regula S →  dacă S
este variabila de start.
Rezultatul care ne interesează este următorul.
Teorema 1 Orice limbaj independent de context este generat de o gramatică ı̂n forma nor-
mală Chomsky.
Demonstraţie. Conversia unei gramatici G ı̂n o formă normală Chomsky se face ı̂n 4 paşi.
1. Mai ı̂ntâi se adaugă a variabilă de start nouă S0 şi regula S0 → S unde S este variabila
originală de start a lui G. Acest pas garantează faptul că variabila de start nu apare
ı̂n partea dreaptă a vreunei reguli.
2. Apoi se elimină toate regulile A →  pentru care A nu este variabilă de start. Pentru
fiecare apariţie a lui A ı̂n partea dreaptă a unei reguli se adaugă o regulă nouă cu
acea apariţie a lui A eliminată. Altfel spus, dacă R → uAv este o regulă, se va adăuga
regula R → uv. Această transformare se face pentru fiecare apariţie a lui A, deci regula
R → uAvAw va provoca adăugarea regulilor R → uvAw, R → uAvw şi R → uvw.
Dacă avem regula R → A şi eliminăm A, adăugăm regula R →  cu excepţia cazului
ı̂n care regula R →  a fost eliminată mai devreme. Acest pas se repetă până când se
elimină toate -regulile care nu se referă la starea de start.

6
3. În al treilea pas se elimină regulile unitare de forma A → B. Când se elimină o regulă
A → B, atunci pentru toate cazurile ı̂n care apare o regulă B → u se adaugă regula
A → u, cu excepţia cazului ı̂n care A → u este o regulă unitară care a fost deja
eliminată. Acest pas se repetă până când se elimină toate regulile unitare.
4. În final se convertesc toate regulile rămase ı̂n forma Chomsky conrespunzătoare. Fiecare
regulă A → u1 u2 . . . uk cu k ≥ 3 se ı̂nlocuieşte cu regulile A → u1 A1 , A1 → u2 A2 , . . . ,
Ak−2 → uk−1 uk unde A1 , A2 , . . . , Ak−2 sunt variabile noi. Dacă k = 2 se ı̂nlocuieşte
fiecare terminal ui din regulile precedente cu o variabilă nouă Ui şi se adaugă regula
Ui → ui .

Exemplu
Fie G6 gramatica independentă de context
S → ASA | aB
A→B|S
B→b|
1. După primul pas obţinem gramatica
S0 → S
S → ASA | aB
A→B|S
B→b|

2. Dacă se elimină -regula B →  se obţine gramatica


S0 → S
S → ASA | aB | a
A→B|S|
B→b
Apoi se elimină -regula A →  şi se obţine gramatica
S0 → S
S → ASA | aB | a | SA | AS | S
A→B|S
B→b

3.a Dacă se elimină regula unitară S → S, restul regulilor rămân neschimbate. Apoi se
elimină regula unitară S0 → S şi se obţine gramatica
S0 → ASA | aB | a | SA | AS
S → ASA | aB | a | SA | AS
A→B|S
B→b

7
3.b Se elimină regula unitară A → B şi se obţine gramatica

S0 → ASA | aB | a | SA | AS
S → ASA | aB | a | SA | AS
A→S|b
B→b

Apoi se elimină regula unitară A → S şi se obţine gramatica

S0 → ASA | aB | a | SA | AS
S → ASA | aB | a | SA | AS
A → b | ASA | aB | a | SA | AS
B→b

4. În final se convertesc toate regulile rămase ı̂n forma Chomsky şi se obţine gramatica

S0 → AA1 | U B | a | SA | AS
S → AA1 | U B | a | SA | AS
A → b | AA1 | U B | a | SA | AS
A1 → SA
U →a
B→b

2 Automate Pushdown
Automatul push-down este un model nou de calcul nedeterminist care, spre deosebire de
automatul finit nedeterminist are o stivă. Stiva reprezintă memorie suplimentară care
permite automatului să recunoască nişte limbaje neregulate.
Vom vedea că automatele pushdown sunt echivalente cu gramaticile independente de
context. Această echivalenţă este utilă deoarece avem 2 opţiuni cum să demonstrăm că un
limbaj este independent de context.
Figura următoare este o reprezentare schematică a unui automat finit. Controlul repre-
zintă stările unei funcţii de tranziţie, banda conţine şirul de intrare iar săgeata reprezintă
capul de citire poziţionat pe simbolul care urmează să fie citit.

Dacă se adaugă o stivă se obţine reprezentarea schematică a unui automat pushdown ilus-
trată ı̂n continuare.

8
Automatul pushdown (APD) poate scrie simboluri pe stivă şi le poate reciti mai târziu.
Scrierea unui simbol ı̂mpinge ı̂n jos toate celelalte simboluri din stivă. În orice moment se
poate citi şi şterge simbolul din vârful stivei. În acest caz simbolurile rămase ı̂n stivă se
mută ı̂n sus cu 1 poziţie. Trebuie reţinut că tot accesul de scriere/citire a stivei se produce
doar la vârful stivei. Altfel spus, o stivă este un dispozitiv de memorare de tipul ,,ultimul
care intră-primul care iese”. Dacă se scrie o informaţie A1 pe stivă şi apoi se adaugă altă
informaţie A2 , informaţia A1 nu mai poate fi accesată decât după ce se elimină informaţia
A2 din stivă.
Stivele sunt utile deoarece pot reţine o cantitate nelimitată de informaţie. Reamintim
faptul că un automat finit nu poate să recunoască limbajul {an bn | n ≥ 0} fiindcă nu are
memorie să reţină numere n mari. Un APD poate recunoaşte acest limbaj deoarece poate
folosi stiva ca să ţină minte câţi 0 a citit. Deci stiva permite ca automatul să memoreze
numere oricât de mari.
La fel ca şi automatele finite, şi automatele pushdown pot fi deterministe sau nedeter-
ministe. Vom vedea că există ı̂nsă o deosebire mare ı̂ntre automatele finite şi automatele
pushdown:

• AFD şi AFN sunt echivalante.


• APD deterministe şi APD nedeterministe nu sunt echivalante.

2.1 Definiţia formală a automatului pushdown


Definiţia 3 Un automat pushdown este un 6-tuplu (Q, Σ, Γ, δ, q0 , F ) unde Q, Σ, Γ şi F
sunt mulţimi distincte şi
1. Q este mulţimea de stări,
2. Σ este alfabetul de intrare,

3. Γ este alfabetul stivei,


4. δ : Q × Σ × Γ → 2Q×Γ este funcţia de tranziţie,
5. q0 ∈ Q este starea de start, şi

6. F ⊆ Q este mulţimea stărilor de acceptare.


Reamintim că  este cuvântul cu lungimea 0, Σ = Σ ∪ {}, Γ = Γ ∪ {} şi 2Q×Γ este
mulţimea submulţimilor lui Q × Γ .

9
Un automat pushdown M = (Q, Σ, Γ, δ, q0 , F ) calculează astfel. Un cuvânt w ∈ Σ∗ este
acceptat dacă putem scrie w = w1 w2 · · · wn cu wi ∈ Σ şi există stările r0 , r1 , . . . , rm ∈ Q şi
şirurile s0 , s1 , . . . , sm ∈ Γ∗ sare satisfac următoarele 3 condiţii (şirurile si reprezintă secvenţa
de conţinuturi ale stivei lui M de-a lungul unei alternative de calcul care-l acceptă pe w):
1. r0 = q0 şi s0 = . Această condiţie indică faptul că M porneşte din starea de start cu
stiva goală.
2. Pentru i = 0, . . . , m − 1 avem (ri+1 , b) ∈ δ(ri , wi+1 , a) unde si = at şi si+1 = bt pentru
a, b ∈ Γ şi t ∈ Γ∗ . Această condiţie spune că M efectuează tranziţii corecte care
depind de starea, conţinutul stivei şi simbolul următor de intrare.
3. rm ∈ F . Această condiţie indică faptul că ı̂n final M trece ı̂n o stare finală.

2.2 Exemple de automate pushdown


Exemplul 1. Un automat psuhdown care recunoaşte limbajul {0n 1n | n ≥ 0} este M1 =
(Q, Σ, Γ, δ, q1 , F ), unde
Q = {q1 , q2 , q3 , q4 },
Σ = {0, 1},
Γ = {0, $},
F = {q1 , q4 }, şi
δ este funcţia de tranziţie dată de tabela următoare ı̂n car eintrările goale reprezintă
mulţimea vidă

Intrare: 0 1 
Stivă: 0 $  0 $  0 $ 
q1 {(q2 , $)}
q2 {(q2 , 0)} {(q3 , )}
q3 {(q3 , )} {(q4 , )}
q4

Acest APD poate fi descris şi cu o diagramă de stări:

Diagrama de stări pentru APD este similară cu cea pentru automate finite, cu modificarea că
scriem deasuprea săgeţilor de tranziţie şi felul cum foloseşte automatul stiva când trece din
o stare ı̂n alta. Se scrie ,,a, b → c” pentru a indica faptul că atunci când automatul citeşte
simbolul a de pe bandă, poate ı̂nlocui simbolul b din vârful stive cu simbolul c. Oricare din
simbolurile a, b, c poate fi . Dacă a = , automatul poate face o tranziţie fără să citească

10
vreun simbol de pe banda de intrare. Dacă b = , automatul poate face tranziţia fără să
citească şi să scoată vreun simbol din stivă. Dacă c = , automatul nu scrie nici un simbol
pe stivă când face tranziţia.
Definiţia formală a unui APD nu are un mecanism explicit care sa-i permită automatului
să detecteze dacă stiva este vidă. APD-ul din acest exemplu poate efectua acest test fiindcă
la ı̂nceput pune simbolul $ pe stivă. Dacă ulterior detectează simbolul $ din nou, va şti că
stiva s-a golit. Acest mod de detecţie că stiva s-a golit poate fi utilizat de către orice APD.
O altă observaţie importantă este că un APD nu poate testa explicit dacă a ajuns la
sfârşitul şirului de intrare. APD-ul din acest exemplu poate detecta acest fapt deoarece
intră ı̂n o stare de acceptare doar atunci când maşina ajunge la sfârşitul şirului de intrare.
Prin urmare putem presupune ı̂ntotdeauna că un APD poate verifica dacă stiva s-a golit
sau dacă a citit tot şirul de intrare.

Exemplul 2. Vom descrie un APD care recunoaşte limbajul {ai bj ck | i, j, k ≥ şi i =


j sau i = k}. Intuitiv, APD-ul pe care-l construim lucrează astfel. Mai ı̂ntâi citeşte subşirul
de a-uri şi le pune pe stivă. Când a terminat de citit a-uri, automatul poate alege să
le potrivească cu subşirul de b-uri sau cu subşirul de c-uri. Această manevră este puţin
problematică deoarece automatul nu ştie ı̂n avans dacă subşirul de a-uri trebuie potrivit cu
cel de b-uri sau cu cel de c-uri. Această problemă poate fi rezolvată uşor deoarece un APD
poate fi nedeterminist şi poate ghici ce să facă.
Diagrama de stări a unui astfel de APD este ilustrată mai jos.

Exemplul 3. Vom descrie un APD pentru limbajul {wwR | w ∈ {0, 1}∗ } unde wR reprezintă
cuvn̂tul w inversat. Construcţia APD-ului poate fi descrisă neformal astfel. Automatul
ı̂ncepe să citească şi să pună pe stivă toate simbolurile citite până la un moment când decide
nedeterminist că a citit jumătate din cuvânt, adică w. Apoi ı̂ncepe să scoată simboluri din
stivă verificând că simbolul scos se potriveşte cu cel de intrare. Dacă automatul reuşeşte
să golească stiva ı̂n acest fel şi totodată să şi consume tot şirul de intrare, cuvântul este
acceptat. În caz contrar, cuvântul nu este acceptat.
Diagrama de stări a maşinii descrise este ilustrată mai jos.

11
2.3 Exerciţii
1. Se consideră gramatica independentă de context următoare
E →E+T |T
T →T ×F |F
F → (E) | a
Ss̆e construiască arborii generatori şi derivaţiile la stânga pentru expresiile următoare

a) a b) a+a c) a+a+a d) ((a))

2. Se consideră gramatica independentă de context G cu regulile


R → XRX | S
S → aT b | bT a
T → XT X | X | 
X→a|b
(a) Care sunt variabilele lui G?
(b) Care sunt terminalele gramaticii G?
(c) Care este variabila de start a lui G?
(d) Să se indice 3 şiruri din limbajul L(G).
3. Să se definească gramatici independente de context care generează limbajele următoare
din {0, 1}∗ :
(a) {w | w conţine trei de 1}.
(b) {w | w ı̂ncepe şi se termină cu acelaşi simbol}.
(c) {w | lungimea lui w este impară}.
(d) {w | lungimea lui w este impară şi simbolul de la mijloc este 0}.
(e) Mulţimea vidă.
4. Să se convertească gramatica următoare ı̂n formă normală Chomsky
A → BAB | B | 
B → 00 | 

12
5. Să se demonstreze că dacă G este o gramatică independentă de context ı̂n formă
normală Chomsky atunci pentru orice şir w ∈ L(G) cu lungimea n ≥ 1 se produce o
derivaţie cu exact 2n − 1 paşi care să-l genereze pe w.

Bibliografie
1. Michael Sipser. Introduction to the Theory of Computation, Second Edition. Thomson
Course Technology. 2006. Capitolul 3: Context-Free Languages.

13

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