Sunteți pe pagina 1din 5

Page 1

extras din "PROIECTAREA COMPILATOARELOR", Grigoras

Algoritm de trecere de la o expresie regulat la


automatul (nedeterminist, apoi la cel determinist) echivalent
S transpunem construciile din teorema 1.2.1 ntr-un algoritm pentru transformarea
unei expresii regulate n automat finit. Mai nti s observm c fiecare din apariiile
operatorilor | i * dintr-o expresie regulat E introduce dou noi stri n automatul
construit, pe cnd operatorul * nu introduce alte stri (figura 1.8). De asemenea, pentru
orice apariie a unui simbol din , ct i pentru , dac acesta apare explicit n E, este
nevoie de 2 stri n automatul construit. Aadar, dac n este numrul de simboluri din E
iar m este numrul de paranteze mpreun cu apariiile simbolului *, atunci numrul
strilor automatului echivalent cu E este 2(n m).
S mai observm c, din orice stare a automatului, se fac cel mult dou tranziii: fie o
tranziie cu un simbol din , fie una sau dou - tranziii, fie zero tranziii. Atunci,
reprezentarea automatului echivalent cu o expresie regulat se poate face cu un tablou
de dimensiune p3 unde p este numrul strilor (acestea sunt numerotate de la 1 la p),
prima coloan conine simbolurile cu care se fac tranziiile iar urmtoarele dou coloane
conin strile rezultate n urma tranziiilor. Pentru descrierea algoritmului o s
identificm cele trei coloane prin vectorii simbol, next1, next2.
Algoritmul pe care-l descriem mai jos este datorat lui Rytter (Ryt91).
Algoritmul 2.1.1
Intrare: Expresia regulat E cu n simboluri dintre care m sunt paranteze i apariii ale
operatorului produs;
Ieire: Vectorii simbol, next1, next2 de dimensiune p = 2(n-m) ce descriu automatul cu
- tranziii echivalent cu E;
Metoda:
1. Se construiete arborele ataat expresie E (o metod se d mai jos);

Page 2

2. Se parcurge arborele n preordine i se ataeaz nodurilor vizitate, exceptnd pe cele


etichetate cu *, respectiv numerele 1, 2, , n-m;
3. Se parcurge arborele n postordine i se ataeaz fiecrui nod N o pereche de
numere (i, f) care reprezint starea iniial respectiv final a automatului
corespunztor subarborelui cu rdcina N, astfel:
3.1. Dac nodul are numrul k (de la pasul 2) atunci N.i = 2k-1, N.f = 2k;
3.2. Dac nodul este etichetat * atunci N.i = S.i iar N.f = D.f (S i D sunt fii lui N,
stng respectiv drept);
4. for(1<= j <=2(n - m)) {simbol[j] = , next1[j] = next2[j] = 0}
5. Se parcurge din nou arborele obinut. Dac N este nodul curent iar S i D sunt fii
si, atunci, n funcie de eticheta lui N, se execut urmtoarele:
5.1. Dac N este etichetat cu |:
next1[N.i] = S.i, next2[N.i] = D.i, next1[S.f] = N.f, next1[D.f] = N.f
5.2. Dac N este etichetat cu * atunci next1[S.f] = D.i
5.3. Dac N este etichetat cu * (D nu exist n acest caz):
next1[N.i] = S.i, next2[N.i] = N.f, next1[S.f] = S.i, next2[S.f] = N.f
5.4. Dac N este etichetat cu a (deci este frunz):
simbol[N.i] = a, next1[N.i] = N.f
Construcia arborelui:
Intrare:
Expresia regulat E = e0e1en-1
Precedena operatorilor: prec(|) = 1, prec(*) = 2, prec(*) = 3.
Ieire:
Arborele asociat t.
Metoda:
Se consider dou stive: STIVA1 stiva operatorilor, STIVA2 stiva
operanzilor (care va conine arborii pariali construii).
1. i = 0;
2. while(i < n){
3.
c = ei;
4.
switch(c){
5.
case ( : {STIVA1.push(c); break;}
6.
case operand : {STIVA2.push(c); break;}
7.
case ) : {
8.
do{build_tree();}while(STIVA1.top()!= ));
9.
STIVA1.pop(); break;
}//endcase
10.
case operator: {
11.
while(prec(STIVA1.top())>=prec(c))build_tree();
12.
STIVA1.push(c); break
}//endcase
}//endswitch
}//endwhile
13.
while(STIVA1!= ) build_tree();
14.
t = STIVA2.pop();
build_tree(){
op = STIVA1.pop();
D = STIVA2.pop();
switch(op){
case *: {
t = tree(op, D, NULL);
STIVA2.push(t); break;
}
case |: case*:{
S = STIVA2.pop();
t = tree(op, S, D);
STIVA2.push(t); break;
}
}

Page 3

Exemplul 2.1.1 S considerm expresia E = a*b | bb(a | c)*.


1. Arborele expresiei este prezentat n figura 2.1.
2. Nodurilor arborelui le sunt ataate respectiv numerele 1, 2, , 10 prin parcurgerea
n preordine i exceptnd nodurile produs.
3. Numrul strilor automatului va fi p = 20. Dup parcurgera n postordine a
arborelui, fiecare nod are ataat o pereche (i, j) (figura 2.2).
4. Se iniializeaz vectorii simbol, next1 i next2.
5. Tabela de tranziie a automatului, n urma aplicrii procedurilor descrise la 5 n
fiecare nod al arborelui, este dat n continuare.
|
1
*
*

*
4

b
9

10

Figura 2.1

*
(3,4)
(5,6)

+ 1
(1,2)

(3,8)
4

b
* (9,12)
(7,8)
6 b
5
b
(9,10)
(11,12) 9
a
(17,18)

(9,14)
7

(13,14)
8
(15,16)

+
10

(19,20)

Figura 2.2
Tabela de tranziie a automatului:
p
1
2
3
4
5
6
7
8
9

simbol[p]

a
b
b

next1[p]
3
0
5
7
6
5
8
2
10

next2[p]
9
0
4
0
0
4
0
0
0

Page 4

10
11
12
13
14
15
16
17
18
19
20

a
c

11
12
13
15
2
17
15
18
16
20
16

0
0
0
14
0
19
14
0
0
0
0

Teorema 2.1.1 Algoritmul 2.1.1 este corect: automatul cu - tranziii obinut este
echivalent cu expresia regulat E.
Demonstraie S observm c modul n care au fost alese perechile (i, f) de stri pentru
fiecare nod al arborelui construit corespunde construciilor din teorema 1.2.1. De
asemenea tranziiile care se definesc n pasul 5 al algoritmului urmresc construcia din
teorema amintit. Aadar, automatul obinut este echivalent cu expresia dat la intrare.

De la un automat cu -tranziii la automatul


determinist echivalent
n paragraful precedent am descris procedeul de trecere de la o expresie regulat la
automatul finit echivalent. Programul care descrie activitatea acestui automat finit pentru
un cuvnt de intrare este de fapt analizorul lexical. Pentru ca acest analizor s fie eficient
este de dorit ca automatul obinut s fie determinist. Cum prin procedeul descris n
teorema precedent se obine un automat cu - tranziii (nedeterminist deci), s indicm
o modalitate de trecere de la un automat cu - tranziii la automatul determinist
echivalent. Mai nti s descriem un algoritm pentru calculul mulimii Cl(S) = (S, ).
Algoritmul 2.2.1
Intrare:
Automatul (cu - tranziii) A = (Q, , , q0, F), S Q.
Ieire:
Cl(S) = (S, ).
Metoda:
Stiva STIVA se iniializeaz cu S i pentru fiecare q din top, strile din
(q, ) ce nu au fost puse n Cl(S) se adaug n Cl(S) i n stiv.
1. R = S; STIVA = S;
2. while (STIVA ) {
3.
q = STIVA.pop(); // Se extrage q din stiv
4.
T = (q, ) ;
5.
if(T ) {
6.
for ( p T ) {
7.
if ( p R) {
8.
R = R {p} ;
9.
STIVA.push(p);//Se adaug p in stiva
}//endif
}//endfor
}//endif
}//endwhile
10.
Cl(S) = R;

Page 5

Algoritmul 2.2.2 Transformarea unui automat cu - tranziii n automat finit


determinist.
Intrare:
Automatul (cu - tranziii) A = (Q, , , q0, F).
Procedura de calcul pentru Cl(S) (Algoritmul 2.2.1).
Ieire:
Automatul determinist A = (Q, , , q0, F), echivalent cu A.
Metoda:
Se construiesc strile lui A ncepnd cu q0 i continund cu cele
accesibile prin tranziii cu simboluri din alfabet.
1. q0 = Cl(q0); Q = {q0} ;
2. marcat(q0) = false; F = ;
3. if ( q0 3 F ) then F = F 4 {q0} ;
4. while (q Q && !marcat(q)){//q este nemarcat
5.
for(a ){
6.
p = Cl(( q, a)); // = (q, a)
7.
if ( p ) {
8.
if ( p Q) {
9.
Q = Q 4 {p};
10.
marcat(p) = false;
11.
(q,a) = p ;
12.
if(p 3 F != )then F = F 4 {p};
}//endif
}//endif
}//endfor
13.
marcat(q) = true;
}//endwhile

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