Sunteți pe pagina 1din 67

PARTEA II

CAPITOLUL 4

DEFINITII DE BAZA ALE GRAMATICII

4.0.Introducere

In prima parte a acestei carti am vazut ca limbajele regulate sunt inzes-

trate cu multe proprietati interesante si utile care duc la o teorie netriviala.

Cu toate acestea, am notat de asemenea ca expresivitatea asociata aces-

tor limbaje este extrem de limitata in multe sensuri. Exista schir limbaje

simple care nu pot fi descrise cu acest model.

In aceasta parte vom considera diferite moduri de definire a limbajelor

vom introduce alte modele care au exprevitate mai mare decat acelea pe

care le-am studiat pana acum. Initial ne vom axa pe gramaticile inde-

pendente de context. Acest mecanism a fost inventat pentru a sustine

cercetarea din doua domeniu diferite. Noam Chomsky a fost interesat de

formalizarea studiului limbajelor naturale si a inventat un spectru de forme

gramaticale utile acestui studiu. Vom considera fiecare nivel din ierarhia

de baza, dar vom incepe cu familiile independente de context. In acelasi

206
timp Chomsky si-a dezvoltat modelele si aparent independent Backus a in-

ventat o metoda formala de gasire a unor mijloace precise si independente

de oice mecanism prin care sa descrie sintaxa limbajelor de programare.

Aceasta metoda larg folosita a ramas cunoscuta sub numele de Bachus Nor-

mal Form sau sub numele de Backus-Naur Form - BNF in ambele cazuri si

este identica cu ideea de gramatici independente de context a lui Chomsky.

Cercetarea acestui model este motivata de aplicatiile sale la descrierea lim-

bajelor de programare mai degraba decat a limbajelor naturale, dar exista

o legatura stransa intre acestea doua.

In timp ce automatele de acceptare finite studiate partea intai sunt in-

adecvate pentru recunoasterea limbajelor independente de context a fost

gasita o modalitatea prin care se asigura o capacitate de recunoastere nece-

sara acestor limbaje. Ea implica mecansime finite cu capacitate aditionala

de numerare care se pot extinde fara limita, dar care sunt restrictionate

de modalitatea de acces - o memorare LIFO sau stiva pushdown. Vom

dezvolta acest model intr-un subcapitol al acestei parti.

Scopul principal in acest capitol este de a introduce conceptele de gra-

matica si de model rescris. Aceasta este cheia pentru cercetarea multor

proprietati ale variatelor modele computationale. Este posibil ca cititorul

sa fi intalnit BNF in studiul limnajelor de programare . Daca de atunci id-

dea principala a acestui capitol ii este deja familiara. Oricum vom dezvolta

aceasta idee in mod riguros decat se face in cazul limbajelor de programare

si vom urmari proprietati ale gramaticilor si ale rescrierilor. Aceasta ne va

207
permite sa intelegem limitele acestui mecanism cat si solidaritatea lor.

4.1. Definitii si proprietati de baza

In partea a treia a acestei carti vom cerceta alte gramatici care au o

capacitate de expresivitate mai mare decat a gramaticilor independente

de context. Deoarece ideile de baza de resceire si derivare sunt aceleasi

pentru toate aceste gramatici vom prezenta suficient de general definitiilor

prin care sa tratam aceste probleme de prima data.

Definitia 4.1.1.

O gramatica G este un 4-uplu G =( V, ,P,S ), unde V si sunt

multimi disjuncte, finite, nevide de elemente numite variabile respectiv

terminale, P , productiile este o multime finita de perechi ordonate de

secvente P (( V )* · V · (V )* ) × (V * )si S V numit simbol

de start. O pereche ordonata <a,ß> din P se noteaza intotdeauna

a ß , deseori ne referim la componentele acestei perechi sub numele

”partea stanga” si ”partea dreapta” a productiei.

Deseori folosim termenul de ”gramatica” in loc de ”gramatica struc-

turala de limbaj”

Se observa ca partea stanga a unei productii trebuie sa includa in-

totdeauna cel putin un nedeterminal si nu sa mai impun alte restric-

tii asupra secventilor unei productii. Neterminalele unei gramatici sunt

”meta-simboluri” al caror rol este de a ajuta la descrierea unui limbaj

peste *. Productiile sunt folosite ca reguli de retranscriere si duc la

208
”generarea” secventelor limbajului asociat.

Definitia 4.1.2.

Pentru gramatica G =( V, ,P,S )si x, y (V ), x deriva direct in

y, notat x y daca x = x 1 ax 2 , y = x 1 ßx 2 si a ß P ; de asemenea

x deriva in y, notat x y , daca pentru un n = 0, exista z 0 ,z 1 , .., z n

(V ) * astfel incat x = z 0 ,y = zn si z i z i+1


pentru o = i<n .

Secventele z 0 ,z 1 , ..., z n se mai numesc pasii derivarii de lungime n. De cele

mai multe ori gramatica G se subintelege din context si notam x y si

x * y.

Deci x y descrie aplicarea unei productii ca regula de retranscriere

intr-o secventa de simboluri x si x * y descrie un numar arbitrar de astfel

de pasi de retranscriere. Se observa ca sunt permise derivarile triviale in

zero pasi. Deoarece partea stanga a unei productii contine cel putin un

neterminal, cand se obtine o secventa de terminale, retranscrierile trebuei

sa se opreasca - de aici s-a ales nedeterminarea de ”terminal”. Putem avea

si cazul in care nu mai putem face retranscrieri, desi mai avem nedetermi-

nale, daca ele nu se potrivesc cu partea stanga a nici unei productii.

Definitia 4.1.3.

Pentru gramatica G =( V, ,P,S ), L(Q), limbajul definit de G, este

L (G)= {x sum * | S x} si un limbaj pentru care exista o astfel de

gramatica se numescte limbaj structural. Doua gramatici G1 si G2 sunt

echivalente daca L (G1 )= L (G2 ).

Limbajul se determina incepand cu simbolul de start al gramaticii si

209
aplicand rescrierea pana cand nu mai raman meta-simboluri, iar multimea

secventilor ce se pot obtine in acest mod constituie limbajul. Se observa ca

procesul de retranscriere este permisiu de obicei exista numeroase optiuni

pentru retranscriere. Suntem obligati sa consideram toare alternativele

posibile de retranscriere pentru a determinalimbajul. Acest lucru introduce

o forma de nedeterminism care se combina cu repetarile pasilor individuali

de retranscriere pentru a forma o multime de posibile iesiri uneori greu de

determinat.

In particula, daca avem un string candidat, poate fi dificil de a at

daca este printre secventele descrise prin reguli pecare gramatica le asigura

pentru descrierea limbajului. Vom trata aceasta problema in detaliu mai

tarziu.

Exemplul 4.1.1.

Consideram G unde V = {S} , = {a, b} si P = {S aSb, S ab} .

Atunci pentru derivari avem o multime de doua ori infinita de posibilitati:

S aSb aaSbb ...

ab aabb aaabbb

deoarece exista doua posibilitati de retranscriere la fiecare pas, una pentru

fiecare productie a lui S. Productia care il elimina pe S incheie retran-

scrierea si cealalta insereaza un S care contine pe S in secventa derivata se

adauga un ’a’ si un ’b’, si deoarece aceasta productie poate fi folosita de

210
oricate ori, pentru fiecare n = 1avem S a n bn . Deci

L (G)= {a n bn | n = 1}.

Desi acest prim exemplu este o gramatica foarte simpla, am vazut ca

acest mecanism are capacitatea de a descrie usor limbaje care nu sunt regu-

late. Mai tarziu in acest capitol vom arata ca toate limbajele regulate pot fi

descrise de gramatici simple, astfel incat avem intr-adevar mijloace mai ex-

presive de descriere a limbajelor decat cele din Partea I. Cand avem cateva

productii cu acelasi membru stang, preferam deseori sa evitam repetarea

lui in scrierea productiilor. Vom adopta o conventie folosita in definitia

BNF a limbajelor de programare. In loc de doua productii in Exemplu

4.1.1. , vom scrie S aSb | ab . Bara verticala ”—” se citeste ”sau” si

poate fi folosita in mod repetat pentru a scrie mai multe alternative pentru

membrul drept ca ordinea in care sunt scrisi membrul drept.

Clasificam productiile in concordanta cu simbolurile care apar in struc-

tura lor si clasificam gramaticile dupa forma cea mai generala a producti-

ilor. Aceasta ne va conduce la numeroase familii de gramatici. Acum ne

concentram atentia asupra a ceea ce urmeaza.

Definitia 4.1.4.

O productie a ß a gramaticii G =( V, ,P,S ) se numeste indepen-

denta de context daca a U . Gramatica G este independenta de context

daca toate productiile ei sunt independente de context.

De exemplu, gramatica din Exemplu 4.1.1 este independenta de con-

211
text. Aceasta conditie este cea mai restrictiva care se poate pune asupra

membrului stang al unei productii, deoarece trebuie sa contina cel putin

un neterminal. Nu ne vom putea da seama de efectul acestei restrictii pana

in Partea a III-a. Oricum, ea are un efect de simplificare asupra analizei

gramaticilor si derivatelor lor.

Gramatica din Exemplul 4.1.1 este un exemplu simplu a unei gramatici

independente de context. Pentru moment, retinem acest exemplu relativ

simplu, dar complicatiile vor aparea cat de curand.

Exemplu 4.1.2.

Consideram G, unde V = {S, T}, = { 0, 1} , simbolul initial este S si

productiile sunt:

S 0S 0 | T

T e| 1T 0

Pentru derivarile care pornesc din S, prima productie pentru S poate fi

aplicata in mod repetat si intr-un numar oarecare si apoi a doua productie,

ducand la

S 0S 0 00S 00 ... 0p S 0p 0p To p , unde p = 0.

In acest punct derivarile continua cu rscrierea lui T. Cand prima produc-

tie este aleasa pentru T, derivarile se termina cu o secventa a limbajului.

Pana atunci se poate aplica derivarea repetata cu a doua productie a lui

T de un numar de ori. De aceea,

0p T 0p o p 1T 0p+1 o p 11T 0p+2 ... o p 1q 0p+ q .

212
Deci pentru orice p, q = 0,S 0p 1q 0p+ q si aceste secvente constitue

L(G).

Acesta este un alt exemplu simplu de gramatica independenta de context

- nu numai ca membrul stang contine un singur nedeterminal, dar partea

dreapta a fiecarei productii contine cel mult un nedeterminal si deci pasii

de derivare contin excat un nedeterminal care trebuie retranscris pana la

sfarsit. Am obtinut din nou, totusi un limbaj neregulat.

Cititorul nu ar trebui sa faca presupunerea ca orice gramatica inde-

pendenta de context genereaza intotdeauna un limbaj neregulat. De fapt,

toate limbajele regulate pot fi descrise folosind gramaticile independente de

context-acest aspect il vom trata in Sectiunea 4.4. Acum dam un exemplu

arata acest lucur.

Exemplu 4.1.3.

Inacest exemplu vom ilustra o descriere cu ajutorul unei gramatici a unui

limbaj regulat, µ((01 * ) * ). Consideram neterminalele {S, T} si productiiile

S e| 0T

T 1T | S

Desi gramatica este liniara, independenta de context, derivarile sunt un

pic complicate, deoarece retranscrierea lui S il poate introduce pe T si

retranscrierea lui T il poate introduce pe S. Dar nu e dificil sa aranjam

aceste posibilitati.

Presupunem ca o derivare nu il retranscrie niciodata pe S prin T. Atunci

S e L (G).

213
Presupunem ca o derivare il retranscrie o singura data pe S prin T.

Atunci S 01T 011T ... 01p T 01p S 01p L ( G),p= 0

Presupunem ca o derivare il retrranscrie de doua ori pe S prin T. Atunci

S 01 T 011T ... 01p T 01p S 01p 0T 01p 01T 01p 011T

... 01p 01q T 01p 01q S 01p 01q L (G) ,p,q= 0. etc

Nu vom urma detaliile formale ale analizei prin inductie a acestor derivari,

dar modelul ar trebui sa fie clar numarul de folosiri al productiei S 0T

corespunde numarului de grupuri 01 *, iar numarul de folosiri ar productiei

T 1T de fiecare data cand T este reintrodus, determina numarul de ’1’

din grupul respectiv.

Inainte de a considera alte exemple, vom da o proprietate de baza a

gramatecilor independente de context care le distinge de celelalte. Propri-

etatea justifica si denumirea lor.

Teorema 4.1.1.

Pentru o gramatica independenta de context, G =( V, P,S ), pre-

supunem ca w = 1 2
... k
, unde k= 1si i
(V ), 1 = i = k si

w x . Atunci exista xi (V )* , 1 = i = k ,astfelˆincˆ at x = x1 x 2 ...x n

si i
x i
, pentru i =1 , 2, ...k .

Demonstratie.

Demonstratia se face prin inductie in raport cu lungimea derivarii lui x.

Etapa de verificare: lungimea derivarii lui x este 0. In acest caz,

w = x , deci luam xi = i
, 1 =i=k .

Etapa de demonstrare :

214
Presupunem ca rezultatul are loc pentru toate derivarile de n = 0pasi

si consideram al ( n +1) - lea pas de derivare 1 2


... k
x . Presupunem

ca aceasta derivare il retranscrie prima data pe m


sa zicem: 1
, 2
... k

1 2
... m- 1 1 2
... p m +1 m +2
... k
. Ipoteza inductiei se aplica acum pen-

tru ultimii n pasi ai acestei derivari, deic exista x 1 ,x 2 ..., x m- 1


,x m +1
..., x k ,y 1 ,y 2 , ..., y p

astfel incat i
x i
pentru i =1 , 2, ...m - 1,m +1 , ...k si i
y i
, pentru

i=1, 2, . . . , p si x = x 1 x 2 ...x m ,y 1 y2 ...y p x m +1 ...x k . Dar atunci luam

x m = y1 y2 ...y p si m 1 2
... p
x m
si inductia este extinsa.

Teorema 4.1.1 implica faptul ca fiecare derivare pentru o secventa de

simboluri consta in derivari separate pentru fiecare simbol al secventei este

sensul ”independentei de context” a retranscrieriilor - nu exista interactiune

intre rescrierea instantelor adiacente de nedeterminale in cele mai largi

scheme ale retranscrierii, fiecare neterminal poate fi privit ca retranscriidu-

se independent. Bineinteles, o derivare poate sa ”sara” rescriind intai din

secventa si apoi alta. Ideea este ca retranscrierea facuta intr-o pozitie nu

interactioneaza cu retrranscrierea facuta in alta pozitie.

Exemplul 4.1.4.

Consideram gramatica cu V = {S, B}, = {a, b} , P = {S aSB, S

e, B bB, B e} si axioma S. In baza observatiilor facute vom scrie pro-

ductiile. S aSB | e . Acestea sunt independete de context, deci G

este independeta de context. Pentru derivari avem mai multe posibilitati,

deoarece fiecare retranscriere a lui S poate introduce pe B, ceea ce adauga

posibilitati de alegere ulterioare. De exemplu,

215
S aSB aaSBB aaSbBB,

S aSB aaSBB aaSBbB,

S aSB aaSBB aaSB,

S aSB aaSBB aaBB .

Derivarile in cazul acestei gramatici sunt mai complexe decat in exem-

plele anterioare deoarece pot aparea mai multe nedeterminale intr-un pas

al unei derivari si fiacare din ele poate fi selectata pentru retranscrieri ulte-

rioare. Conform Teoremei 4.1.1., in considerearea retranscrierilor secven-

tiale precum aaSBB putem considera derivari ulterioare ale fiecarui simbol

in parte. Derivarile pentru B sunt simple: B bB bbB ...b k ,k =

0. Adica B x * daca si numai daca x µ ( b* ). Dar atunci

aaSBB aaSb p bq , p, q = 0 si retranscrieri ulterioae ale lui S il pot

elimina sau pot introduce ’a’-uri si ’B’-uri aditionale. Observa deci ca

L (G)= {a n ( b* )n | n = 0} ; acestea sunt secvente de ’a’-uri urmate de

grupuri de’b’-uri, unde numarul frupurilor este egal cu numarul ’a’-urilor

si fiecare grup are un numar arbitrar de ’b’-uri. Cu putina atentie se ob-

serva ca limbajul este acelasi cu limbajul µ( e + aa* b* ) si cititor ar putea

verifica daca toate acestea secvente si numai ele pot fi derivate din gramat-

ica.

Cheia realizarii unei intelegeri a gramaticilor este buna intelegere a pro-

cesului de derivare. Desi fiecare pas al unei retranscrieri este o simpla

inlocuire de simboluri, numeroasele optiuni pot sa faca procesul neclar. In

continuarea acestei sectiuni vom face simplificari care sa ne ajute sa inde-

216
partam complicatiile procedeului de derivare. In Partea I am vazut ca se

poateca un automat de acceptare sa continua stari care sa nu contribuie

cu nimic la limbajul necunoscut de automat si am prezentat modalitati

de indepartare a acestor stari. Pentru gramatici pot de asemenea exista

componente fara folos si vom prezenta acum gramaticile independente de

context.

Definitia 4.1.5. Fie G =( V, ,P,S ) o gramatica independenta de

context. Un simbol X (V ) este accesibil daca S aSß pentru

a, ß (V )* ; in caz contrar x este inaccesibil. Un simbol X V este

productiv daca x w , unde w *; in caz contrar x se numeste nepro-

ductiv. Un simbol x (V ) este simbol parazit daca este inaccesibil

sau neproductiv.

Deoarece la determinarea unui limbaj descris de o gramatica consideram

numai derivarile care pornesc de la axioma S, simbolurile inaccesabile si

productiile lor nu contribuie cu nimic la descriere. Mai mult, aparitia

unui neterminal neproductiv va garanta o derivare nu contribuie cu nici o

secventa la L(G) chiar daca neterminalul este accesibil. Desi simbolurile

parazite sunt nefolositoare la descrierea unui limbaj, ele nu sunt interzice

. Dupa cum vom vedea mai tarziu, unele demonstratii vor fi mai usoare

daca ne concentram pe obtinerea unei gramatici corecte. Daca stim ca

inlaturam aceste simboluri va fi suficient.

Exemplul 4.1.5.

Consdieram gramatica independenta de context G, cu neterminalele

217
{S, A, B, C} , axioma S si productiile

S bb | aB

a | Aa

bB | Ba | AB

ba | aA | Bb | aCb

Pentru aceasta gramatica, C este inaccesibil deoarece nu exista derivari

incepand de la S care sa introduca vreo operatie a lui C. DE asemenea

B este neproductiv, deoarece ori de cate ori este introdus intr-o derivare,

rescrierea ulterioara a lui B va produce o alta aparitie a lui B, facand

imposibila generarea de secvente de terminale. Desi A este atat productiv

cat si accesibil, nu contribuie cu nimic la limbaj, deoarece apare numai in

legatura cu B. Neterminabile cu caracteristicile lui A sunt imposibile sa

exsite intr-o gramatica fara simboluri parazit, deoarece un alt neterminal

neproductiv trebuie sa existe pentru a crea, astfel de situatie.

Vom avea cum toate simbolurile neproductive si productiile lor pot fi

eliminate in mmod sigur din orice gramatica independeta de context. Ur-

matoarele doua rezultate asigura o schita formata pentru procesul de elim-

inare a acestor simboluri.

Teorema 4.1.2.

Pentru orice gramatica independenta de context G =( V, ,P,S )cu

L (G) = Ø, exista G =( V , ,P ,S )astfelincat L (G )= L ( G),V

V,P P si G’ nu contine simboluri neproductive.

Demonstratie.

218
Prima data definim inductiv o serie de multimi de neterminale ale lui

G dupa cum urmeaza: luam V0 = {S V | x w P si w *} si

pentru i = 0, definim Vi+1 = Vi {x V | x w P si w ( Vi , )* } .


8
Definim apoi V = si P = {x w P | x V si w (V )* } .
i =1
Afirmatie.

V este multimea tuturor simbolurilor productive ale lui G si pentru

x V,x y * daca si numai daca x y .

Demonstratia afirmatiei

Fiecare neterminal x V trebuie sa apartina unui Vi . Demonstrarea

faptului ca fiecare neterminal x V este productiv se face prin inductie

dupa cel mai mic index i astfel incat x V i


.Daca x V 0
, atunci evident

x e productiv; daca presupunem si x V i +1


, atunci toate neterminalele

din Vi sunt productive si x V i+1


, atunci exista o productie x w si

w ( Vi ) * deci din ipoteza inductiei, toate simbolurile din w deriva

intr-o secventa de terminale si deci si x - omitem detaliile ulterioare.

Pentru a arata ca fiecare neterminal productiv al lui G apartine lui V ,

argumentam prin inductie dupa lungimea celei mai scurte derivari de la x

la o secventa de terminale. Daca x are un singur pas de derivare, atunci

x V 0
si deci x V . Daca toate neterminalele cu n sau mai putini pasi

de derivare intr-o secventa de terminale apartine lui V , consideram un

neterminal cu n+1 de derivare, sa zicem x 1 2


... k
y *. Atunci

din Teorema 4.1.1, y = y1 ...y k ,sidaca ; este neterminal , atunci i


y i

printr-o derivare cu n sau mai putini pasi. Deci din ipoteza inductiei,

219
i
V . Atunci fiecare astfel de neterminal trebuie sa apartina uneia din

multimile din reuniunea care defineste V sa zicem VM si daca M e maximul

dintre indicii neterminalelor, atunci toate neterminale apartin de asemenea

lui VM . De aceea productia x 1 2


... k
in P stabileste ca x V M +1
si

deci x V .

Deoarece L (G) = Ø, simbolul de start S e productiv si deci S V .

Evident avem L(G ) L ( G) deoarece P P si deci orice retranscriere in

G poate fi deasemenea facuta in G. Reciproc, un pas din derivarea unei

secvente de terminale in G poate sa nu introduca nici un simbol reproductiv

si deci productia folosita apartine de asemenea lui G si avem L ( G)

L (G ). Deci L ( G )= L (G ) si teorema e demonstrata.

In demonstratia Teoremei 4.1.2 am definit un sir infinit de multimi V0

V1 ... V i
V i +1
... . Deoarece multimea termenilor este finita, aceste

multimi nu pot continua sa creasca la infinit. Eventual trebuie sa existe

un k astfel incat Vk = Vk +1 . Daca gramatica are N neterminale, atunci

repetitia poate sa apara cel tarziu la k=N-1. Odata ce o astfel de repetitie

apare, schimbarile subsecventionale sunt imposibile deoarece definitiile si

egalitatea Vk = Vk +1 implica

Vk +2 = Vk +1 {x V | x w P si w ( Vk +1 )* } =

= Vk {x V | x w P si w ( Vk )* } =

= Vk +1

Prin analize similare se observa ca Vk = Vk +1 = Vk +2 = ... = Vk + i =

... pentru i=1, 2, 3, . . . De aceea, de fapt V este o reuniune finita

220
N- 1
V = Vi = VN - 1 . Desi nu am dat o formulare explicita, ar trebui sa
i=0
fie clar ca am dezvoltat pasii esentiali ai unui algoritm care sa simplifice

gramatica G.

Vom arata in continuare cum se elimina simbolurile inaccesibile fara

introducerea neterminalelor neproductive si de aici sa obtinem o gramatica

fara simboluri parazite.

Teorema 4.1.3.

Pentru orice gramatica independenta de context G =( V, ,P,S )cu

L (G) = Ø, exista G =( V , ,P ,S )astfelincat L (G)= L (G ),

,V V,P P si G nu are simboluri neproductive si simboluri inac-

cesibile:

Demonstratie.

Din Teorema 4.1.2 putem presupune ca G nu are neterminale nepro-

ductive. Prima data definim un sir de multimi de simboluri R 0 = {S} si

pentru i = 0, R i+1 = R i {t (V ) |, x R i
si a, ß (V )* cu

x a ß P} .
8 8
Fie V = Ri nV , Ri n si P acele productii ale lui P
i =0 i=0
care contin numai simboluri din V .

Afirmatia 1.

V este exact multimea simbolurilor accesibile ale lui G.

Demonstratie.

Demonstratia ca fiecare simbol s (V ) este accesibil se face prin

221
inductie dupa cel mai mic index i astfel incat s R i
. Pentru i=0, acest

lucru este adevarat in mod trivial. Daca toate simbolurile lui R n sunt

accesibile si s R n +1
, atunci avem fie s R n
si deci s e accesibila, fie

exista x R n
si aß (V ) * ,cu x atß P . Dar in ultimul caz,

deoarece x R n
,x este accesibil si deci S w 1
×w2 w 1
aßw 2
si s ese

accesibil.

Demonstratia ca fiecare simbol accesibil s al lui G apartine lui V

se face prin inductie in raport cu lungimea celei mai scurte derivari prin

care se obtine s . Acest lucru este analog cu demonstratia din Teorema

4.1.2. si este omis aici.

Afirmatia 2.

Stergerea simbolurilor inaccesibile si a productiilor lor nu creaza neter-

minale neproductive in G.

Demonstratie.

Se observa ca daca x este neterminal accesibil si X w * in G,

atunci fiecare simbol introdus in aceasta derivare este de asemenea accesibil

si deci nu e sters. Deci x este inca in G.

Afirmatia 3. L (G )= L (G)

Demonstratie.

Deoarece P P , fiecare derivare din B este o derivare din G si deci

L (G ) L ( G). Invers, daca S w *, atunci fiecare simbol introdus

in derivare este accesibil si deic toate productiile sunt retinjute in G , deci

L (G) L ( G ). Deci L (G )= L (G).

222
Aceasta completeaza demonstratia teoremei.

Din nou in demonstratia Teoremei 4.1.3. am definit din sir de multimi

R0 R 1
R 2
... R i
R i +1
... . De aici analiza pe care am facut-o

dupa demonstratia Teoremei 4.1.2. poate fi repetata si avem efectiv un

algoritm de eliminare a simbolurilor parazite.

Exemplul 4.1.6.

Acest exemplu ilustreaza aplicarea ”algortimului” de eliminarea a sim-

bolurilor parazite din gramatica independenta de context din Exemplul

4.1.5. Productiile acestei gramatici erau:

S bb | aB

A a | Aa

B bB | Ba | AB

Cba | aA | Bb | aCb .

Primul pas este de a descoperi si de a elimina neterminalele neproduc-

tive. Pana aici determinam V0 = {S, A, C} = V1 = V . Noua gramatica

are numai aceste neterminale si productiile care le contin pe acestea. Adica

G =( {S, A, C}, {a, b} ; S, {S bb, A a | Aa, C ba | aA | aCb} ).

Al doilea pas este de a aplica procesul de stergere a simbolurilor in-

accesibile din B . Pentru a realiza acest lucru, determinam R 0 = {S} ,

R 1 = {S, b} si R 2 = R 1 . Apoi inlaturam din G tot ce contine celelalte

simboluri. Aceasta ne duce la rezultatul final G ( {S}, {b},S,{S bb} )

si L ( G )= L (G ) si deci am construit o descriere mai simpla a limbajului

223
decat gramatica originala.

Daca aceste doua simplificari sunt facute in ordine inversa este posibil

ca inlaturarea variabilelor neproductive sa introduca simboluri inaccesibile

in locuri unde nu au existat inainte. De aici rezulta ca, pentru a satisface

afirmatia Teoremei 4.1.3, este important sa observam ordinea indicata. Se

observa de asemenea ca aceste rezultate nu au loc pentru limbajul Ø unde

simbolul de strat al gramaticii ar trebui sa fie parazit.

In aceasta sectiune am format conceptele de baza ale retranscrierilor

gramaticelor. Operatia de baza este simpla inlocuire. Este important sa

ne familizarizam complet cu aceste notiuni deoarece chiar si atunci este

greu sa stapanim impactul complet al capacitatii descriptive care este val-

abila universala a gramaticilor independente de context pe care ne vom

baza de acum in colo. Am prezentat de asemenea analize care ne permite

sa identificam si sa eliminam componentele parazite ale gramaticilor inde-

pendentedecontext.

4.2. Arbori de derivare si ambiguitate

Unul din principalele motive pentru folosirea gramaticilor independente

de context este ca ele nu numai ca ofera o descriere precisa a multimilor

de secventa, dar asociaza o structura ierarhica pentru fiecare secventa a

limbajului. Aceasta structura este vitala pentru multe aplicatii ale acestui

mecanism. Pentru determinarea secventei din limbaj care a fost produsa in

urma unei derivari, derivarea contine in mod normal mai multe informatii

224
decat este necesar. Deci putem face intelegerea gramaticilor independente

de context prin adoptarea unui punct de vedere abstract care ignora de-

taliile inutile ale derivarilor. Arborele structura importanta asociata cu

secventa derivata.

4.2.1.

Fiind data o gramatica independenta de context G =( V, ,P,S )sio

derivare A 1 2
... k
w , A v si i
(V ), 1 = i = k , exista un

arbore de derivare asociat care este un arbore etichetat, orientat si definit

inductiv astfel:

i. exista un mod radacina etichetat cu A

ii. exista k noduri fii si al i-lea nod fiu (1 = i = k )este etichetat cu i

iii. un nod fiu etichetat cu i


este un nod terminal daca derivarea core-

spunzatoare lui are lungimea 0.

iv. un mod fiu etichetat cu i


v este un nod radacina pentru subar-

borele care e arbore de derivare pentru i


x i
, daca derivarea aceasta are

lungime mai mare ca 0.

Desi definitia formala a unui arbore de derivare este impozanta, exista

o intuitie puternica pentru aceasta idee. De fapt este usor de inteles. Vom

considera numeroase exemple ce vor clarifica acaesta notiune pe masura ce

o vom dezvolta.

Exemplul 4.2.1.

Pentru gramatica independenta de context din Exemplul 4.1.4 aveam

productiile S aSB | e, B bB | e .

225
Pentru aceasta gramatica, derivarea S aSB aaSBB aaSBbB

are ca si corespondent urmatorul arbore de derivare

Figura 4.1.

Fiecare din cei trei pasi ai derivarii corespund unui nod neterminal al

arborelui. Retranscrierile obiectelor de acelasi fel apar sub forma de de-

scendenti in arbore. Ordinea retranscrierilor obiectelor care nu sunt de

acelasi fel nu este re ectata in arbore. Aceasta inseamna ca daca con-

sideram derivarea S aSB aSbB aaSBbB obtinem exact acelasi

arbore de derivare! Aceasta informatie descrisa in arborele de derivare

ilustreaza faptul ca aceste doua derivari aparent diferite produc acelasi

rezultat, ele reprezinta aceasi derivare. Aceasta inseamna ca ele amandoua

retranscriu acelasi simboluri cu aceleasi reguli si numai ordinea irelevanta

pentru iesire , le distinge. Se observa ca secventa derivata se citeste de pe

frontiera arborelui .

Din feicare chiar si acest exemplu face ca ideea de arbore de derivare sa

fie naturala si intuitiva. Este dificil de descris arbori de derivare atat in

maniera intuitiva cat si succinta, dar este vital pentru cititot sa se acomod-

226
eze cu acest concept. Fiecare derivare are un arbore de derivare corespun-

zator. Fiecare aparitie a unui simbol in derivare are un nod corespunzator

in arborele de derivare, simbolului de strat fiindu-i asociata radacina ar-

borelui. Simbolurile neterminale corespund nodurilor din care se formeaza

subarbori, iar terminalele corespund nodurilor ”frunza”. Nodurile fii ale

unui nod din care porneste un subarbore sunt acelea asociate cu simbolurile

introduse de partea dreapta a productiei folosite in retranscrierea corespun-

zatoare.

Dupa cum am vazut din exemplul precedent, exista o corespondenta

n:1 intre derivari si arbori de derivare. Un arbore de derivare nu ne per-

mite sa regasim o unica derivare din care sa format. Oricum, informa-

tia care s-a eliminat este neesentiala pentru scopul determinarii secven-

tilor derivate. Deoarece scopul nostru in folosirea unei gramatici este de

a determina secventele derivate, arborii de derivare ofera o abstractizare

a produsului de derivare prin care mi se fixeaza mai bine atentia asupra

acestui aspect. Pentru a realiza acelasi scop folosind abordarea derivarilor

liniare, ne vom referi la derivarea cea mai de stanga - aceasta sunt derivari

in care intotdeauna este retranscris neterminalul cel mai din stanga. In

acest fel inlocuim inlaturarea ordinii neesentiale din aceste descrieri prin

alegerea unei rodini canonice reprezintativa pentru toate derivarile. Evi-

dent, diferite derivari cele mai de stanga corespund la arbori de observare

diferiti.

Intr-o derivare A 1 2
... k
w , dupa cum am vazut in Teorema 4.1.1,

227
retranscrierea fiecarui i
se face independent de celelalte. Oridinea acestor

retranscrieri nu e importanta pentru secventa care e generata, dar pasii

derivarii retin ordinea ca parte integrala. In arborele de derivare oridinea

este indepartata si se retine numai productia care se aplica fiecarui neter-

minal - aceasta este informatia esentiala pentru determinarea secventei

derivate. Evident retranscrierea lui A trebuie sa preceada retranscrierea

lui i
,1 = i = k . Retranscrierile se fac intr-o anumita ordine si acest lucru

se re ecta in arborele de derivare din structura de subarbore. De asemenea,

frontierea arborelui de derivare ( adica secventa de etichete ale nodurilor

”frunza” in ordinea stanga-dreapta in jurul arborelui - vezi Capitolul 0)

este chiar secventa derivata. Urmatorul rezultat formalizeaza aceste pro-

prietati:

Teorema 4.2.1.

Fei G o gramatica independenta de context, G =( V, ,P,S ),A V

si consideram derivarea A 1 2
... k
x , unde i
V (1 = i =

k ) al carei arbor de derivare este t . Atunci frontiera ( t )= x si fiecare

exemplificare a unei variabile v retranscrisa in derivare este eticheta unui

mod care e radacina a unei subarbore pentru subderivarile sale.

Demonstratie.

Din Teorema 4.1.1. avem ca x = x 1 x 2 ...x k si i


x i
, pentru i=1, 2, . .

. , k. Presupunem ca t i este arborele de derivare pentru i


x i
. Atunci

t este arborele

228
Figura 4.2.

Frontiera lui t reprezinta concatenarea frontierilor subarborilor sai, ad-

ica x = frontiera ( t ) =frontiera( t 1 ) frontiera( t 2 )...frntiera( tk )

= x 1 x 2 ...x k . De asemenea fiecare aparitie a unui terminal fie este eticheta

nodului radacina, fie apare in subarborele unde este derivat. Lungimea

drumului de la radacina la un nod egala cu lungimea retranscrierii neter-

minalului ce eticheteaza acel nod.

Arborii de derivare ofera o organizare ierarhica pentru structura secven-

tilor. Exista doua strategii uzuale de a are a anumitor lucruri despre gra-

maticile independente de context si ambele se bazeaza pe analiza derivar-

ilor. O abordare pe care am vazut-o deja (Ex: in demonstrarea Teoremei

4.1.1.) foloseste inductia dupa lungimea derivarii. O alta abordare , pe

care suntem pregatiti sa o folosim este inductia in raport cu adancimea

arborelui de derivare. Din moment ce adancimea arborelui de derivare re-

ecta lungimea retranscrierii , acaesta modalitate de organizare poate fi

folositoare.

Definitia 4.2.2.

O gramatica independenta de context G este ambigua daca exista x

229
L (G) cu doi arbori de derivare distincti (sau echivalent, cu doua derivari

de stanga diferite).

Demonstratia ca o gramatica este ambigua este relativ usoara dintr-

un punct de vedere. Nu trebuie sa determinam care sunt toate secventile

limbajului, ci doar sa gasim o secventa in limbaj pentru care sa avem doi

arbori de derivare diferiti.

Exemplul 4.2.2.

Consideram din nou gramatica din Exemplul 4.1.4 cu productiile S

aSB | e, B bB | e . Am observat in Exemplul 4.2.1. ca aceasta gra-

matica admite doua derivari care duc la acelasi rezultat, dar acestea au

constituit ”una si aceeasi” derivare, adica au acelasi arbore de derivare.

De fapt acaesta gramatica admite de asemenea derivari foarte diferite, care

duc la acelasi rezultat si aceasta inseamna ca este ambigua. De exemplu,

consideram secventa aab L ( G). Aceasta secventa are urmatoarele doua

derivari de stanga distincte:

S aSB aaSBB aBB aabBB aabB aab

si

S aSB aaSBB aaBB aaB aab.

Aceste doua derivari corspund respectiv arborilor de derivare distinctii

de mai jos - aceste doua derivari nu retranscriem aceleasi simboluri cu

aceleasi reguli. Gramatica asociaza doua structuri diferite secventei aab.

230
Figura 4.3.

si

Figura 4.4.

O perspectiva mai exacta asupra ambiguitatii este aceea ca gasirea unei

secvente cu doi arbori de derivare poate fi dificil. Unul din rezultatele din

Partea a III-a arata ca nu exista algortim pentru acaesta determinare.

231
Pe de alta parte, daca am determinat ca o gramatica nu este ambigua,

atunci demonstratia este o sarcita si mai dificila. Trebuie sa aratam ca

fiecare secventa a limbajului are un singur arbore de derivare. Acest lucru

cere nu nuami sa cunoastem toate secventele limbajului ci si sa argumentam

unicitatea derivarii pentru fiecare secventa!

Este important de retinut ca ambiguitatea este o proprietate a descrierii,

nu a limbajului descris! Aceasta inseamna ca putem avea atat o gramatica

ambigua, cat si una care nu este ambigua putem acelasi limbaj. Vom ilustra

acest lucru dand un exemplu de gramatica ce nu este o ambigua pentru

acelasi limbaj definit de gramatica ambigua din exemplul 4.2.2.

Exemplul 4.2.3.

Am observat in Exemplul 4.1.4 ca limbajul generat de gramatica G

analizata in Exemplul 4.2.2 este µ(e + aa * b* )

Consideram gramatica alternativa G cu productiile S e | aS |

aB, B b | bB . Ar trebui sa fie clar ca L ( G )= L ( G). Pentru vedea ca G

nu este ambigua, trebuie sa aratam ca fiecare secventa ap bq L (G ),p,q=

0 admite o singura derivare de stanga. Se observa ca toate derivarile din G

sunt de stanga, deoarece intr-o derivare ce porneste de la S nu exista mai

mult de un neterminal. O derivare in G alui ap bq este unic determinata

de p si q. Singurul mod de a introduce ’a’-uri este de a folosi productiile

S aS si S aB .Daca q = 0, trebuie sa folosim S aS de p ori si apoi

S e .Daca q> 0, trebuie sa folosim S aS de p-1 ori apoi productia

S aB ,apoi B bB de q-1 ori si in final B b . Astfel sunt imposibile

232
doua derivari diferite pentru aceleasi secventa si deci gramatica G nu este

ambigua.

Deci ambiguitatea este o proprietate a definirii limbajului nu a lim-

bajului insusi. Daca avem o descriere ambigua, putem retine limbajul si

sa cautam o noua gramatica cu care sa il descriem. Din nefericire nu

este intotdeauna posibil sa gasim o gramatica ce nu este ambigua. Un

limbaj independent de context se numeste ambiguu, daca fiecare gramat-

ica independenta de context care il descrie este ambigua. Se poate pre-

supune ca astfel de limnaje sunt anormale, dar din nefericire aceste lim-

baje nu sunt nici rare nic extrem de complexe. De exemplu, limbajul

{a p bp cq dq | p, q = 1} {a p bq cq dp | p, q = 1} este un limbaj independent de

context care este absolut ambiguu.

Folosim aici termenul de ”ambiguitate” ca termen tehnic. Astfel el de-

nota o notiune sintactica ce are legatura numai cu structurile determinate

de o gramatica independenta de context. Interpretarea obisnuita a aces-

tui cuvint are legatura cu intelesul lui, in particular alocarea mai multor

intelesuri. Se arata ca conceptul pe care l-am definit aici are o legatura

mai apropiata decat pare cu intelesul informal. Ideea este ca pentru limba-

jele de programare intelesul unei constructii este mereu asociat cu intelesul

componentelor sale. Deoarece arbori de derivare diferiti asociaza unei con-

structii componente diferite, prezenta ambiguitatii sintactice duce aptoape

intotdeauna la intelesuri confuze.

Vom ilustra pe scurt acest lucru. Deoarece autorii de limbaje de progra-

233
mare fac tot posibilul sa evite ambiguitatea, exemplele din limbajele larg

raspandite sunt rare. Dar ambuitatea exista de exemplu ambiguitatea a

persitat in formularea finala a limbajului ALGOL 70, un limbaj de pro-

gramare care a folosit pentru prima data BNF. Vom discuta un exemplu

interesant din FORTRAN IV, iar cititorii nefamilizati cu acest limbaj nu

ar trebui sa intampine greutati in intelegerea exemplului . Consideram

afirmatia din FORTRAN IV urmatoarele:

10FORMAT ( X 3H )=( I 6)

Aceasta este o instructiune etichetata si poate fi interpretata in trei

moduri valide distincte. Prima data, este o instructiune FORMAT vali-

data - un mijloc pe care FORTRAN IV il ofera pentru descrierea aparitiei

iesirii tiparite. Din acest punct de vedere instructiunea este echivalenta cu

instructiunea

10FORMAT (1X, 3H )=( ,I 6)

Instructiunile FORMAT prezinta un sir de articole, informatii inchise

intre paranteze si separate de virgula, fiecare din ele descriind un anumit

aspect al aparitiei iesirii. O informatie argument nX, unde n= 1 este

un intreg, indica faptul ca trebuie sa apara n spatii, iar daca n este omis,

el este implicit. O informatie de forma nHc 1 c2 ...cn , unde n = 1 este un

intreg, iar ci (1 = i = n ) este un caracter FORTRAN indica faptul ca

secventa (Hollerith) c1 c2 ...c n trebuie ca insasi sa apara. Un argument In

indica o valoare intreaga ce ar trebui tiparita intr-un camp de latime n.

234
De asemenea, separatorul ’,’ este optional pentru acele argumente a caror

forma determina unde argumentul ar trebui sa se termine - ex: nX si

nHc 1 c2 ...c n . Deoarece spatiile sunt ignorate in FORTRAN in aproape toate

contextele, avem echivalenta de mai sus.

In al doilea rand instructiunea de mai sus, poate fi interpretata ca o in-

structiune valida de alocare. In acest caz, este echivalenta cu instructiunea

10FORMAT ( X 3H )=( I 6)

Instructiunile de alocare au forma variabila = expresii . Deoarece

cuvintele cheie din FORTRAN nu sunt rezervate ’FORMAT’ poate fi o

variabila de program si poate fi declarata ca un sir. De aceea stringul din

stanga lui ’=’ este o variabila indexata valida. De asemenea, I6 este un

identificator de variabila valid si deci (I6) este o expresie valida. Din nou

aparitia spatiilor este ignorata in FORTRAN, exceptand cateva contexte

speciale. Deci astfel a doua interpretare este si ea valida.

Se observa rolul crucial pe care il au componentele in intelegerea sensu-

lui acestei instructiuni ambigue. Daca privim componentele ca o lista de

argumente de format, vedem unul din intelesuri. Pe de alta parte, daca

privim componentele ca variabile indexate si ea expresii, avem un inteles

cu totul diferit. Dar in ambele cazuri avem in fata aceeasi secventa de

simboluri! Ideea este ca nu secventa insasi de simboluri este semnificativa

, ci structura asoiciata instructiunii si componentele acelei structuri dau

intelesul ei. De aceea dau un aspect vital folosirii lor.

235
Nu vom analiza amanuntit a treia interpretare valida, deoarece am arata

deja cum ambiguitatea in sintaza duce la confuzii de inteles intr-un lim-

baj. Programele ce contin asemenea anomalii sunt declarate nefolositoare

datorita incertitudinii pe care o ridica. Intr-o versiune a limbajului FOR-

TRAN, aceasta ambiguitate a fost eliminata prin anularea lipsei de sens

pentru n in argumentele nX ale instructiunii FORTRAN , si cererea ca 1X

sa fie folosit in loc de X. Aceasta a inlaturat problema ambiguitatii, dar

numai cu pretul sacrificarii compatibilitatii perfecte ascendente in evolutia

limbajului.

Ar fi de dorit ca, daca avem un algortim care poate fi aplicat unei

gramatici independente de context, sa determinam daca este ambigua sau

nu. Din pacate nu exista un astfel de algortim! Numai in Partea a III-a

vom niciodata determina daca acaesta proprietaea este adevarata sau nu.

Am vazut deja cazuri in care am determinat ca o gramatica este ambigua.

Aceasta afrimatie nu implica faptul ca trebuie sa consideram fiecare caz in

parte si sa folosim caracteristicile specifice fiecarei gramatici - nici o metoda

uniforma nu poate fi corect aplicata tuturor gramaticilor independente de

context.

In sectiunile urmatoare vom vedea ca arborii de derivare nu sunt numai

critici in aplicatiile gramaticilor independente de context ci constituie si un

instrument vital de analiza in intelegerea mai buna a procesului de derivare.

4.3. Gramatici in forme normale

236
Anumite caracteristici tehnice ale gramaticilor pot deranja in anumite

contexte. Cateva astfel de caracteristici pot fi inlaturate din gramaticile

independente de context transformand gramatica in alta mai potrivita,

echivalenta cu cea initiala. In aceasta sectiune vom prezenta cateva trans-

formati care ne vor fi de folos mai tarziu.

Definitia 4.3.1.

O productie a ß se numeste productie de stergere, daca len ( ß ) <

len ( a ). Pnetru cazurile independente de context aceste productii iau in

mod necesar forma A e pentru un neterminal oarecare A.

Productiile de stergere pot facilita caracterul succint si claritatea gra-

maticii. In contextul analizei de mai tarziu ele pot introduce un grad mai

mare de dificultate. De asemenea, dupa cum vom vedea in Partea III-a

a aceastei carti, in cazul gramaticilor dependente de context regulile de

stergere pot avea un efect enorm asupra puterii descritive. Oricum, pentru

gramaticile independete de context, regulele de stergere pot fi interzise fara

a duce la pierderea capacitatii expresive. Bineinteles, deoarece simbolul de

start are lungimea 1, fara reguli de stergere secventa mai scurta e nu poate

fi derivata. Urmatoarea teorema arata ca acaesta singura secventa este

singura pierdere ce trebuie rezolvata.

Teorema 4.3.1.

Daca L este un limbaj independent de context, atunci exista o gramatica

independenta de context G fara reguli de stergerea asfel incat L(G)=L- {e} .

Daca L = f si L = {e} , G poate fi aleasa astfel incat sa nu aiba simboluri

237
parazite.

Demonstratie.

Deoarece L este independent de context, exista o gramatica indepen-

denta de context G =( V, ,P ,S ) astfel incat L=L(G). Din Teorema

4.1.3, fara a se pierde generalitatea, putem presupune fie ca L = f si nu

cerem sa existe nici o productie, fie ca G nu are simboluri parazite. Deci

putem presupune ca G nu are simboluri parazite. Daca G nu are reguli de

stergere, demonstratia e incheiata. Daca G are reguli de stergere, deter-

minam mai intai toate neterminalele care pot fi sterse. Definim inductiv:

E 1 = {A V | A e P } si pentru i = 1,
8
E i+1 = E i {A V | A a P si a E * }. Atunci E = E i si
i
i=1
G =( V, ,P,S ), unde P se determina din P dupa cum urmeaza:

• fiecare regula de stergere din P este eliminata si

• fiecare regula care nu e stergere. A 1


,xi 2 ... k
P , i
V

(1 = i = k ) este inlocuita cu multimea tuturor productiilor de forma

A a 1
a 2 ...a k P, unde a 1 a 2 ...a k = e si avem fi a i = i
,fie a i = e cu

i
E (1 = i = k ).

Se observa ca pentru multimile de neterminale de stergere au loc incluzi-

uninile: E 1 E 2
E 3
... Neterminalele din E k sunt acelea cu o derivare

de stergere al carei arbore de derivare are inaltimea mai mica sau egala cu

k. Dupa cum am mai argumentat in situatii similare, deoarece poate exista

un numar finit de neterminale, sa zicem N, aceste incluziuni de multimi nu


8 N
pot continua la infinit. De fapt avem E = Ei = E i = EN .
i =1 i=1

238
Afirmatia 1.

E este formata din toate neterminalele A V cu A e si numai din

acestea.

Demonstratie.

Evident, daca A E , atunci A e . Invers, daca A e , demonstratia

se face prin inductie dupa inaltimea arborelui de derivare al derivariide

stergere. Evident, pentru inaltimea 1, neterminalele se gasesc in E1 E .

Definirea multimilor E i +1 permite ca inductia sa fie usor extinsa:

Afirmatia 2

L ( G)= L (G ) -{e} , concret, pentru fiecare A V si x * cu x = e,

A x daca si numai daca A x .

Demonstratie.

Diferenta intre productiile celor doua gramatici este ca in P regulile de

stergere sunt omise, si pot lipsi simboluri care pot fi sterse cu P Astfel orice

pas de retranscriere cu P poate fi simulat printr-un pas corespunzator in

P plus derivarile de stergere dupa cum este nevoie. Deci evident L ( G )=

L (G ) -{e} .

Invers, regulele de stergere din P lipsesc in P. Pentru a vedea ca orice

derivare in P ce implica stergerea pot fi simulate in P, folosim un argument

inductiv in raport cu numarul de pasi din P . Pentru etapa de verificare,

daca A x , atunci A x P si deoarece x = e, A x P si deci

A x . Pentru etapa de demonstrare, presupuenm ca Afrimatia 2 este

adevarata pentru toate derivarile cu n sau mai putini pasi si consideram al

239
(n+1)-lea pas de derivare din P , A 1 2
... k
x . Din Teorema 4.1.1,

x = x 1 ,x 2 ...x k si i
x i
(1 = i = k ). Daca x i = e din ipoteza induxtiei

i
x i
si daca x i = e, atunci avem in P o productie corspunzatoare lui

A 1 2
... k
, in care este omis i
. Deci inductia este extinsa si Afrimatia

2 este demonstrata.

Aceasta completeaza demostratia teoremei.

Gramaticile de genul celor construite in demonstratia Teoremei 4.3.1

se mai numesc gramatici in ”forma normala” - ideea este ca exista con-

strangeri structurale asupra productiilor care sunt permise. In acest caz,

toate productiile nu sunt de stergere. Este usor sa subestimam impactul

eliminarii regulilor de stergere citind ca schita pentru un algortim prin care

sa se faca aceste transformari, vom ilustra efectul sau in urlatorul exemplu.

Exemplul 4.3.1.

Consideram gramatica G cu productiile S e | SabS . Pentru acaesta

gramatica, E 1 = E = {S} . Pentru a obtine o gramatica corespunzatoare

fara reguli de stergere, eliminam regula de stergere si inlocuim productia

S SaSbS din G cu urmatoarea multime de productii din G:

S SaSbS | aSbS | SabS | SaSb | abS | aSb | Sab | ab.

Deoarece stergerea este imposibila in G, aceste productii anticipeaza

toate posibilele combinatii cu neterminalul S care poate fi eliminat sub-

secvential in G . Cititoul ar trebui sa verifice ca cele doua productii initiale

sunt echivalente cu multimea rezultenta a opt productii, reconsultand daca

240
e nevoie demonstratia de mai sus. De exemplu, derivarea din G:

S SaSbS aSbS abS abSaSbS abab eaebab

se regaseste in derivarea coresponzatoare din G

S abS abab

Definitia 4.3.2.

O productie A B o productie singulara, daca atat A cat si B sunt

neterminale

Regulele de redenumire inlocuiesc pur si simplu un neterminal cu altul

si nu au nici o contributie speciala, la realizarea scopului esential al unei

gramatici derivarea secventilor de terminale. Bineinteles, cu o astfel de pro-

ductie, optiunile efective pentru retranscrierea neterminalului din stanga

le includ pe acelea pentru neterminalul din dreapta. Desi acest lucru com-

pleteaza cu certitudine posibilitatile de retranscriere, aceste productii pot

fi eliminate daca dorim.

Teorema 4.3.2.

Orice gramatica independenta de context este echivalenta cu o gramatica

fara productii singulare.

Demonstratie.

Presupunem ca G =( V, ,P,S ) este independenta de context. Daca

A B P este productie singulara, luam G =( V = ,P ,S ), unde

P = P {A a | a V,A Z si Z a P}-{A B} . Prin

aceasta se inlatura productia singulara si se adauga o multime de productii

241
care executa o ” atuncare cu privirea” simulata spre rezultatul unei serii

de retrasncriseri de productii singulare.

Afrimatie. L ( G)= L (G )

Demonstratie.

Productiile din P fie sunt deja in P fie efectuaiaza retranscrieri care

pot fi realizate in cativa pasi in P. Deci este evident ca L (G ) L (G).

Trebuie doar sa mai aratam ca L ( G) L (G ). Consdieram x L (G )

si S x . Daca aceasta derivare nu necesita productia A B , atunci

este de asemenea o derivare in G si demonstratia afirmatiei este incheiata.

Altfel consideram prima utilizare a productiei A B intr-o derivare in

G, sa zicem S w 1
Aw 2 w 1
Bw 2 x = x 1 x 2 x3 . Din Teorema 4.1.1

avem ca wi x i
, penrtru i=1, 3 si B x 2
. Consideram acum derivarea

B x 2
* . Deoarece x2 V , aceasta derivare trebuie sa contina cel

putin o productie nesingulara. Ne concentram asupra pasului in care este

folosita prima data o productie nesingulara, sa zicem B C ...

Z a x 2
, unde C, ...Z V si a V . Dar atunci, deoarece A Z

si Z a P , A a P . De aceea S w 1
Aw 3 w 1
aw 3 .Alte

utilizari ale productiei A B in unele derivari din G pot fi inlocuite in G

in acelasi mod. De aceea x L (G ) si deci L ( G) L (G ), ceea ce incheie

demonstratia afirmatiei L (G )= L (G).

Am vazut cum se inlocueste o productie singulara cu o multime de

productii care nu sunt singulare.

Putem repeta procesul pentru toate productiile singulare din G iar gra-

242
matica rezultata este cea dorita. Se observa ca daca initial G nu contine

nici o productie singulara, atunci prin aceasta constructie nu se introduce

nici o astfel de productie.

Exemplul 4.3.2.

Ilustram constructia algortimica din demonstratia Teoremei 4.3.2 pentru

gramatica

A aA | B, B bB | C ; C cC | e

Avem doua productii singulare si eliminam prima data productia A B

obtinand (deoarece avem atat B C )

A aA | bB | cC | e, B bB | cC | e, C cC | e.

Acest rezultat este un alt exemplu de gramatica in forma normala si

ne conduce spre principalul rezultat al acestei sectiuni. Urmatoarea teo-

rema justifica faptul ca sunt suficiente doar doua forme foarte restranse ale

productiilor independente de context pentru aproape toate scopurile.

Definitia 4.3.3.

O gramatica independenta de context este in forma normala a lui Chom-

sky daca fiecare productie are forma A BC , unde B si C sunt netermi-

nale, sau forma A , unde este un simbol terminal.

Teorema 4.3.3.

Pentru orice gramatica independenta de context G cu e L ( G), exista

o gramatica in forma normala a lui Chomsky echivalenta cu 8 .

Demonstratie.

243
Demonstratia se face printr-o constructie care arata cum se transforma

G =( U, ,P,S ) intr-o gramatica in forma normala a lui Chomsky. Deoarece

e L ( G), putem presupune din Teorema 4.3.1 fara a se pierde gen-

eralitatea, ca G nu contine reguli de stergere din Teorema 4.3.2 putem

presupune ca G cu contine productii singulare. Construim gramatica

G =( V , ,P ,S ) in forma normala a lui Chomsky printr-o serie de pasi.

Pasul 1.

eliminam productiile care au si terminale in partea dreapta, exceptandu-

le pe cele de forma A , unde este un terminal.

Pasul 1A.

pentru fiecare , introducem un nou terminal X si productia

X P .

Pasul 1B.

inlocuim apoi fiecare productie din P al carei membru drept contine unul

sau mai multe terminale prin productii din P obtinute prin inlocuirea cu

X a fiecarui din productiile din P.

In acest punct derivarile sunt diferite, dar nu semnificative. Un terminal

este introdus mai intai ca X care poate fi imediat inlocuit ca , deci se

obtine exact aceeasi secventa de terminale. Se observa ca toate productiile

al caror membru drept are lungime 1 au acum forma corecta. De asemenea,

toate productiile al caror membru drept are lungimea mai mare sau egala

cu 2 constrau numai din neterminale.

Pasul 2.

244
eliminam productiile al caror membru drept de lungimea mai mare sau

egala cu 2.

Pasul 2A.

Pentru o productie A B 1
B 2 ...B k P cu k> 2si Bi V (1 =

i = k ) , productia se elimina din P , se introduce un nou neterminal C si

in locul acestei productii adaugam doua productii noi in P A B 1


C si

C B 2
...B k . Deoarece C nu mai apare in alt loc in gramatica, aceste doua

productii realizeaza exact aceleasi retranscrieri ca si productia initiala care

a fost eliminata.

Pasul 2B.

Se repeta pasul 2A de cate ori este nevoie. Deoarece lungimea mem-

brului drept al productiei scade la fiecare aplicare a Pasului 2A, procesul

trebuie sa se termine la un moment dat. Evident in acel moment avem

o gramatica in forma normala a lui Chomscky echivalenta cu gramatica

initiala.

Exemplul 4.3.3.

Ilustram procesul de aducere a unei gramatici la forma normala a lui

Chomsky urmarind pasii din demonstratia teoremei pentru gramatica G

sin Exemplul 4.1.2. Se observa ca poate exista o modalitate mai buna prin

care sa se ajunga la asemenea rezultate.

Gramatica initiala G este S aSB | e, B bB | e . Initial, se

observa ca deoarece e L (G) aceasta gramatica nu se poae aduce in forma

normala a lui Chomsky! Daca il eliminam pe e, putem aduce gramatica

245
obtinuta la forma normaqla a lui Chomsky.

Eliminam prima data regulile de stergere din G. Deoarece atat din S

cat si din B se poate obtine e, acaesta duce la gramatica G1 cu L ( G1 )=

L (G) -{e} si productiile

S aSb | aB | aS | a, B bB | b

G1 nu are productii singulare, deci putem incepe sa aplicam algoritmul

pentru aducerea in forma normala a lui Chomsky. Pasul 1 ne conduce la

gramatica G2 cu productiile:

S X a
Sb | X a B | X a
S | a, B X b
B | b, X a
a, X b
b.

Acum G2 are o singura productie care nu are forma dorita si aceasta

poate fi transformata printr-o singura aplicare a Pasului 2. In final se

obtine gramatica G3 care este in forma normala a lui Chomsky.

S X a
C|X a
B|X a
S | a, B X b
B | b, X a
a, C SB.

Daca legatura intre G 1 si G3 este neclara, cititorul ar trebui sa se

opreasca si sa compare cele doua gramatici.

Dupa cum se observa din exemplul anterior, forma normala a lui Chom-

sky desi simpla in principiu, introduce mai multe neterminale si mal multe

productii. Acest lucru face ca gramatica in forma normala a luiChomsky

sa fie mai putin clara decat gramatica initiala. Oricum, aceasta forma este

utila ca instrument teoretic, deoarece asigura numai doua tipuri de produc-

tii in analiza gramaticilor prin diferite metode. Deoarece forma normala

246
a lui Chomsky poate fi determinata mecanic si este garantat faptul ca

se va obtine o gramatica echivalenta, ea poate fi folositoare in procesarea

automata a gramaticilor unde numarul mai mare de neterminale si de pro-

ductii nu constituie un avantaj.

4.4. Gramatici regulate

Inainte de a continua studiul gramaticilor independente de context gen-

erale si al limbajelor, vrem sa dam o caracterizare a multimilor regulate

in termenii formalismului gramatical. Vom considera un caz special de

gramatici independente de context obtinuta prin adaugarea unor restrictii

asupra membrului drept al productiilor. Principalele doua rezultate din

aceasta sectiune ofera o noua caracterizare a multimilor regulate.

Definitia 4.4.1.

O productie A B a unei gramatici independente de context G =

( V, ,P,S ) se numeste lineara daca ß * ·V · , liniara-dreapta ,

daca ß * ·V , liniara-stanga, daca ß V· * si terminala daca ß


*. O gramatica G se numeste liniara daca toate productiile sale sunt

fie liniare-dreapta, fie terminale si G se numeste liniara-stanga daca toate

productiile sale sunt liniare-dreapta fie terminale; de asemenea o gramatica

G se numeste #-liniara daca # este un simbol terminal ce nu este in

si toate productiile terminale sunt de forma A #si#numaiaparein

alta parte.

Deci pentru productiile liniare-dreapta existe cel mult un neterminal in

247
partea dreapta a fiecarei productii si neterminalul trebuie sa fie cel mai din

stanga simbol. Analog se defineste pentru gramaticile liniare-stanga. De

exemplu, gramatica din Exemplul 4.1.1 este liniara, dar nu liniara-stanga

sau dreapta. Ca exemplu in care se prezinta structura liniara-dreapta

avem.

Exemplul 4.4.1.

Gramatica A 0A | B, B 1B | e cu axioma=A are de ex.

A 0A 00A 00B 001B 0011B 00111 B 00111 .

In general L (G)=0 * 1* deoarece productiile pentru A pot introduce un

numar arbitrar de 0 -uri care preced un numar arbitrar de ’1’ care pot fi

introduse prin retranscrieri ale lui B.

Gramatica din Exemplul 4.4.1 este liniara-dreapta si nu este o coinci-

denta faptul ca limbajul pe care il descrie este regulat. De fapt, astfel de

gramatici sunt suficiente pentru a descrie toate limbajele regulate si numai

pe acestea, dupa cum vom vedea in urmatoarele rezultate.

Teorema 4.4.1.

Daca L * este regulat, atunci exista o gramatica liniara dreapta G

cu L=L(G).

Demonstratie.

Deoarece L este regulat, exista un DFA A =( S, ,d,s 0


,R ) cu L=L(A).

Fara a restrange generalitatea, presupunem ca S si sunt disjuncte. Apoi

definim gramatica B =( S, ,P,s 0


) unde P = {s t | si d( s, )=

248
t} {s e | s R} . Aceasta gramatica este liniara-dreapta. Masi

mult, G ”simuleaza” direct DFA-ul A, in sensul ca fiecare secventa de

intrare x = 1
, 2
... n
( i
, 1 =i=n ) cu tranzitiile d(s 0 , )=

s 1 ,d ( s1 , )= s 2 , ..., d(s n- 1 , )= sn din A are o derivare corespunzatoare

s0 s
1 1 1 2 2
s ... 1 2
... n
s n in G si reciproc. Mai mult, sn R

daca si numai daca sn e P . De aceea L(A)=L(G).

Acest rezultat arata simplitatea in cazul limbajelor regulate din perspec-

tiva gramaticilor. In particular, desi am observat anterior ca ambiguitatea

este inevitabila in descrierea unor limbaje relativ simple, vo mvedea ca ele

nu pot fi ata de simple ca limbajele regulate.

Corolarul 4.4.2.

Nici un limbaj regulat nu este absolut ambiguu.

Demonstratie.

Fiecare secventa din limbaj are o tranzitie unica acceptata in DFA-ul

corespunzator. Dar tranzitiile DFA-ului sutn intr-o corespondenta unu-la-

unu cu derivari ale gramaticii asociate si deci nu este ambiguu.

Exemplul 4.4.2.

Pornind de la DFA-ul A=

Figura 4.5

care accepta 0 * 1* , constructia din demonstratia Teoremei 4.2.1 duce la

249
gramatica

q0 0q0 | 1q1 | e

q1 1q1 | 0q2 | e 4

q2 0q2 | 1q2 .

In aceasta gramatica simbolul q2 este neproductiv si eliminarea lui duce

la

q0 0q0 | 1q2 | e

q1 1q1 | e .

Cititorul ar trebui sa compare tranzitiile din DFA si derivarile din aceasta

gramatica; poate fi de asemenea folositor sa compare aceasta gramatica cu

gramatica echivalenta din EXemplul 4.4.1.

Strategia din demonstratia Teoremei 4.4.1 este convenabila cu NFA-urile

si e-NFA-urile, desi aceste modele nu ne-ar permite sa deducem corolarul.

Mai mult, constructia este reversibila efectiv - vom vedea ca putem porni

de la o gramatica si sa ajungem la un acceptor. O complicatie tehnica ar

trebui rezolvata insa inainte de a trece la rezultatul reciproc.

Lema 4.4.3.

Pentru fiecare gramatica liniara-dreapta G =( V, ,P,S ) exista o gra-

matica liniara-dreapta echivalenta G =( V , ,P ,S ) astfel incat fiecare

productie neterminala A a P are len ( a ) = 2 si fiecare productie

A x P are len ( x ) = 1.

Demonstratie.

Se observa ca in G nu este interzisa stergerea sau regulile de retranscriere

250
( e poate sa apartina unui limbaj regulat). Pentru A a P cu len (a ) > 2

putem folosi aceeasi constructie ca la pasul 2 in constructia formei normale

a lui Chomsky (Teorema 4.3.3.).

Aceasta lema ne da o varianata a formei normale a lui Chomsky pentru

gramaticile regulate care lasa limbajul neschimbat si conserva regularitatea

gramaticii.

Exemplul 4.4.3.

In conformitate cu Lema 4.4.3, o gramatica liniar-dreapta ca G= A

abA | abB, B aaaB | b este transformata in gramatica echivalenta G =

A aX 1
| aY 1 , x 1 bA , Y1 bB , B aZ 1
| b, Z 1 aZ 2
,Z 2
aB .

Teorema 4.4.4.

Pentru fiecare gramatica liniara-dreapta G, L(G) este regulat.

Demonstratie.

Pentru G =( V, ,P,S ), din lema 4.3.3 putem presupune ca P contine

numai productii de forma X 2Y si X z , unde X,Y V si z

{e} . Apoi definim un e-NFA A care accepta L(G) dupa cum urmeaza.

Introducem un simbol abstract nou, , care nu apare in G si definim A =

( V { }, ,d,s,{ } ) unde pentru fiecare x V si z {e} ,daca

x z P , atunci d(X, z )= { } {Y | X zY P} ;daca x z P ,

atunci d( x, z )= {Y | X zY P} . Prin aceeasi analiza ca cea din

Teorema 4.4.1 este evident ca acest e-NFA ”simuleaza” gramatica. De

aceea L(A)=L(G).

Exemplul 4.4.4.

251
Pentru gramatica G din Exemplul 4.4.3, constructia din demonstratia

Teoremei 4.4.4 conduce la acceptorul

Figura 4.6.

Se observa, de exemplu, ca o derivare a gramaticii ca A aY 1

abB abb corespunde exact tranzitia acceptata a NFA-ului:

d(A, abb ) d (Y1 ,bb ) d (B, b ) { }.

Strategia de demonstratie pe care am dezvoltat-o in aceste teoreme ilus-

treaza o dualitate perfecta intre recunoasterea si generarea din definitia

unui limbaj regulat. Cand acceptorul executa un pas atomic, el ”con-

suma” unul dintre simbolurile de intrare - cand o gramatica este folosita

pentru unul din pasii sau atomici, ea ”produce” unul din simbolurile de la

intrare. Vom vedea mai tarziu ca aceasta dualitate persista pentru modele

care sunt mai puternice.

Aceleasi rezultate pe care le-am obtinut in aceasta sectiune pentru gra-

maticile liniare-dreapta au loc si pentru gramaticile liniare-stanga. Aceasta

este o consecinta a faptului ca limbajele regulate sunt inchise in raport cu

inversa - detaliile le lasam ca exercitiu. Termenul de gramatica regulata se

252
refera la o gramatica independenta de context care este fie liniar-stanga fie

dreapta, si deci in mod necesar defineste un limbaj regulat.

Am vazut in aceasta sectiune ca folosind numai gramatici regulate, o

submultime restransa a gramaticilor independente de context, ofera sufi-

ciente mijloace de descriere a limbajelor regulate. Mai mult, Exemplul

4.1.1 a ilustrat deja ca gramaticile independente de context nerestriction-

ate ofera o putere expresiva mai mare.

Sintaxa limbajelor de programare

Dupa cum am observat mai devreme, mecanismul gramaticilor inde-

pendente de context a fost introdus de lingvistul Noam Chomsky in cer-

tarile sale pentru modele formale ale limbajelor naturale. Dar exact acelasi

mecanism a fost introdus si de Backus ca modalitate de a oferi mijloace pre-

cise, independente de masina de desriere a limbajelor de programare. Desi

este exact acelasi mecanism, in limbajele de programare se intalneste sub

denumirea de ”forma normala a lui Backus” (BNF). Desi acest mecanism s-

a dovedit a fi insuficient pentru a descrie precis fie limbajele de programare

fie limbajele naturale, el prezinta totusi o aproximare care este avantajoasa

pentru anumite scopuri. In descrierea sintaxei sale BNF a devenit princi-

pala componenta in descrierea limbajelor de programare.

S-a observat in sectiunea anterioara ca structura componenta asociata

cu un gragment de program este esentiala in intelegerea sensului acelui

fragment. Cel mai folosit aspect al descrierilor BNF ale limbajelor de

253
programare este acela ca vom avea un arbore de derivare disponibil pen-

tru identificarea componentelor unui program. Deoarece este esential sa

evitam ambiguitatea, este esential ca o BNF sa asocieze fiecarei compo-

nente un arbore de derivare unic. Nu avem nevoie doar de un arbore de

derivare, ci de acela corect. Am vazut deja ca diferite gramatici indepen-

dente de context pot descrie acelasi limbaj. Desi o gramatica asociaza

fiecarei secvente un singur arbore de derivare, aceste poate sa nu asig-

ure o structura potrivita pentru expresiile componente. Deoarece intelesul

unui fragment de program este o compunere a intelesurilor componentelor

sale, identificarea componentelor si stabilirea relatiilor care re ecta rolul

lor sunt esentiale. Nu numai intelegerea de catre un cititor a unui pro-

gram dependent de arborele sau de derivare este importanta; compilatorul

care traduce un program pentru executie determina interpretarea pe baza

structurii acestuia.

In aceasta sectiune vom ilustra organizarea descrierilor BNF care duc la

arbori de derivare adecvati pentru constructiile limbajelor de programare.

Deoarece descrierea limbajelor de programare nu este principalul tel in

aceasta carte, ne vom concentra pe BNF pentru sintaxa ”expresiilor”. Nu

numai ca sintaxa expresiilor este un element cheie in limbajele tipice de

programare, dar si descrierea expresiilor duce la multi factori complicati

care apar in descrieile BNF ale limbajelor complete. Deoarece limbajele

moderne de programare au sintaxa amestecata chiar pentru expresii ne

vom concentra atentia asupra expresiilor de baza.

254
Incepeem prin recapitularea unor lucruri de baza despre sintaxa expresi-

ilor. Intr-o expresie pot aparea numeroase operatii si principalela problema

este de a determina ordinea in care sunt efectuate operatiile. De exemplu,

vrem sa facem diferenta intre (2*x)+3 si 2*(x+3). O modalitate de a

face acest lucru este sa scriem parantezele. Dar pentru expresii care sunt

mai complicate, forma numai cu paranteze este greu de scris si mai greu

de citit. De exemplu, consideram expresia (2*(A-B)+3*((X+1)-(Y-1))) +

(4*(A+X) + 3*(B-Y)) - identificarea parantezelor pereche este o activitate

greoaie. Din acest motiv, s-a dorit sa se minimizeze folosirea parantezelor

in expresii si de aceea se foloseste un alt mecanism de determinare a or-

dinii operatiilor. Acest mecanism alternativ este acela de atribuire a unei

precedente fiecarei operatii. Se intentioneaza ca operatiile de precedenta

mai mare sa fie efectuate inaintea celor de precedenta mai mica, indifer-

ent de ordinea relativa a aparitiei lor in expresie. Operatiile de aceeasi

precedenta care efectuiaza in ordinea aparitiei lor in expresie se numesc

asociative-stanga, iar cele care se efectueaza in ordinea inversa a operatiei

lor se numesc - asociative dreapta.

Vom folosi numai operatori numerici de baza din Figura 4.5.1 plus op-

eratia de atribuire (=), care are un argument stang ce este o variabila si un

argument drept ce este o subexpresie dreapta si o atribuie celui din stanga.

255
Figura 4.5.1.

Figura 4.5.1 indica atat precedenta cat si asociativitatea fiecarei operatii

si acesti doi factori determina ordinea de efectuare a operatiilor. Desi

utilizarea lor este minimilizata, parantezele pot fi inca folosite pentru a

indica o ordine a operatiilor care sa difere de ordinea in care ele apar. Cu

conventiile din Figura 4.5.1.

• expresia X +3 * Y ”inseamna” X +(3 * Y ), nu ( X * 3) * Y

• expresia -X * Y - Z/ 2 ”inseamna” (( -X ) * Y ) - (Z/ 2)

• expresia X = Y = Z + 5 ”inseamna” X =( Y =( Z +5))

O abordare pentru descrierea unei expresii fara folosirea precedentelor,

parantezelor sau a asociativitatii este de a o descrie printr-un ”arbore aso-

ciat unei expresii”. Un arbore asociat unei expresii este un arbore orientat,

unde fiecare mod este o operatie; o variabila sau o constanta a expresiei.

Variabilele si constantele sunt noduri terminale. Operatiile unare au un

nod fin care este radacina pentru subarborele corespunzator subexpresiei

ce desrie argumentul sau si operatiile binare au cate un nod fin stang si unul

drept, care sunt noduri radacina pentru subarborii corespunzatori subex-

256
presiilor si constituie fiecare argument al operatiei. De exemplu, expresia

2 * X +3 /Y este reprezentat in arborile din Figura 4.5.2, presupunand ca

precedenta este cea din Figura 4.5.1.

Figura 4.5.2

Structura unui arbore asociat unei expresii releva constrangerile esen-

tiale asupra ordinii operatiilor. Dupa cum sugereaza exemplul din Figura

4.5.2, o expresie poate fi evaluata printr-un proces de orientare a arbore-

lui care are loc de jos in sus. Nodurile terminale sunt evaluate imediat,

deoarece sunt fie constante fie variabile. Folosind valorile nodurilor ter-

minale evaluarea ”se muta” cu un nivel mai sus, prin executarea operatiei

indicate, si fiind date acele valori se urca un nivel in arbore etc. Deci avand

un arbore asociat unei expresii, nu ne mai preocupa, asociativitatea sau

parantezele - acestea sunt necesare numai pentru a determina ordinea oper-

atiilor scrise in forma secventionala obisnuita. Strcutura de arbore contine

singura ordine necesara a operatiilor.

Este usor pentru un compilator sa genereze instructiuni executabile

pornind de la un arbore asociat unei expresii. De exemplu, in arborele

din Figura 4.5.2, fiind date instructiunile pentru doi subarbori, ele pot fi

257
”ansamblate” impreuna cu o instructiune ’add’ pentru a obtine instruc-

tiunile care sa evalueze intreaga expresie. Acest lucru duce la un proces

recursiv simplu, de generare de cod pentru subarbori si de adaugare a al-

tor catorva instructiuni care sa creeze cod pentru urmatorul nivel; baza

pentru recurenta din nodurile terminale, si instructiunile pentru variabile

si constante pot lua valori din memorie. Nu vom da detalii ale procesului

de compilare a instructiunilor, dar sa specram ca s-a intuit cum se merge

mai departe odata ce este obtinut un arbore asociat unei expresii. Citi-

torul interesat poate gasi detalii ale acestui proces in cartile de construire

a compilatoarelor.

Scopul nostru este de a construi o descriere BNF a expresiilor care vor fi

baza pentru constructia arborilor acsociati expresiilor. Acest lucru se real-

izeaza prin dezvoltarea unei descrieri BNF care duce la arbori de derivare

a caror structura seamana cat de mult este posibil cu arborii asociatii ex-

presiilor corespunzatoare. Analiza posibilitatilor BNF va fi criteriul folosit

pentru selectie.

In structura arborelui asociat unei expresii operatia care va fi efectuata

ultima are cea mai mica precedenta si apare ca radacina a arborelui, iar

operatiilr care vor fi efectuate primele au cea mai mare precedenta si apra

imediat deasupra nodurilor frunza. De aceea trebuie ca BNF sa fie aran-

jata astfel incat operatiile cu precedenta mai mare sa apara in subarborii

operatiilor cu precedenta mai mica.

Deoarece pentru operatii consideram (vezi Figura 4.5.1) ”=” ca avand

258
cea mai mica precedenta, aceasta operatie trebuie sa apara iin nodul radacina

al arborelui de derivare.

Pe baza acestui strategii, consideram < expr > ca simbol de start al

formei BNF pentru expresii si prima productie pe care o introducem este

expr var = expr . Aceasta productie plaseaza operatorul ”=” in

varful arborilor de derivare si impune ca argumentul sau sa fie o variabila

si permite ca subexpresia din dreapta sa contina operatii aditionale de

atribuire. Mai mult, in arborii de derivare rezultanti, introducerea oper-

atiilor ”=” aditionale prin rescrierea lui <expr> din partea dreapta va

aparea intr-un subarbore si deci va duce in mod natural la asocietivitatea

-dreapta a acestei operatii.

Figura 4.5.3

Arborele de derivare din Figura 4.5.3 este partea initiala a echivalentului

sintactic pentru arborii asociati unor expresii ca cel din Figura 4.5.4. El

stabileste ordinea de executie a atribuirilor in expresii de forma X=Y=X+1

plasand operatii ”=” in aceeasi relatie expusa in arborele asociat expresiei;

259
de fapt, daca intrepatrundem nodurile ”=” si <expr> din Figura 4.5.3

obtinem efectiv Figura 4.5.4.

Figura 4.5.4

Pentru a continua dezvoltarea formei BNF pentru expresii, sa observam

ca nu toate expresiile contin o operatie de atribuire si mai mult ar trebui

sa putem eventual deriva o secventa care nu contine <expr> , deci nu

trebuie o alta optiune de retranscriere pentru <expr> .

Pentru a genera ” expresii aritmetice” introducem productia expr

arith . Productiile pentru expr ne dau singurul mod de introducere a

operatiei ”=” in expresii. Productiile pe care le vom da pentru arith vor

fi responsabile de introducerea tuturor celorlalte operatii.

Operatiile aditive + si - au urmatoarea precedenta dupa ”=” si de aceea

ar trebui sa apara la urmatorul nivel in arborii de derivare, adica in varful

arborilor de derivare pentru arith . Aceste operatii sunt asociate-stanga,

si deci de exemplu X-Y-X inseamna (X-Y)-Z, nu X-(Y-Z). Arborele asociat

expresiei X-Y-Z este cel din Figura 4.5.5.

260
Figura 4.5.5

Dupa cum ilustreaza exemplul X-Y-Z, asociativitatea-stanga implica

faptul ca cea mai din dreapta operatie ar trebui sa apara cel mai aproape de

varful arborelui si cea mai din dreapta operatie ar trebui sa apara cel mai

aproape de baza arborelui. Pentru a obtine un efect similar pentru arborii

de derivare, introducem productiile arith arith + term si arith

arith - term . Arborele de derivare bazat pe aceste productii care duce

la expresia X-Y-Z este prezentat in Figura 4.5.6. Aceste productii exprima

arith ca suma de term si derivarile arith arith + term ...

introduc cel mai din stanga operator editiv la baza arborelui de derivare.

261
Figura 4.5.6.

Continand strategia folosita pentru operatia de atribuire aceste produc-

tii pentru arith ofera singurul mod de introducere a operatiilor ”+” si

”-” in expresii. Restul operatiilor vor fi generate prin productii potrivite

pentru term . Dupa cum s-a aratat in acest exemplu, arborele de derivare

”imita” plasarea in arborele asociat expresiei a operatiilor adetivi- din nou

daca imbinam nodurile ”-” si arith din Figura 4.5.6, obtinem structura

arborelui din Figura 4.5.5. Fiecare fin cele doua productii a lui arith

introduc inca o data arith , deci trebuie sa gasim un mod de a elimina

acest neterminal. Facem acest lucru cu ajutorul ultimei productii pentru

arith si anume arith term .

Productiile pentru term vor furniza expresiile care nu contin nici

atribuiri, nici operatori aditivi. Urmatoarele operatii ca precedenta sunt

operatiile multiplicative, deci ele ar trebui sa apara cel aproape de varful

restului arborelui de derivare. Aceste operatii sunt de asemenea asociative-

stanga, deci putem proceda cu term la fel cum am procedat cu arith .

Introducem productiile term term * f actor si term term

/ f actor . Folosind aceste productii pentru term obtinem arbori de

derivare similare cu cei aditivi. Vom analiza cateva exemple specifice putin

mai tarziu. Si aici avem nevoie de o productie care sa ne permita sa elim-

inam term din derivari, si aceasta va fi productia term factor .

Mai avem de introdus numai operatia de cea mai mare precedenta, mi-

nus unar. Acaesta operatie este introdusa in expresii prin intermediul

262
productiilor dupa ce toate celelalte operatii au fost generate, ea trebuie sa

apara cel mai aproape de nodurile terminale ale arborului de derivare. Ul-

timul lucru pe care trebuie sa-l mai asiguram este asocietivitatea-dreapta

a lui minus unar. Rationamentele care arata ca aceasta productie asigura

asocietivitatea -dreapta a lui ”-” este similar cu analiza pentru speratia

”=”. Vom amana exemplele pana cand BNF este completa.

In sfarsit, avem nevoie de productii pentru f actor care sa introduca

subexpresiile in care ordinea operatiilor sa nu necesite o analiza imediata

pentru a o determina. Acest lucru se realizeaza printr-un ultim netermi-

nal prin productia f actor primary .Apoi primary ne permite

introducerea variabilelor si constantelor. Dar avem si o ”surpriza” - putem

sa avem ca parte componenta a subexpresiei intre paranteze. Acest lu-

cru este necesar pentru a putea avea subexpresii intre paranteze de mai

multe ori. Aceasta este momentul potrivit de a avea o astfel de optiune

evaluate inaintea ca rezultatul ei sa fie argument, dandu-le acestor operatii

precedenta mai mare ca altor operatii din expresie. De aceea avem trei

productii pentru primary , primary var , primary const si

primary ( expr ).

Multimea tuturor acestor productii apare in Figura 4.5.7 si constituie

figura BNF pentru expresii. Tehnic avem nevoie si de productii care sa

descrie sintaxa pentru variabile si constante. Oricum, acestea nu implica

operatii si deci nu au legatura cu scopul pe care ni la-u propus. Productiile

pentru var si const pot fi date in orice mod convenabil si sunt omise

263
aici - inlocuim pur si simplu aceste neterminale cu identificari si numerele

de acre este nevoie.

Figura 4.5.7. Forma BNF pentru expresii

Exemplul 4.5.1.

Pentru o simpla ilustrare a formei BNF din Figura 4.5.7 consideram

expresia A+B*C. Presupunerile asupra precedentei duc la arborele asociat

expresiei din Figura 4.5.8 si forma BNF duce la arborele de derivare indicat.

Categoriile extra sintactice pe care le-am introdus in BNF pentru a modele

constrangerile de precedenta ”intind” arborele de derivare, dar structura lui

o re ecta efectiv pe cea a arborelui asociat expresiei. Suprapunand nodurile

din arborele de derivare care doar redenumesc o categorie sintactica prin

alta, pentru a genera fiecare element primar al expresiei , se obtine arborele

asociat expresiei.

264
Figura 4.5.8.

Desi forma noastra BNF este destul de compacta comparativ cu sin-

taxa expresiilor limbajelor moderne de programare, derivarile sunt evident

netriale. Productiile au fost gandite in asa fel incat precedenta si aso-

ciativitatea operatiilor sunt prioritare in arborele de derivare. Productile

pentru expr si factor sunt considerate deseori ”recursive la dreapta” -

ex: retranscrierea lui expr il reintroduce pe expr ca cel mai din dreapta

simbol expr var = expr . Acaesta este consecinta fireasca a tratarii

operatiei implicate (=) ca fiind recursiva-dreapta, deoarece aparitiile celui

mai din dreapta operator sunt celel mai urgente deci trebuie executate

primele. O relatie similara apare in productiile pentru arith si term

care sunt ”recursive-stanga” si introduc operatii asociative-stanga (adica

265
+ , -* si / ). Recursivitatea -stanga cauzeaza esecul unor metode de analzia

sintactica si de aceea ar trebui evitata. Aceasi precedenta poate fi expri-

mata fara recursivitate-stanga, dar acest lucru nu e necesar pentru scopul

nostru. Tratarea acestor probleme pragmatice trece de scopul discutit din

aceasta sectiune.

Forma BNF din Figura 4.5.7 a fost atent formulata astfel incat arborii

de derivare sa re ecte precedenta si asociativitatea operatiilor care sunt in-

troduse. Dar vrem de asemenea sa fiu siguri ca toate secventele derivate din

acaesta gramatica sunt toate ”expresiile bine formate” si numai acestea.

Pentru a verifica formal acaesta, trebuie sa avem o alta descriere riguroasa

a expresiilor care vor servi ca standard pentru comparare. Dar deoarece

scopul descrierii BNF este de a stabili in primul rand un astfel de stan-

dard, aceasta verificare trebuie sa ramana informala. Deoarece expr

var si expr const toate expresiile atomice sunt generate. Putem

apoi sa continuam inductiv pentru expresiile compuse, bazandu-ne pe nu-

marul operatiilor pe care acaestea le contin. De exemplu, daca e1 si e2

sunt expresii valide, atunci e1 + e2 este o expresie valida, deoarece acaesta

compunere este compatibila cu precedenta si asociativitatea. Adica, daca

de exemplu e1 = X + Y si e2 = Z , atunci derivarile lui e1 si e2 nu au nici

o legatura cu derivarea lui X + Y + Z , deoarece operatia de pe cel mai de

sus nivel din aceasta expresie este ”+” si nu ”*”. Deci pentru a construi

corect expresia e1 * e2 cu aceste componente, toate operatiile din e1 nein-

cluse intre paranteze trebuie sa aiba precudenta mai mare decat aceea a

266
lui ” * ”, sau precedenta egala si asociativa-stanga si toate operatiile lui e2

neincluse intre paranteze trebuie sa fie de precedenta mai mare sau egala

si asociativa-dreapta. De aceea, factor e 1


si f actor e 2
.Deaici

expr arith term term * factor factor * factor e 1


*e2 .

Analize similare se pot face pentru expresiile compuse formate cu cele-

lalte operatii.

Expresia simpla din Exemplul 4.5.1 ilustreaza cateva probleme de baza

pentru forma BNF pentru expresii dar nu dezvaluie clar toate substitu-

tiile. Oricum insa, prezentarea detaliilor pentru expresiile reale este vo-

luminoasa. Categoriile sintactice intermediare introduse pentru realizarea

precedentei operatorilor largesc mult arborele de derivare. Vom da un ex-

emplu simplu pentru a sugera cat de repede se extind aceste delatii.

Exemplul 4.5.2.

Consideram expresia ( N = N +1) * N

267
Figura 4.5.9.

Arborele asociat expresiei care re ecta ordinea execuriei operatiilor si

arborele de derivare pentru acaesta expresie sunt ilustrati in figura 4.5.9.

Arborelui de derivare ii lipseste compactitatea arborelui asociat expresiei,

268
dar caracteristicile structurale importante ale arborului asopciat expre-

siei sunt inca vizibile. Arborele de derivare din Figura 4.5.9 are operatia

multiplicativa (*) cel mai aproape de radacina, operatia de atribuire in

subarborele stang cu un nivel deasupra operatiei aditive (+) si bineinte-

les, toti operanzii apar pe pozitiile nodurilor terminale corespunzatoare.

Folosind forma BNF din Figura 4.5.7, chiar si o expresie mica cum este cea

din cazul acesta are un arbore de derivare de marime considerabila. Ar-

borele de derivare trebuie sa contina explicit subexpresiile intre paranteze,

care sutn imoplicite in arborele asociat expresiei. Pe masura ce expresi-

ile devin mai complexe, arborii de derivare incorporeaza numeroase nivele

intermediare care ”intind” ramurile sale.

Relatia intre evaluarea expresiilor si structura arborilor de derivare nu

va fi elaborata dincolo de observatiile informale facute pana acum. Din

fericire, discutiile din jurul dezvoltarii formei BNF si exemplele au facut

plauzibila acaesta legatura. Justificarea tehnica completa ar duce la exam-

inarea codului executabil, ceea ce este mai mult decat scopul initial.

O proprietate pe care vrem sa o stabilim cu siguranta este ca forma BNF

pentru expresii nu este ambigua. Am ilustrat mai devreme modul cum

ambiguitatea sintactica duce la ambiguitatein inteles si pune sub semnul

intrebarii secventa respectiva. Ambiguitatea este o proprietate formala a

gramaticilor independente de context si o demonstratie riguroasa a aces-

tei proprietati este imaginabila. Dupa cum s-a observat anterior, aceasta

argumentare poate fi destul de dificila, deoarece trebuie sa aratam pen-

269
tru fiecare secventa din limbaj ca are exact un arbore de derivare. Chiar si

pentru aplicatiile limitate si relativ familiare pe care le-am prezentat, acest

lucru este provocator.

Afrimatie.

Expresia BNF din Figura 4.5.7 este ne-ambigua.

Arborele asociat expresiei este unic si deoarece arborele de derivare pen-

tru BNF ”mimeaza” structura arborelui asociat expresiei, rezulta ca si ar-

borele de derivare ar trebui sa fie unic. Pentru operatii care nu sunt inchise

intre paranteze si productiile folosite, pentru expr sunt complet deter-

minate de numarul de operatii ”=” din secventa derivata. De asemenea,

productiile folosite pentru arith sunt complet determinate de numarul

si ordinea relativa a operatiilor + /- . Observatii similare se aplica pentru

celelalte operatii. Numarul si locatia variabililor, constantelor si subexpre-

siilor intre paranteze determina cel mai jos nivel de retranscriere. Subex-

presiile din paranteze trebuie sa derive din expr si deci sunt un subiect

al aceleiasi analize. Nu vom da o demonstratie detailata a ne-ambiguitatii,

dar cititorul ar trebuie sa se gandeasca putin la ea.

Formularea unei BNF care sa descrie un limbaj de programare cere

mai multa consideratie decat simpla asigurare ca sunt generate secventele

corecte. Structura arborilor de derivare joaca un rol critic in transformarea

unui program intr-o secventa de instructiuni, care realizarea programul,

deci acestor arbori de derivare trebuie sa li se acorde mai multa atentie

decat limbajului de programare insusi. Se observa ca tratarea noastra a

270
sintaxei omite orice folosire a ”spatiului alb”. Acesta ar putea fi integrat

in BNF, dar in specificatiile compilatorului, spatiile alebe sunt procesate

in analiza lexicala, nu in BNF. Analiza lexicala este mai eficient r4ealizate

folosindu-se tehnicile cu stari finite. Detaliile practice trec de scopul studi-

ului de aici.

4.6. Rezumat

Acest capitol a introdus conceptele de retranscriere, de baza ale de-

scrierii limbajelor prin intermediul gramaticilor formale. A fost prezentata

o examinare initiala a caracteristicilor de retranscrisre asociate cu gramati-

cile independente de context si a fost dat un indiciu preliminar a puterii lor

expresive. Aceasta a inclus identificarea subfamiliei de gramatici liniare-

dreapta, care descriu exact limbajele regulate si justifica si alte mijloace de

descriere a acestei familii de limbaje.

Idea unui arbore de derivare este centrala pentru gramaticile indepen-

dente de context si este unica pentru acestea. Structura ierarhica asociata

unei secvente pe baza arborelui sau de derivare are o importanta imensa

in aplicatii. Aceasta in schimb duce la nevoie de a identifica si elimina

ambiguitatea, o problema pe care o vom considera in Partea a III-a.

Simplificarile gramaticale au fost dezvoltate in spiritul descrierilor im-

plicite ale algoritmilor, continuind aspectul considerarii mecanismelor de-

scriptive. Acesta a dus in schimb la transformarea gramaticilor in diferite

forme normele care sunt utile pentru anumite scopuri din capitolele ulte-

271
rioare.

In sfarsit, Sectiunea 4.5 ilustreaza rolul esential jucat de arborii de

derivare cand x folosesc gramatici independente de context pentru a de-

scrie sintaxa limbajelor de programare. O relatie naturala intre sintaxa si

semantica se realizeaza cel mai bine prin luarea atenta in considerare atat

a limbajului cat si a stucturii comunicata de gramatica.

Am prezentat in acest capitol cateva idei si tehnici de baza, dar aceste

preliminarii ofera doar a perspectiva de inceput asupra adevaratei puteri

descriptive a gramaticilor independente de context. Am vazut ca toate

limbajele regulate pot fi descrise de gramatici independente de context,

si numeroasele limbaje neregulate au fost de asemenea expuse. Dar lim-

itele expresivitatii nu au fost explorate. In urmatoarele doua capitole vom

dobandi o mai buna intuitie asupra faptului cum capacitatea expresiva este

extinsa odata cu gramaticile independente de context si cat de serioase sunt

limitele care raman.

272

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