Documente Academic
Documente Profesional
Documente Cultură
6 la Modelarea Sistemelor
36
Care realizeaz descompunerea unei propoziii/fraze ntr-o list a cuvintelor sale componente
2. parser-ul care realizeaz analiza propoziiilor/frazelor conform regulilor specificate de gramatica
adoptat precum i obinerea semanticii aferente acestora. Pentru aceasta, se
apeleaz la analiza sintactic i morfologic, la analiza semantic i la analiza pragmatic;
3. executivul care preia semantica obinut n pasul anterior, transformndu-o n comenzi sau
cunotine. Noi nelegem texte mari combinnd fora noastr de nelegere pentru textele mai mici.
Principalul scop al teoriei lingvistice este acela de a arta cum prtile mari de text sunt formate din mai
multe prti mici. Acestea sunt modelate de gramatic. Lingvistica computaional ncearc s implementeze
acest proces de recunoatere ntr-un mod ct mai eficient. Este tradiional s subdivizm acest task n
sintactic i semantic, unde sintactica descrie cum diferite elemente formale a unui text, de cele mai multe ori
propoziii, pot fi combinate, iar semantica descrie cum este calculat interpretarea.
Analiza sintactic ne ajut s nelegem modalitatea prin care cuvintele se grupeaz n vederea
construirii unei propoziii sau fraze. n acest sens, o propoziie este format din constitueni sintactici, unii
dintre ei fiind, la rndul lor, compui din constitueni. Constituenii care la rndul lor sunt formai din
constitueni se numesc non-lexicali n timp ce toi ceilali se numesc lexicali. Constituenii lexicali (cuvintele
vocabularului) mpreun cu caracteristicile lor morfologice (numr, timp, caz etc.) formeaz lexiconul.
1. Schema general a unui compilator. Compilatorul este un program complex, a crui realizare
presupune abordarea sistemic a procesului de traducere. In procesul de compilare, PS sufer un ir de
transformri n cascad, din ce n ce mai apropiate de CO. Conceptual, un compilator realizeaz dou mari
clase de operaii:
- analiza textului surs;
- sinteza codului obiect.
La rndul lor, aceste operaii se descompun n suboperaii specializate, nlnuite ntre ele i caracterizate
prin funcii bine precizate. Din punctul de vedere al structurii sale, un compilator poate fi reprezentat
schematic ca n fg. 3.5. Se observ nlnuirea etapelor analizei i sintezei, precum i ordinea natural a
acestora. Facem aici observaia c aceast reprezentare se dorete a fi general, i c n practic anumite
etape pot fi considerate mpreun.
36
Analiza lexical realizeaz o prim parcurgere a PS (considerai ca sar de caractere), grupnd aceste
caractere in subsiruri. numite atomi lexicali: cuvinte cheie sau rezervate, operatori, constante, identificatori,
separatori.
Analiza sintactica depisteaz in irul atomilor lexicali structuri sintactice, expresii, liste, instruciuni,
procedri s a , genernd arborele sintactic (arborele de derivare), care descrie relaiile dintre aceste structuri
(de incluziune, de separare etc).
Analiza semantic folosete arborele sintactic pentru extragerea de informaii privind apariiile obiectelor
purttoare de date din PS (tipuri de date, variabile, proceduri, funcii) i pentru verificarea consistenei
utilizrii lor Pe msura parcurgerii arborelui sintactic, se genereaz codul intermediar. Acesta este un ir de
instruciuni simple, cu format fix, n care: codurile operaiilor sunt asemntoare cu codurile main
corespunztoare, ordinea operaiilor respect ordinea execuiei (dictat de apariia acestora n PS), iar
operanzii sunt reprezentai sub forma variabilelor din PS, i nu sub form de regitri sau adrese de memorie.
Optimizarea codului intermediar are ca obiectiv eliminarea redundanelor, a calculelor inutile, n scopul
realizrii unei execuii eficiente a codului obiect Pentru atingerea acestui obiectiv se ncearc:
realizarea tuturor calculelor posibile nc din faza de compilare (de exem-plu
n expresii cu operanzi constante);
eliminarea subexpresiilor comune (prin evaluarea lor o singur dat);
factorizarea invarianilor din cicluri.
Generarea programului (codului) obiect const in alocarea de locaii de memorie i regitri ai unitii
centrale pentru variabilele programului i n nlocuirea codurilor de operaii din codul intermediar cu cele
main. Codul obiect rezultat poate fi:
absolut (direct executabil);
relocabil (care va face obiectul editrii de legturi, unde va fi legat de alte
module obiect, rezultate din compilri anterioare sau din biblioteci);
n limbaj de asamblare, lucru ce asigur un efort mai mic de implementare a
generatorului de cod
sau
n alt limbaj de programare n cazul preprocesoarelor.
n alt ordine de idei, generarea de cod difer in funcie de arhitectura mainii (main cu acumulator i
cu registre de baz i index sau main cu registre generale).
Cele 5 module de baza ale procesului de compilare sunt asistate de alte dou componente ale compilatorului,
ale cror servicii sunt utilizate pe tot parcursul compilarii: modulul de tratare a erorilor i gestionarul tabelei
de simboluri:
Modulul de tratare a erorilor este constituit dintr-o colecie de proceduri care sunt activate ori de cte ori este
detectat o eroare n timpul operaiilor de analiza. Ele emit mesaje de diagnostic relative ia eroarea
respectiv i iau decizii privind modul de continuare a traducerii:
- traducerea se continu cu ignorarea elementului ce conine eroarea;
- se ncearc corectarea erorii
sau
- se abandoneaz procesul de traducere.
Dup momentul de analiz n care apar, erorile pot fi lexicale, sintactice sau semantice. Un alt criteriu de
clasificare a erorilor este "gravitatea" lor; distingem avertismente (de obicei omisiuni de programare),
erori care se pot "corecta" de ctre un compilator mai inteligent i erori "fatale", care provoac
abandonarea
Gestionarul tabelelor este tot o colecie de proceduri care realizenz crearea si actualizarea bazei de date a
compilatorului, carc conine dou categorii de informaii:
37
- proprii compilatorului (generate la implementare i constituite din mecanismele de descriere a
analizei lexicale, sintactice i semantice)
si
- caracteristice PS (identificatori, constante, cuvinte cheie), care de obicei se memoreaz ntr-o tabel
de simboluri.
Exist diverse modaliti de gestionare a tabelei de simboluri, n funcie de reprezentarea acesteia (tabel
neordonat, tabel ordonat alfabetic sau dispersat -memorarea i regsirea fcnd apel ntr-un astfel de caz
la aa numitele funcii de dispersie hashing functions de tipul limbajului supus traducerii (cu sau fr
structur de bloc), de conveniile alese pentru reprezentarea atributelor n tabel, de caracterul general
(acoperitor) al tabelei (existena unei singure tabele de simboluri sau prezena unor tabele specializate
pentru variabile, proceduri, constante, etichete) etc.
In faza de analiz lexicali (de obicei), la ntlnirea unui nume nou, acesta este introdus n tabela de
simboluri, reinndu-se adresa intrrii. Ori de cte ori numele este referit, informaia prezenta n tabel
este actualizat cu informaii sau atribute noi ale numelui respectiv, verificndu-se totodat consistena
utilizrii acestuia (n analiza semantica). La generarea de cod, atributele numelui determina lungimea
zonei de memorie alocata acestuia. In sfirsit, atributele
numelui pot servi si in faza de tratare a erorilor.
1.1 Analiza Faza de analiz cuprinde trei etape: analiza lexical, sintactica si semantica. Aceste trei etape
se pot implementa separat, aa cum este ilustrat in figura 3.5, sau global.
1.2 Analiza lexical. Analiza lexical (engl. scanning, analizor lexical = scanner), transforma PS
(considerat ir de caractere) ntr-un ir de uniti lexicale, numite atomi lexicali sau particule lexicale (engl.
tokens). Clasele de atomi lexicali, considerate ca mulimi finite, corespund identificatorilor, constantelor
ntregi, constantelor reale i operatorilor. Pe scurt, analizorul lexical realizeaz operaii de detectare,
clasificare i traducere:
- detectarea n PS a subirurilor ce respecta regulile de formare a atomilor lexicali;
De obicei, analiza lexical este considerat ca o etap a analizei sintactice. Intre argumentele n favoarea
separrii acestor operaii menionm:
- o proiectare mai simpl a analizorului sintactic i a celui lexical, datorat principiului separrii
funciilor;
- posibilitatea scrierii analizorului lexical n limbaj de asamblare (el ne cesitnd n general operaii apropiate de
main), i n limbaje de nivel nalt a celorlalte componente ale compilatorului;
- deoarece sintaxa atomilor lexicali se poale exprima cu ajutorul unei gramatici regulate, modelul
analizorului lexical poate fi un automat finit care este mai simplu de implementat dect automatele push-
down utilizate n celelalte etape ale analizei;
- aportul analizorului lexical la "igienizarea" PS, deoarece:
numrul atomilor lexicali este mai mic dect numrul de caractere din PS;
se elimini blank-urile sau comentariile;
se poate prelua n analiza lexical evaluarea unor construcii dificil de implementat n analizorul
sintactic, rezultatul fiind reducerea complexitii analizei sintactice;
36
- creterea portabilitii algoritmului de compilare (de exemplu la dialecte diferite ale aceluiai limbaj, ce
diferi prin cuvinte cheie, realizarea unui compilator nseamn doar (scrierea analizorului lexical).
Din punctul de vedere al relaiei cu analizorul sintactic, se deosebesc dou moduri de abordare:
- analizor lexical comandat de analizorul sintactic, caz n care primul este o rutin a celui de al doilea.
Din punct de vedere structural, analizorul lexical poate fi monobloc (analiza lexical este abordat i
rezolvat global) sau structurat, cnd gramatica atomilor lexicali este stratificat, rezultnd de obicei trei
subfaze: transliterare (clasificarea caracterelor PS), explorare (depistarea i clasificarea subirurilor de atomi
lexicali) i selectare (definitivarea clasificrii, eliminarea caracterelor inutile i codificarea atomilor lexicali).
tratarea gramaticii atomilor lexicali, prin rafinri succesive, obtinndu-se o mulime de gramatici
regulate;
1.3 Analiza sintactic. Analiza sintactic (engl. parsing) este una dintre etapele principale ale
procesului de traducere. Prin ea se realizeaz transformarea irului de intrare (format din atomi lexicali) n:
- descrierea structural a acestuia, semantic echivalent (n cazul cnd irul de intrare este corect
sintactic)
respectiv
- mesaj de eroare (n caz contrar).
Construirea arborelui de derivare se face pe baza irului atomilor lexicali i poate fi:
Analizoarele sintactice se pot clasifica dup modul de construire a arborelui de derivare (analizoare
ascendente, respectiv descendente) sau dup existena revenirilor n procesul de construire a acestui arbore
(cu reveniri sau fr reveniri).
Modelul sintaxei limbajelor de programare este gramatica independent de context, prin urmare,
conform rezultatelor teoretice expuse n seciunea precedent, modelul analizorului sintactic va fi
automatul push-down nedeter-minist. n simularea funcionrii acestuia, este important problema tratrii
revenirilor. Dac la un moment dat se pot lua n considerare mai multe alternative de continuare a derivrii,
trebuie s se prevad posibilitatea revenirii la o alt alternativ posibil cnd alternativa aleas nu conduce
la un rezultat favorabil. Acest lucru mrete timpul de realizare a analizei, motiv pentru care este de dorit ca
la orice moment s fie asigurat o singur posibilitate de continuare a acesteia.
Analiza sintactic descendent are ca model APDN i se bazeaz pe derivarea stnga a irului
37
acceptat Operaiile acestui automat sunt:
- expandarea (nlocuirea unui neterminal A din vrful stivei cu partea dreapt a unei A-producii din
gramatic) i
- avansul (tergerea unui terminal din vrful stivei atunci cnd el coincide cu terminalul curent din
irul de intrare, urmat de avansul intrrii).
Criteriul de acceptare este criteriul stivei vide. Revenirile sunt modelate cu ajutorul unei stive auxiliare, n
care se memoreaz configuraia APDN la fiecare punct de ramificare a analizei, cnd sunt posibile mai
multe alternative de derivare. In cazul analizoarelor sintactice descendente fr reveniri, modelul sintaxei
este gramatica LL(k).
Analiza sintactic ascendent are ca model APDN extins i se bazeaz pe derivarea dreapta a irului
acceptat, parcurs n ordine invers. Operaiile acestui automat sunt:
- deplasarea (cutarea n irul de intrare, trecut succesiv n stiv, a prilor drepte ale regulilor de
producie ale gramaticii) i
- reducerea (o parte dreapt a unei reguli de producie este nlocuit cu neterminalul din partea stng
a regulii respective).
Criteriul de acceptare este epuizarea ntregului ir de intrare, iar n stiv trebuie si rmn numai simbolul
de start al gramaticii. In cazul general, cnd modelul sintactic al limbajului de tradus este o gramatic
independent de intext, analiza sintactic ascendent este cu reveniri. Analiza sintactic acendent fr
reveniri utilizeaz ca model de sintax gramaticile LR(k).
1.4 Analiza semantic. Structura sintactic poate fi folosit pentru specificarea semanticii unui limbaj.
n general, semantica (nelesul) unei construcii poate fi exprimat prin orice cantitate sau mulime de
cantiti asociate acelei construcii. O astfel de cantitate asociat se numete atribut. Ca exemple de
atribute putem meniona: o mulime de iruri de caractere, o valoare, un tip, o configuraie specific de
memorie etc. Aceast modalitate de abordare a semanticii se numete orientat de sintax (syntax
directed). Regulile care definesc atributele unei construcii se numesc reguli semantice. O specificare de
sintax mpreun cu regulile semantice asociate realizeaz o definiie orientat de sintax.
De exemplu, dac dezvoltm un evaluator de expresii, semantica expresiei 2+3 poate fi exprimat prin
valoarea 5. Dac dezvoltm un translator din form infixat n form postfxat semantica expresiei 2+3 ar
putea fi exprimat sub forma tripletului (+ 2 3).
Conceput ca o finalizare a etapei de analiz a textului surs (prin generarea codului intermediar), analiza
semantic completeaz structurile sintactice cu valorile atributelor asociate fiecrei componente de structur.
Cunoscndu-se valorile atributelor, se realizeaz:
- validare semantic a PS;
- generarea codul intermediar echivalent
Aciunile realizate n aceast ultim faz a analizei sunt urmtoarele:
- atributarea arborelui de derivare (evaluarea atributelor asociate nodurilor acestuia);
- generarea de cod intermediar.
Aceste dou obiective se realizeaz de obicei prin parcurgerea de mai multe ori a arborelui de sintax. In
practic, analiza semantic se desfoar n paralel cu analiza sintactic, prin completarea aciunilor
analizorului sintactic cu aciuni referitoare la anumite structuri de date ce reprezint atribute ale
componentelor sintactice.
Exist diverse formalismc pentru analiza semantic, ntre care amintim:
- schemele generalizate de traducere orientate pe sintax (Aho);
36
- gramaticile de atribute extinse cu aciuni de traducere (Marcotty),
Nu exist ns un model unanim acceptat Formalismele existente depind de strategia aleas n analiza
sintactic (ascendent sau descendenta)
1.5 Uniti de program. Structura general a unui program scris ntr-un limbaj de
programare convenional (imperativ, dirijat de control) presupune existenta unui program principal
i eventual a unuia sau mai multor subprograme (proceduri, funcii si subrutine) care comunic ntre
ele i/sau cu programul principal prin intermediul parametrilor i/sau a unor variabile globale.
Orice program sau subprogram surs, indiferent de limbajul n care este scris i indiferent de sintaxa
concret a acestuia este divizat n dou pri (nu neaparat distincte din punct de vedere fizic): partea de
declaraii i partea imperativa Declaraiile, denumite uneori i instruciuni neexecutabile sunt informaii
descriptive adresate compilatorului care descriu in principal atribute ale zonelor de date cum ar fi tipul,
dimensiunea de reprezentare, eventual valori initiale etc. Partea imperativ conine instruciunile ce se vor
executa n cursul rulrii (sub)programului.
Ideea reutilizrii codului precum i cea a reducerii dificultilor de proiectare i ntreinere a programelor
mari au condus n mod natural la modularizarea dezvoltrii programelor. Corespunztor, ca rezultat al
procesului de abstractizare i factorizare, apar astfel la nivelul programelor, unitati de program distincte,
numite module, cu rol bine precizat i care aduc odat ru apariia lor numeroase avantaje. Unul dintre cele
mai importante n acest sens este compilarea separat.
In
majoritatea cazurilor activitile pe care subprogramele le efectueaz sunt independente. Astfel, unul
sau mai multe subprograme pot fi grupate n module, care, fiind la rndul lor independente pot fi compilate
separat unul de cellalt, adic la momente diferite n timp i combinate mai trziu de ctre editorul de
legturi ntr-un unic program executabil. Ca urmare, dac un modul necesit modificri i celelalte nu, va fi
recompilat doar modulul modificat, editorul de legturi realiznd apoi combinarea codului obiect rezultat cu
versiunile deja compilate ale celorlalte module. Se economisete in acest fel un timp semnificativ de lucru,
ideea compilrii separate fiind extrem de util la ntreinerea bibliotecilor mari de programe.
37
1.7 Problema recunoaterii. Problema recunoaterii n gramatici
independente de context este urmtoarea: Dat o gramatic G = (V, T, S, P) i un
cuvnt w T*, care este rspunsul la ntrebarea w L(G)? Se tie c problema este
decidabil; mai mult, exist algoritmi care n timp O(|w| ) dau rspunsul la ntrebare
(Cooke-Younger-Kasami, Earley). Problema parsrii (analizei sintactice) este
problema recunoaterii la care se adaug: dac rspunsul la ntrebarea w e L(G) este
afirmativ, se cere arborele sintactic (o reprezentare a sa) pentru w.
Fie G = (V, T, S, P) o gramatic i w L(G). S notm prin
p q
()
st dr
relaia de
derivare extrem stng (dreapt) n care, pentru rescriere s-a aplicat producia p e P
(q P).
Atunci, pentru w L(G) exist o derivare extrem stng:
p1 p2 pn
S 0 1 ... n n w
st st st
Figura 1.1
Analizarea stng pentru acest cuvnt este: 1=12463466 iar analizarea
dreapt este 2=64264631. Aici am identificat fiecare producie prin numrul su.
36
Analiza sintactic descendent (parsarea descendent) poate fi considerat ca o
tentativ de determinare a unei derivri extrem stngi pentru un cuvnt de intrare.
In termenii arborilor sintactici, acest lucru nseamn tentativa de construire a unui
arbore sintactic pentru cuvntul de intrare, pornind de la rdcin i construind
nodurile n manier descendent, n preordine (construirea rdacinii, a subarborelui
stng apoi a celui drept). Pentru realizarea acestui fapt avem nevoie de urmtoarea
structur (figura 1.2):
o band de intrare n care se introduce cuvntul de analizat, care se parcurge
de la stnga la dreapta, simbol cu simbol;
o memorie de tip stiv (pushdown) n care se obin formele propoziionale
stngi (ncepnd cu S). Prefixul formei propoziionale format din terminali se
compar cu simbolurile curente din banda de intrare obinndu-se astfel
criteriul de naintare n aceast band;
o band de ieire n care se nregistreaz pe rnd produciile care s-au aplicat
n derivarea extrem stng care se construiete.
Figura 1.2
Criteriul de oprire cu succes este acela n care s-a parcurs ntreaga band de
intrare, iar memoria pushdown s-a golit. n acest caz n banda de ieire s-a obinut
parsarea stng a cuvntului respectiv. Iat un exemplu de cum funcioneaz acest
mecanism (considerm gramatica din exemplul precedent i cuvntul w = id+id*id).
Vom considera caracterul # pentru marcarea sfritului benzii de intrare (marca de
sfrit a cuvntului) precum i pentru a marca baza stivei.
Tabelul 1: Analiza sintactic descendent pentru w = id+id*id
Pasul Banda de Stiva de Banda de
intrare lucru ieire
1 id+id*id# E#
2 id+id*id# E+T# 1
3 id+id*id# T+T# 12
4 id+id*id# F+T# 124
5 id+id*id# id+T# 1246
6 id*id# T# 1246
7 id*id# T*F# 12463
8 id*id# F*F# 124634
9 id*id# id*F# 1246346
37
10 id# F# 1246346
11 id# id# 12463466
12 # # 12463466
st
36
u1 A 1 u1 1 u1u 2 u Y == u1Ay1 i demonstraia este ncheiat.
st st
Corolarul 1.3.1 Dac n parserul descendent are loc (w#, S#, )+(#,#, ) atunci
n gramatica G are loc S w
st
Demonstraie Se aplic lema precedent pentru u = w, v = , Y = S, = .
Lema 1.3.2 Dac n gramatica G are loc derivarea u i 1: V, (vezi
st
definiia 1.3.2), atunci n parserul descendent are loc calculul:
(uv#, Y#, )*(v#,#,), v T*.
Teorema 1.3.1 (Corectitudinea panerului descendent general). Se consider
gramatica redus G = (V, T, S, P) i w G T*. Atunci, n parserul descendent general
ataat acestei gramatici are loc (w#, S#, s) d* (#, #, n) (acceptare) dac i numai
dac w e L(G) i n este o analizare sintactic stng a frazei w.
Demonstraie Teorema sintetizeaz rezultatele din lemele 1.3.1 i 1.3.2.
1.8.2 Gramatici LL(k). Parserul general introdus n paragraful precedent este
un model nedeterminist iar implementarea sa pentru gramatici oarecare este
ineficient. Cea mai cunoscut clas de gramatici pentru care acest model
funcioneaz determinist este aceea a gramaticilor LL(k): Parsing from Left to right
using Leftmost derivation and k symbols lookahead. Intuitiv, o gramatic este LL(k)
dac tranziia de tip 1 din Definiia 1.3.1 se face cu o unic regul A P
determinat prin inspectarea a k simboluri care urmeaz a fi analizate n banda de
intrare. Dar s definim n mod riguros aceast clas de gramatici.
Defininiia 1.3.2 Fie G = (V, T, S, P) o gramatic, a 2* i k > 1 un numr
natural. Atunci definim:
k:a = if | a | < k then a else a1, unde a = a1P, | a1| = k,
a:k = if | a | < k then a else a2, unde a = ya2, | a2| = k.
Defininiia 1.3.3 O gramatic independent de context redus este gramatic
LL(k), k > 1, dac pentru orice dou derivri de forma:
* *
S uA u 1 ux
st st st
* *
S uA u 2 uy
st st st
37
Teorema 1.3.10 O gramatic G = (V, T, S, P) este gramatic LL(1) dac i numai
dac
pentru orice A V i pentru orice producii A P1 | P2 are loc:
FIRST (P1FOLLOW (A)) 3 FIRST (P2FOLLOW (A)) = 0 Demonstraie S
presupunem c G este LL(1). Acest lucru este echivalent cu(dup Definiia 1.3.3):
.
n acest caz avem:
36
cu 1:v = 1:v' dar 1 2.
Analiznd cele dou derivri, se constat uor c:
37
implementare al unui analizor sintactic LL(1). Presupunem c dispunem de o band
de intrare (fiier de intrare) din care, cu o funcie getnext(), se obine caracterul
(tokenul) urmtor. De asemenea dispunem de o stiv cu funciiile specifice pop() i
push() . Produciile care se aplic pe parcursul analizei le scriem ntr-o band
(fiier) de ieire cu funcia write(). Atunci algoritmul de analiz sintactic se descrie
astfel: Algoritmul 1.3.6 (Parser LL(1) )
Gramatica G = (V, T, S, P). Tabela de analiz LL(1) notat M. Cuvntul de intrare
w#.
Analiza sintactic stng n a lui w dac w L(G), eroare n caz contrar.
Sunt implementate tranziiile 1 5 folosind o stiv St.
St.push(#),St.push(S)// St = S# a = getnext(), n = s;
do {
X = St.pop();
if(X == a)
if(X != '#') getnext(); else{
if (n != s){write("acceptare"); exit(0);} else {write("eroare");
exit(1);} } //endelse else{
if(XT){write("eroare"); exit(1);} else{
if(M(X,a)
{write( else {
// M(X,a) = (P,r), r=X P, P=Y1Y2...Yn //P inlocueste pe X in stiva
for(k = n; k>0; --k) push(Yk)
write(r); //se adauga r la n
} //endelse
} //endelse } //endelse
} while(1);
Exemplul 1.3.4 S relum gramatica din exemplele precedente:
1. S E
2. S B
3. E s
4. B a
5. B begin SC end
6. C s
7. C ;SC
Mulimile FIRST i FOLLOW sunt date n tabelul urmtor:
X FIRST(X) FOLLOW(X)
S a begin s end ; s
E s end ; s
B a begin end ; s
C ; s end
Tabela de analiz LL(1) pentru aceast gramatic este dat mai jos:
M a begin end ;
S
E eroar eroare (s, 3) (s, 3) (s, 3)
e
B (begin SC eroar eroare eroar
end, 5) e e
C eroar eroare (;SC, eroar
e 7) e
36
Se vede din tabel c aceast gramatic este LL(1) (conform teoremei 1.3.13).
Iat i dou exemple de analiz, unul pentru cuvntul begin a;;a end care este din
limbajul generat de gramatica dat, iar altul pentru begin aa end care nu este
corect.
PAS INTRARE STIVA OPERAIE IEIRE
1 begin a S# expandare
a; end#
2 begin a B# expandare 2
a; end#
3 begin a begin SC potrivire 5
a; end# end#
4 a; a SC end# expandare
end#
5 a; a BC end# expandare 2
end#
6 a; a aC end# potrivire 4
end#
7 a C end# expandare
end#
8 a ;SC end# potrivire 7
end#
9 a SC end# expandare
end#
10 a EC end# expandare 1
end#
11 a C end# expandare 3
end#
12 a ;SC end# potrivire 7
end#
13 a end# SC end# expandare
14 a end# BC end# expandare 2
15 a end# aC end# potrivire 4
16 end# C end# expandare
17 end# end# potrivire 6
18 # # acceptare
1 begin aa end# S# expandare
2 begin aa end# B# expandare 2
3 begin aa end# begin SC potrivire 5
end#
4 aa end# SC end# expandare
5 aa end# BC end# expandare 2
6 aa end# aC end# potrivire 4
7 a end# C end# eroare
37
neterminal A pentru care A = Aa. Spunem c un neterminal A este stng recursiv
imediat dac exist o producie A Aa n P. S indicm mai nti un procedeu de
eliminare a recursiei stngi imediate.
Lema 1.3.7 Fie G = (V, T, S, P) o gramatic pentru care A este stng recursiv
imediat. S considerm toate A produciile gramaticii, fie ele A Aa1 | Aa2 | ... |
Aan cele cu recursie i A P1 | P2 | ... | Pm cele fr recursie imediat (prile
drepte nu ncep cu A). Exist o gramatic G' = (V', T, S, P') echivalent cu G, n care
A nu este stng recursiv imediat.
Demonstraie S considerm un nou neterminal A' 2 V i fie V' = V U{A} iar P'
se obine din P astfel:
Se elimin din P toate A -produciile;
Se adaug la P urmtoarele producii:
A PiA' 1 < i < m. A' ajA' | s 1 < j < n.
Notm cu P' mulimea de producii obinut.
S observm c A nu mai este stng recursiv n G'. Noul simbol neterminal
introdus, notat cu A', este de data aceasta drept recursiv. Acest lucru ns nu este un
inconvenient pentru analiza sintactic descendent.
S observm c, pentru orice derivare extrem stnga n gramatica G, de forma:
exist n gramatica G' o derivare extrem dreapta de forma:
A = PhA' = Phak1 A' = ... = fta^. -a^ A' = fta^.. .a^.
De asemenea, afirmaia reciproc este valabil.
Aceste observaii conduc la concluzia c cele dou gramatici sunt echivalente.
Exemplul 1.3.5 n gramatica expresiilor aritmetice:
E E+T |E-T |-T |T
T T*F | T/F | F
F (E) | a se fac transformrile urmtoare:
Produciile E E+T |E-T |-T |T se nlocuiesc cu:
E TE' | -TE', E' +T E'|-TE' | s
Produciile T T*F | T/ F | F se nlocuiesc cu:
T FT', T' *FT' | /FT' | s
Se obine astfel gramatica echivalent:
E TE' | -TE'
E' +T E'|-TE' | s
T FT'
T' *FT' | /FT' | s
F (E) | a
Aplicnd algoritmii pentru determinarea mulimilor FIRST i FOLLOW se obine:
X FIRST(X) FOLLOW(X)
E (a- s)
E' + -s s)
T (a +-s)
T' * /s + - s)
F (a */+-s)
Tabela de parsare pentru aceast gramatic este dat mai jos.
M a + - * / ( ) #
E (TE', eroare (-TE', eroare eroare (TE', 1) eroare eroare
1) 2)
E' eroare (+TE',3) (-TE', eroare eroare eroare (s, 5) (s, 5)
4)
T (FT', eroare eroare eroare eroare (FT', 6) eroare eroare
6)
T' eroare (s, 9) (s, 9) (*FT',7) (/FT',8 eroare (s, 9) (s, 9)
36
)
F eroare eroare eroare eroare ((E) 10) eroare eroare
Se observ de aici c gramatica este LL(1). S urmrim analiza sintactic pentru
expresia -(a+a)*a.
PASU INTRARE STIVA OPERAI IEIRE
L E
1. - E# expandar
(a+a)*a# e
2. - -TE'# potrivire 4
(a+a)*a#
3. (a+a)*a# TE'# expandar
e
4. (a+a)*a# FT'E'# expandar 6
e
5. (a+a)*a# (E)T'E'# potrivire 10
6. a+a)*a# E)T'E'# expandar
e
7. a+a)*a# TE')T'E'# expandar 1
e
8. a+a)*a# FT'E')T'E expandar 6
'# e
9. a+a)*a# aT'E')T'E potrivire 11
'#
10. +a)*a# T'E')T'E' expandar
# e
11. +a)*a# E')T'E'# expandar 9
e
12. +a)*a# +TE')T'E' potrivire 3
#
13. a)*a# TE')T'E'# expandar
e
14. a)*a# FT'E')T'E expandar 6
'# e
15. a)*a# aT'E')T'E potrivire 11
'#
16. )*a# T'E')T'E' expandar
# e
17. )*a# E')T'E'# expandar 9
e
18. )*a# )T'E'# potrivire 5
19. *a# T'E'# expandar
e
20. *a# *FT'E'# potrivire 7
21. a# FT'E'# expandar
e
22. a# aT'E'# potrivire 11
23. # T'E'# expandar
e
24. # E'# expandar 9
e
25. # # acceptare 5
37
S artm cum eliminm n general recursia stng ntr-o gramatic. Vom face
ipoteza c + gramatica G nu are s - producii i nu are cicluri de forma A == A.
Aceasta nu este de fapt o restricie: este tiut faptul c, pentru orice gramatic G
exist G' fr s -producii i fr cicluri astfel nct L(G') = L(G) - { s }. (vezi [Gri86],
[Juc99]). Aadar are loc urmtoarea teorem:
Teorema 1.3.13 Pentru orice gramatic G fr s - producii i fr cicluri, exist
o gramatic echivalent G' care nu este stng recursiv.
Demonstraie S considerm urmtorul algoritm:
Intrare: Gramatica G = (V, T, S, P) fr s-producii, fr cicluri.
Ieire:Gramatica G' fr recursie stng astfel ca L(G)=L(G').
Metoda: Dup ordonarea neterminalilor se fac transformri ce nu schimb
limbajul gramaticii, inclusiv prin eliminarea recursiei imediate
Se consider V = [Ai, A2, -,An|
for (i=1; i < n;)
for (j=1; j < i 1;){
for (Ai AjY e P) {
P = P - { Ai AjY };
for (Aj p e P ) P = P U { Ai Py};
} //endfor
8. Se elimina recursia imediata pentru Ai;
//endfor
} //endfor
8. V'= V; P'=P; // V s-a modificat la 7 iar P la 4-6
1.8.6 Funcii de numrare i formula multinomului. In cele ce urmeaz se va lucra cu mulimi finite.
Numrul de elemente din mulimea finit X va fi notat cu |X|. Unei funcii / de la X in Y, unde X si Y sunt mulimi
finite, astfel nct X = [ x \ , . . . , x n } si Y = [ y i , . . . , y m } , i se pune in corespondenta o aranjare a mulimii X de
obiecte in mulimea Y de csue, astfel nct in csua s intre obiectele din mulimea [x|x E X , / (x) = y }. Aceasta
corespondent este o bijecie. De asemenea, se poate stabili o bijecie intre mulimea funciilor / : X Y si mulimea
n-uplelor formate cu elemente din Y sau a cuvintelor de lungime n formate cu litere din mulimea Y astfel: unei
funcii / i se pune in corespondenta cuvntul / ( x i ) / ( x 2 ) . . . /(xn) in care ordinea literelor este esenial.
PROPOZIIA 1. Numrul funciilor / : X Y este egal cu mn, daca |X| = n si |Y| = m.
Prin definiie se noteaz [x]n = x(x 1). . . (x n + 1) si [x]n = x(x + 1). . . (x + n 1), ambele produse
coninnd cte n factori consecutivi.
PROPOZIIA 2. Numrul funciilor injective / : X Y, unde |X| = n si | Y| = m este egal cu [m ]n.
Aranjamente de m luate cate n se numesc cuvintele de lungime n formate cu litere diferite din mulimea Y, iar
numrul lor este [m]n. Dac m = n, aceste cuvinte de lungime n formate cu toate literele din Y se numesc permutri
ale mulimii Y si numrul lor este egal cu [n]n, care se noteaz cu n! = 1 2 n si se numete n factorial. Prin
definiie 0! = 1.
Daca mulimea Y este o mulime ordonat astfel nct y1 < y2 < . . . < yn, un cuvnt de lungime n format cu litere
din Y, yil . . . yin se numete cresctor dac yil < yi2 < . . . < yin si strict cresctor daca yil < yi2 . . . < yin. Cuvintele strict
cresctoare de lungime n formate cu m simboluri se mai numesc combinri de m luate cte n, iar cele cresctoare se
numesc combinri cu repetiie de m luate cte n.
36
PROPOZIIA 3. Numrul cuvintelor strict cresctoare de lungime n formate cu m simboluri este egal cu
[m]n/n!. Acest numr este egal si cu numrul submulimilor cu n elemente ale unei mulimi cu m elemente. Numerele
[m]n se mai noteaz prin si se numesc numere binomiale cu parametrii m si n.
PROPOZIIA 4. Numrul cuvintelor cresctoare de lungime n formate cu m simboluri este egal cu [m] n/n!.
Demonstraie. S observam mai nti ca [m] n/n! = (m+n_^. Putem presupune ca Y = {1,. . . ,m} si vom stabili o
bijecie de la mulimea cuvintelor cresctoare de lungime n formate cu litere din Y (cu ordinea naturala) pe mulimea
cuvintelor strict cresctoare de lungime n formate cu litere din alfabetul extins {1,. . . , m + n 1} in felul urmtor:
^(yil yj2 . . . yin) = yil |yi2 + 1|. . . |yin + n 1. Se verific imediat ca ^ este o bijecie, de unde rezult propoziia,
deoarece numrul cuvintelor strict cresctoare de lungime n formate cu litere dintr-un alfabet cu m + n 1 simboluri
este egal cu
, (1)
care este valabil pentru orice a , b dintr-un inel comutativ. Demonstraia formulei (1) se poate face innd
seama ca (a + b)n = (a + b)(a + b ) . . . (a + b), unde in produs sunt n factori. Pentru a obine monomul an-kbk trebuie sa l
alegem pe b din k paranteze si pe a din parantezele ramase, in numr de n k. Dnd cate un numr de ordine celor n
paranteze, trebuie sa selectam k numere de ordine ale parantezelor din care l alegem pe b din mulimea de numere
{1,. . . , n}, ceea ce se poate face in (jkj moduri, deci coeficientul
monomului an-kbk este egal cu nk .
PROPOZIIA 5. Numrul de aranjri ale unei mulimi de n obiecte X = . . . ,xn} intr-o mulime de p csue Y =
{y1,... ,yp}, astfel nct csua yj s conin n obiecte pentru orice 1 < i < p (n1 + . . . + np = n) este egal cu
Demonstraie. Obiectele din csua y1 pot fi alese in(n/n1) moduri, obiectele din csua y2 pot fi alese din cele
n n1 obiecte rmase in (n-n1/n2) moduri etc. Rezulta in total un numr de posibiliti egal cu
Acest raport de factoriale se mai noteaz si se numete numr multinomial, care generalizeaz
numerele binomiale (cazul p = 2) si apar in formula multinomului care extinde relaia (1):
(2)
Demonstrata formulei (2) a multinomului se poate face astfel: Este clar c dezvoltarea ( a \ + . . . + ap)n va
conine o suma de monoame de forma an , unde numerele naturale n \ , . . . n p verific ni+ . . .+np = n. Trebuie gsit
coeficientul acestui monom, deci de cate ori apare el in puterea a na a expresiei a1 + . . . + ap. Pentru aceasta se
procedeaz ca la formula binomului, dndu-se numerele de ordine 1 , . . . , n parantezelor din dezvoltarea (a1 + . . . +
ap)n = (a1 + . . . + a p ) . . . (a1 + . . . + ap) si observnd c pentru a obine monomul a*,11 trebuie s-l alegem pe a1
din n1 paranteze,... ,pe ap din np paranteze. Ori aceasta este echivalent cu plasarea numerelor de ordine 1 , . . . , n ale
parantezelor in p cutii, astfel nct cutia 1 sa conin n 1 numere,...,cutia p sa conin np numere, ceea ce se poate realiza
in (ni n n ) moduri, conform propoziiei 5.
PRINCIPIUL INCLUDERII I AL EXCLUDERII I APLICAII Principiul includerii si al excluderii constituie
o generalizare a identitii:
(3)
unde A, B C X.
TEOREMA 1 (Principiul includerii si al excluderii). Dac Aj (1 < i < q) sunt submulimi ale unei mulimi X,
are loc relaia:
37
(4)
r
Demonstra e. Vom face demonstraia prin inducie dup q. Pentru q = 2 se obine relaia (3). Fie q > 3, sa
presupunem formula (4) adevrata pentru q 1 mulimi si s o demonstrm pentru q mulimi. Avem:
. Aplicnd
(5)
. (6)
(7)
Daca m = n se obine snn = n!, iar daca m > n nu exist surjectii de la X pe Y, deci xn>m = 0 (identitile lui
Euler).
(8)
Numerele s(n, k) se pot calcula prin recurenta, utiliznd relaiile s(n, 0) = 0, s(n, n) = 1 si s(n + 1, k) = s(n, k
1) ns(n, k), ultima relaie obinndu-se prin egalarea coeficienilor lui xk in cei doi membri ai egalitii [x]n+1 =
[x]n(x n). Se obine tabelul urmtor, unde s(n, k) = 0 pentru n < k.
s(n, k) k=0 1 2 3 4 5 ...
n=1 0 1 0 0 0 0
36
2 0 -1 1 0 0 0
3 0 2 -3 1 0 0
4 0 -6 11 -6 1 0
5 0 24 -50 35 -10 1
Numrul lui Stirling de spea a doua, notat S ( n , m), este numrul partiiilor unei mulimi cu n elemente in
m clase. S observm c att ordinea claselor, cat si ordinea elementelor intr-o clas a unei partiii sunt indiferente. De
exemplu, dac avem X = [ a , b , c , d}, partiiile cu trei clase ale acestei mulimi sunt: {(a), (b), (c, d)}, {(a), (c), (b,
d)}, {(a), (d), (b,c)}, {(b), (c), (a, d)}, {(b), (d), (a, c)}, {(c), (d), (a, b)}, deci S(4, 3) = 6.
Numerele lui Stirling de spea a doua pot fi calculate prin recurent astfel: Considernd mulimea celor S(n, k
1) partiii ale unei mulimi cu n elemente in k 1 clase, putem obine S(n, k 1) partiii a n + 1 elemente in k clase,
adugnd la fiecare partiie o noua clasa formata dintr-un singur element si anume al ( n + 1)-lea. S considerm acum
o partiie a n elemente in k clase. Deoarece putem aduga al (n + 1)-lea element la clasele deja existente in k moduri
diferite si toate partiiile a n + 1 elemente cu k clase se obin fr repetiii printr-unul din cele dou procedee expuse,
rezult c
pentru 1 < k < n si S(n, 1) = S(n, n) = 1. Aceste relaii permit calculul prin recurenta al numerelor S(n, m),
obinndu-se tabelul urmtor:
S(n, m) m =1 2 3 4 5 ...
n=1 1 0 0 0 0
2 1 1 0 0 0
3 1 3 1 0 0
4 1 7 6 1 0
5 1 15 25 10 1
Pentru calculul direct al numerelor lui Stirling de spea a doua, vom arta ca S(n,m) = xn>m/m!. Intr-
adevr, oricrei surjectii / a mulimii X = . . . , xn} pe mulimea Y = { y 1 , . . . , yn} ii corespunde o partiie a mulimii X
cu m clase si anume /-1(y1), /- 1 ( y 2 ) , . . . , /-1(ym). Deoarece intr-o partiie nu conteaz ordinea claselor, rezult c n!
funcii surjective de la X pe Y vor genera o aceeai partiie a mulimii X. innd seama de (7) rezult:
(9)
i cuvntul baacde din limbajul generat de gramatic. Vom ncerca s refacem drumul parcurs de un
analizor cu strategie ascendent care pleac de la irul baacde i gsete n final neterminalul S. Pe parcurs
vom evidenia problemele mai deosebite ale acestui tip de analiz.
Prototipul analizei sintactice ascendente este automatul "push-down" extins. Dup cum se tie, el poate
simula n funcionarea sa derivarea dreapt ntr-o gramatic independent de context, derivare parcurs ns
n ordine invers. Automatul "push-down" extins identific pentru acesta n vrful stivei pri drepte ale
produciilor pe care le "reduce" la neterminalul prii stngi corespunztoare. n vederea completrii prii
drepte, automatul i aduce pe rnd n stiv simbolurile de la intrare. irul este acceptat dac au rmas doar
simbolul de nceput.
n cazul exemplului considerat, un analizor sintactic ascendent va cuta pri dreapta ale produciilor n
irul de intrare. Le gsete sub forma: a i d. Desigur, analiznd n mod natural, de la stnga la dreapta, dup
depirea lui b, va prefera nlocuirea primului a cu A, rezultnd irul bAacde. n termenii arborilor de
derivare subirul analizat se prezint ca n figura .2.1.
Dup cum vom vedea n continuare, un analizor ascendent creeaz o "pdure" de arbori pe care
ncearc s-i reuneasc n final ntr-un unic arbore. n cazul nostru, el a creat un arbore format dintr-un nod
etichetat b i un arbore ca n figura 2.1.
37
Figura 2.1
Figura 2.2.
ncercnd n continuare s gseasc pri dreapta (de aceast dat n bAacde) analizorul va
gsi, n ordine : Aa, a i d. Ordinea de analiz de la stnga la dreapta a intrrii impune de data
aceasta dou posibiliti: Aa i a. Ambele se reduc la A, dar nu sunt totui la fel de bune. ntr-
adevr, reducerea lui a la A conduce la irul bAAcde care apoi prin reducerea lui d la B conduce
la bAAcBe n care analizorul nu mai poate recunoate nici o parte dreapt i analiza pe aceast
cale euat, fiind necesar revenirea la decizia reducerii lui a. Dac se alege reducerea lui Aa la A
se obine irul bAcde i corespunztor "pdurea" din figura 2.3
Concluzia este, desigur, acceptarea irului.
S observm c analiza a refcut n ordine invers derivarea dreapt:
Dup adugarea lui e i d la pdure, singurul ir de redus este d. Dup reducerea lui
obinem bAcBe i pdurea din figura 2.4.
n fine, adugnd i ultimul simbol la pdurea de arbori, se observ c noul ir, ca i
rdcinile arborilor pdurii, alctuiesc partea dreapt a primei producii, deci putem reduce la S,
adic ajungem la arborele de derivare din figura 2.5.
Figura 2.3
Figura 2.4
36
Figura 2.5
prin reduceri:
n aceste transformri, subirul redus joac un rol esenial. El trebuie mai nti identificat i
apoi nlocuit cu un neterminal. Acest subir este ntotdeauna cel mai din stnga subir dintr-o
form propoziional dreapt care poate fi redus astfel nct s se refac n sens invers un pas
ntr-o derivare dreapt. El poart numele de capt (n engl.: handle).
Definiia 2.5. Captul unei forme propoziionale dreapta este irul a dac n
gramatica respectiv exist derivarea:
n cazurile concrete captul este dat printr-o producie A a i poziia lui a n /3aa>
(adic limitele lui din stnga i din dreapta).
n arborele de derivare asociat unei forme propoziionale captul apare ca cel mai din
stnga subarbore complet (format deci dintr-un nod-rdcin i toi descendenii si).
Utiliznd noiunea de capt, analiza ascendent apare ca un proces de formare i
identificare a capetelor formelor propoziionale dreapta obinute i de reducere a lor la
neterminale.
Exemplul 2.5. Fie gramatica:
37
n ceea ce privete identificarea captului, se poate arta c ntr-o parcurgere de la stnga la
dreapta a irului de intrare nsoit de reduceri succesive ale captului fiecrui forme
propoziionale dreapta, la un moment dat, analizorul sintactic nu trebuie s se ntoarc oricnd n
pdurea de arbori deja format pentru a cuta captul, ci acesta apare n mod natural n
vecintatea imediat a punctului de analiz.
Mai precis, s considerm cele dou posibiliti de apariie a captului. Fie mai nti
derivarea:
36
- se semnalizeaz eroarea prin modificarea strii procesorului.
4) Acceptare (are loc la ntlnirea marcajului $ pe banda de intrare i a irului $Z0 n stiv,
Z0 T):
- se semnalizeaz acceptarea prin modificarea strii procesorului.
Starea mainii este sintetizat ctre configuraia sa ($aX,x$, ), unde $aXeste coninutul
stivei cu vrful X reprezentat spre dreapta, x$ este irul de intrare cu marcajul de sfrit al irului
$ i n este irul numerelor de producii cu care s-au fcut reducerile.
Configuraia iniial este ($,x$, ),unde x este irul de analizat, iar configuraiile finale sunt
de forma ($Z0,$, i).
Reducerea cu (,A,i) determin o micare a mainii de forma :
37
simbolurile ce alctuiesc forma propoziional. Relaiile, trei la numr, sunt notate de obicei cu
<,=,>. n cazul precedenei simple, ntr-o derivare de forma:
captul XK+1XK ...X 2 X1 este delimitat prin cele trei relaii astfel :
- la dreapta: X1>a,
- la stnga: XK+1<Xk,
- n interiorul captului: Xi+1=Xi, pentru i=1,.........,k-1. De asemenea, ntre simbolurile
consecutive din aXK+1 avem relaii < sau =.
Presupunnd c ntre dou simboluri oarecare din gramatic exist cel mult o relaie,
depistarea captului de ctre MDR este unic determinat. Problema care rmne este cea a
alegerii produciei cu care se face reducerea . Pentru a nltura aceast nedeterminare vom
presupune c gramatica folosit este unic invertibil, adic n cadrul produciilor ei nu exist
dou pri drepte identice. Cele de mai sus sunt formal introduse prin urmtoarele definiii:
Definiia 2.7. Se numesc relaii de preceden Wirth - Weber relaiile :
n ciuda asemnrii lor ca notaie cu relaiile <,=,> din algebr, relaiile Wirth -Weber nu au
proprietile acestora. Reprezentarea cea mai folosit pentru relaiile Wirth -Weber este cea tabelar
Definiia 2.8. O gramatic independent de context G=<N, E ,P,S> este proprie dac nu are
simboluri inutile, dac nu exist derivri de forma pentru A e N i dac nu are X - producii n
afar, eventual, a produciei S X n care caz S nu apare n nici o parte dreapt a vreunei producii. O
gramatic independent de context, proprie, fr X -producii, n care ntre orice dou simboluri exist cel
mult o relaie de preceden Wirth-Weber, se numete gramatic de preceden simpl.
Mulimea perechilor R. este uor de construit : se caut n prile dreapta ale produciilor
toate perechile de simboluri consecutive:
<
36
Pentru calculul perechilor din mulimea R o vom considera iniial vid. Fie o mulime M
iniializat cu R. n M vom cuta perechile de forma (B,Y). n exemplul nostru ele sunt: (A,A),(A,a),(S,a).
Se calculeaz PRIM(Y). Apoi, pentru fiecare B-producie, se ia ultimul simbol al prii dreapt, fie el X.
Se adaug la toate perechile (X,a) cu a e PRIM(Y), iar la mulimea M perechile (X,a) cu X e N. n
exemplul nostru, pentru (A,A) avem : PRIM(A)={a,b}, iar ultimul simbol al prii dreapta este a. Deci
perechile adugate la R sunt (a,a) i (a,b). Mulimea R rezultat este:
S A a b c $
S
A < = < < =
a > > >
b < < <
c > >
$ <
Deoarece n fiecare intrare a tabelului exist cel mult o relaie de preceden, gramatica
este de precedent simpl.
La baza analizei limbajelor generate de gramatici de precedent st urtoarea teorem:
Teorema 2.5. Fie G=<N, S ,P,S> o gramatic proprie fr - producii i fie o derivare
dreapta n aceast gramatic a irului $S$:
Atunci:
a) pentru k < i < p, Xi+1 = Xi;
b) Xk +1 < Xk ;
a) pentru 1 < i < k -1, Xt+1 = Xt;
c) X1 > a1.
Demonstraie: Folosind metoda induciei pentru numrul de pai n derivare. Dac derivarea este
ntr-un pas: , unde k>1, atunci din definiia 2.7. avem: $ < Xk, Xi = Xi+1
pentru 1 < i < k - 1 i Xi > $. Deci cerinele teoremei sunt ndeplinite.
S considerm afirmaiile teoremei adevrate pentru n pai n derivare, n>0 , i fie
derivarea dreapta n n+1 pai:
Deoarece : avem:
37
c) pentru 1 < i < k -1, Xi+1 = Xt;
d) X1 > a1 ;
e) ntre orice dou simboluri din irul X p ...X1a1 nu mai exist nici o alt relaie n afara celor
precizate n a)..d).
Demonstraie. Eviden, datorit definiiei 2.8.
a + * ( ) $
D, E E D, E E
s3 s2
s E D, S4 D, s5 E E A
1
S D, E E D, E E
2 s3 s2
S E R, 4 R, 4 E R, 4 R,
3 4
S D, E E D, E E
4 s3 s2
S D, E E E E
5 S3
S E D, S4 D, s5 E D, E
6 S9
S E D, S4 R, D, s5 R, E R1 R,
7 1 1 1
S E D, S4 R, D, S5 R, E R, 2 R,
8 2 2 2
S E R, 3 R, 3 E R, 3 R,
9 3
36
Se consider conflictul din TA(s7 ,*) ntre (D,s5) i (R,1). Analizorul are de ales ntre a
deplasa ,,* ''(conform lui (D, s5)) i a reduce cu producia E E +E i a deplasa ,+' vom prefera
reducerea ceea ce reflect opiunea pentru asociativitatea la stnga, cea mai folosit de obicei. n
al doilea caz, din acelai motiv aplicat ns operatorului *, vom prefera tot reducerea.
Cu aceste modificri, tabela de aciuni devine cea din fig.2.8.
a
+ * ( ) $
S D, E E D, E E
0 S3 s2
s E D, D, E E A
1 S4 S5
S D, E E D, E E
2 S3 s2
S E R, 4 R, 4 E R, 4 E,
3 4
S D, E E D, E E
4 S3 s2
S D, E E D, E E
5 S3 s2
S E D, D, E D, E
6 S4 S5 S9
S E R, 1 D, E R, 1 R,
7 S5 1
S E R, 2 R, 2 E R, 2 R,
8 2
S E R, 3 R, 3 E R, 3 R,
9 3
Observaie : Analizorul care folosete aceast tabel va recunoate acelai limbaj cu
limbajul recunoscut de analizorul ce folosete tabela din figura III.2.24 (Exemplul 2.10) dar va
evita reducerile prin producii singulare i va beneficia astfel de o tabel mai mic. n mod
asemntor se pot obine pentru gramatici ambigue i tabelele LR(1) i LALR(1).
Bibliografie
37
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include<string.h>
int disparte(char S[], char *ss,char c, int a)
{ int k=0;
if (S[a]==c)
{a++;
for(;a<strlen(S);a++)
if(S[a]!=' '&&S[a]!=')'&&S[a]!=';'&&S[a]!='\0') {ss[k]=S[a]; k++;}
else {ss[k]='\0'; break;}
}
else
{for(;a<strlen(S);a++)
if(S[a]==c) break;
a++;
for(;a<strlen(S);a++)
if(S[a]!=' '&&S[a]!=')'&&S[a]!=';'&&S[a]!=';') {ss[k]=S[a]; k++;}
else {ss[k]='\0'; break;}
}
return a;
}
void simulare_switch()
{
char ch,s1[256],s2[256],s3[300],s4[300],s5[300];
int i=0,j=0;
FILE *f;
clrscr();
f = fopen("switch.txt", "r");
window(1,1,80,50);
textbackground(1);
textcolor(15);
clrscr();
int k=0,l=0;
i=0;
puts("\tOperatorul 'Switch' analizat este:\n");
do
{
do
{
ch=fgetc(f);
s1[i]=ch; i++; printf("%c",ch);
} while(ch!='\n'&&ch!=EOF&&ch!=' ');
s1[i-1]='\0';
//puts(s1);
i=0;
if(strcmp(s1,"switch")==0) {l=1;}
if(!strcmp(s1,"case")||!strcmp(s1,"default:")) k++;
if(!strcmp(s1,"break;")) j++;
} while (ch!=EOF );
puts("\n\tAnaliza sintactica a operatorului 'Switch'...\n");
if(l)
36
{if (j>k) printf("\nIn exprsia data lipseshte un 'case' sau instructiunea optionala 'default'");
else if(j<k) printf("\nExpresia switch este incorecta deoarece lipseste intreruperea 'break' a
instructiunii");
else printf("\nDin punct de vedere sintatic operatorul SWITCH a fost oganizat corect");
}
else printf("\nIn instructiunea data lipseshte cuvintul chee 'switch'");
fclose(f);
getch();
}
void main()
{ char s[100],s1[10],s2[10],s3[10],s4[10];
char *semn[5]={"!=","<=",">=","<",">"},*oper[6]={"++","--","+=","-=","*=","/="};
int i,j,k,l,d;
window(1,1,80,50);
textbackground(1);
textcolor(15);
clrscr();
simulare_switch();
et1:
window(1,1,80,50);
textbackground(1);
textcolor(15);
clrscr();
clrscr();
puts("Introdu expresia for: ");
//gets(s);
strcpy(s,"for (i=0;i<=n;i+=2)");
puts(s);
for(i=0;i<strlen(s);i++)
if(s[i]!=' '&&s[i]!='(') {s1[j]=s[i]; j++;}
else {s1[j]='\0'; break;}
i=disparte(s,s2,'(',i);
i=disparte(s,s3,';',i);
i=disparte(s,s4,';',i);
int v=0;
puts("Verificarea sintaxei a operatorului 'for'");
if(!strchr(s,'(')) {puts("In exprsia data lipseste '('"); v++;}
if(!strchr(s,')')) {puts("In exprsia data lipseste ')'"); v++;}
k=0;
for(l=0;l<strlen(s);l++)
if(s[l]==';') k++;
if(k!=2) {puts("In expresia data lipseste ';'"); v++;}
if(strlen(s1)==3&&s1[1]!='=') {puts("Inexpresia data lipseste '='"); v++;}
if (v) {puts("In expresia introdusa sunt erori doritzi sa o reintroducetzi? da-'y',nu-'n'");
et3: char ch=getch();
if (ch!='y'&&ch!='n') goto et3;
if(ch=='y') goto et1;
else exit(0);
}
else puts("\n\tVerificarea sintaxe a expresiei a trecut cu succes\n");
37
for(i=0;i<5;i++)
if(strstr(s3,semn[i])) {printf("\nSemnul conditional utilizat este: %s",(semn[i])); break;}
for(j=0;j<6;j++)
if(strstr(s4,oper[j])) {printf("\nSemnul operational utilizat este: %s",oper[j]); break;}
l=s2[2]-48;
k=0; int ll=1;
for (i=strlen(s4)-1;i>0;i--)
if(s4[i]>47&&s4[i]<59) {k+=(s4[i]-48)*ll; ll*=10;}
else break;
int n;
printf("Valoarea de modificare a parametrului ciclului este=%d\n\n",k);
puts("Introdu vloarea lui n");
scanf("%d",&n);
for(i=0;i<5;i++)
if(strstr(s3,semn[i])) {puts(semn[i]); break;}
/////////////// Simularea lui for
int t;
t=l; l=0;
while (1)
{ switch(i)
{ case 0: if (t==n) goto et; break;
case 1: if (t>n) goto et; break;
case 2: if (t<n) goto et; break;
case 3: if (t==n) goto et; break;
case 4: if (t==n) goto et; break;
}
switch(j)
{ case 0: t++; break;
case 1: t--; break;
case 2: t+=k; break;
case 3: t-=k; break;
case 4: t*=k; break;
case 5: t/=k; break;
}
l++;
}
et: printf("\nnumarul de pashi de executzie este=%d\n",l);
/////////////// sf Simularii
getch();
36