Sunteți pe pagina 1din 8

Definirea relaiilor de preceden

Analiza sintactic bazat pe precedena operatorilor


(ASPO)

n ASPO se definesc trei relaii de preceden disjuncte, notate ,= i , care


se stabilesc ntre anumite perechi de terminale. Pe baza acestor relaii se
selecteaz captul formei propoziionale, n stiva analizorului. Semnificaia lor
este urmtoarea:

ASPO se poate aplica doar la o clas redus dar important de gramatici iar
analizorul se poate construi uor manual, pe principiul de lucru al ASDR.
Gramatica trebuie s ndeplineasc urmtoarele dou cerine:
1) S nu aib producii vide (cu n partea dreapt).
2) n nici o parte dreapt s nu fie dou neterminale adiacente.
Gramaticile care satisfac ultima proprietate se numesc gramatici de operatori.

Relaia

Exemplu: Urmtoarea gramatic pentru expresii nu este gramatic de


operatori:
EEAE(E)-Eid
A+ - /
Ea poate fi transformat ntr-o gramatic de operatori prin substituirea lui A
cu fiecare din alternativele sale:
EE+E E-E EE E/E EE (E) -E id
Ca tehnic general de analiz sintactic, ASPO are o serie de dezavantaje:
- Sunt dificil de prelucrat acei atomi care au dou precedene diferite
(exemplu: semnul minus, care este att operator unar ct i binar).
- Relaia ntre analizor i gramatic nu este ntotdeauna biunivoc ceea ce
face ca analizorul s accepte iruri care nu fac parte din limbajul definit de
gramatic.
- Clasa de gramatici analizabile prin tehnica ASPO este redus.
Totui, datorit simplitii, n numeroase compilatoare s-a utilizat aceast
tehnic exclusiv pentru expresii, instruciunile i construciile de nivel mai nalt
fiind analizate prin alte metode (de exemplu, cu descendeni recursivi). S-au
construit ns i ASPO pentru limbaje ntregi.

Semnificaia

a b

a cedeaz precedena lui b

a = b

a are aceeai preceden ca b

a b

a are preceden fa de b

Aceste relaii se deosebesc n esen de relaiile algebrice <, = i > din


urmtoarele motive:
au cu totul alt semantic;
este posibil ca ntre dou terminale s nu existe nici o relaie de preceden;
este posibil ca ntre dou terminale s existe simultan dou relaii de
preceden (exemplu: a b i a b).
Relaiile de preceden ntre perechile de terminale se pot stabili pe dou ci:
1) Intuitiv: pornind de la semnificaia algebric a operatorilor i innd cont
de prioritatea i de asociativitatea lor. De exemplu, deoarece trebuie s aib
prioritate mai mare dect + se face + i + . Astfel se rezolv i ambiguitile
gramaticii expresiilor i se poate scrie i programul de ASPO.
2) n mod automat: aplicnd un algoritm adecvat. n prealabil, trebuie
eliminat ambiguitatea din gramatica iniial a limbajului, pentru ca ea s reflecte
corect asociativitatea i prioritatea operatorilor. Pentru gramatici mai complicate
dect gramatica expresiilor este posibil ca relaiile generate automat s nu fie
disjuncte i limbajul s fie mai cuprinztor dect cel iniial.

Utilizarea relaiilor de preceden a operatorilor


Scopul introducerii relaiilor de preceden este delimitarea capetelor ntr-o
form propoziional dreapta. Astfel, < marcheaz extremitatea stng a unui capt,
= apare n interiorul captului i > marcheaz extremitatea sa dreapt.
Captul poate fi gsit prin urmtorul procedeu:
1) Se baleiaz irul, cu relaiile de preceden introduse, de la extremitatea
stng i pn la ntlnirea primului marcaj >. Acesta reprezint extremitatea
dreapt a captului.
2) Se baleiaz irul napoi, omind eventualele simboluri = , pn la
ntlnirea primului marcaj <. Acesta reprezint extremitatea stng a captului.
3) Se consider ca fiind capt ntreg irul de simboluri gramaticale situat la
stnga marcajului > i la dreapta marcajului <, inclusiv toate neterminalele care
apar ca incluse sau nconjurnd terminalele dintre cele dou marcaje. Considerarea
neterminalelor nconjurtoare este necesar pentru a asigura c nu vor aprea dou
neterminale adiacente n forma propoziional urmtoare.
Exemplu: Se consider irul de intrare: $id+id id $ i matricea relaiilor de
preceden de mai jos:
id
id
+

Aciunile analizorului sunt cele cunoscute:


1) Deplasare: ct timp nu s-a gsit extremitatea dreapt a captului adic,
ntre simbolul terminal cel mai apropiat de vrful stivei i simbolul curent de
intrare, este valabil una din relaiile sau = .
2) Reducere: S-a gsit extremitatea dreapt a captului adic, ntre
simbolul terminal cel mai apropiat de vrful stivei i simbolul curent de intrare,
este relaia . Prin baleierea n sens invers a coninutului stivei i verificarea
relaiilor de preceden se caut extremitatea stng dup care se efectueaz
reducerea.
3) Acceptare: n situaia n care ambele simboluri care se compar (vrful
stivei i simbolul curent de intrare) sunt $.
4) Eroare: dac se ajunge n situaia s se compare o pereche de terminale
ntre care nu exist nici o relaie de preceden. Se va apela la o rutin special de
tratare i revenire.
Ideile de mai jos pot fi sintetizate n urmtorul algoritm:
Algoritmul de ASPO
Intrare: irul w i tabela relaiilor de preceden.
Ieire: dac irul w este corect se va obine un schelet al arborelui su
sintactic (datorit substituirii neterminalelor pe parcursul analizei, nodurile
interioare, corespunztoare acestora, vor fi uniformizate); n caz contrar, se va da
un mesaj de eroare.
Situaia iniial a structurii de date:
STIVA
$

irul cu relaiile de preceden introduse, este:


$ id + id id $
captul : id
$E+idid$
red : Eid
captul : id
$ + id id $
$E+Eid$
red : Eid
$ id+ id $
captul : id
$E+EE$
red : Eid
$ + $
captul : EE
$E+E$
red : EEE
$ + $
captul : E+E
$E$
red : EE+E
Deoarece neterminalele nu influeneaz analiza sintactic, nu trebuie fcut
distincie ntre ele. n stiva analizorului este suficient s se in un singur fel de
marcaj, neterminal, pentru a indica locurile respective (utile doar pentru
nregistrarea atributelor semantice).

INTRARE
w$

Algoritmul propriu-zis:
(1) poziioneaz pointerul de intrare pe primul simbol din w;
(2) repeat forever
(3)
if att simbolul din vrful stivei ct i simbolul curent de intrare
(4)
sunt $ then return {acceptare}
else begin
(5)
fie a simbolul terminal cel mai apropiat de vrful stivei
i b simbolul curent de intrare;
(6)
if (a b) or (a = b) then begin {deplasare}
(7)
introdu b n stiv;
(8)
avanseaz cu o poziie pointerul de intrare
(9)
end else if a b then {reducere}
(10)
repeat
(11)
extrage din stiv
(12)
until terminalul din vrful stivei este n relaia
cu terminalul cel mai recent extras
(13)
else eroare ()
end

Deducerea intuitiv a relaiilor de preceden din


asociativitatea i prioritatea algebric a operatorilor
Singura cerin care trebuie avut n vedere la stabilirea relaiilor de
preceden este aceea ca ele s conduc la analiza corect a limbajului definit de
gramatic. innd cont de faptul c ASPO se aplic n primul rnd la gramatici
pentru expresii sau similare cu acestea, iar ntre operatorii din expresii exist reguli
de asociativitate i prioritate riguroase care rezolv eventualele ambiguiti, aceste
reguli pot reprezenta baza stabilirii relaiilor de preceden.

Exemplu: gramatica EE+EE-EEEE/EEE(E)id


Operatorii au urmtoarele prioriti:
1)
este cel mai prioritar i este asociativ la dreapta;
2)
i / au prioritatea urmtoare i sunt asociativi la stnga;
3)
+ i au cea mai mic prioritate i sunt asociativi la stnga
Rezult urmtoarea tabel a relaiilor de preceden (absena relaiei
nseamn caz de eroare):
+

id
(
)
$

Pentru cazul operatorilor binari, notai cu , 1 i 2, relaiile de preceden


pot fi deduse astfel:
1) Dac 1 are prioritate algebric mai mare ca 2, se creaz relaiile de
preceden: 1 > 2 i 2 < 1
Exemplu: +, + i din E+EE+E, EE se va reduce primul.
2) Dac 1 i 2 sunt de prioritate egal (inclusiv cazul cnd ambele
reprezint acelai operator) apar urmtoarele situaii:
a) 1 i 2 sunt asociativi la stnga 1 > 2 i 2 > 1
b) 1 i 2 sunt asociativi la dreapta 1 < 2 i 2 < 1
Exemplu: + + , + - , - - , - + i din E-E+E se va selecta la nceput captul E-E
(asociativ la dreapta) i din EEE se va selecta la nceput ultimul
EE

id

Exemplu: id(idid)-id/id
$ id ( id id ) - id / id $
Eid
$ ( id ...
Eid
$ ( id ) ...
Eid
$ ( ) ...
EEE
$ ( = ) - ...
E(E)
$ - ...
EEE
$ - id / ...
Eid

3) Oricare ar fi , exist urmtoarele relaii de preceden cu celelalte


terminale: id, (,), $
< id
< (
> )
> $

id >
(<
) >
$ <
Pentru a asigura reducerea la E a lui id i a (E), ntre terminalele care nu sunt
operatori se introduc urmtoarele relaii:
$ < (
$ < id
( = )
id > $
) > $
( < (

( < id
id > )
) > )

$ - / id $
Eid
$ - / $
EE/E
$ - $
EE-E
$E$
Acceptare

Funcii de preceden

Tratarea operatorilor unari


Pentru acei operatori unari (prefix sau postfix) care nu sunt n acelai timp i
binari, se pot uor extinde regulile din paragraful precedent. Pentru exemplificare s
considerm ca fiind un operator oarecare, binar sau unar, i s definim relaiile
sale de preceden cu operatorul unar (negare logic):
<
i

>
<

dac are o prioritate mai mic dect

Un dezavantaj al ASPO poate s fie dimensiunea relativ mare a tabelei


relaiilor de preceden. n majoritatea cazurilor ns, nu este obligatoriu ca
analizorul s pstreze n memorie aceast tabel. Ea poate fi substituit prin dou
funcii de preceden notate f i g, care pun n coresponden simbolurile
gramaticale cu numere ntregi. Funciile f i g vor fi astfel alese nct s satisfac
urmtoarele condiii:
1) f(a) < g(b)
2) f(a) = g(b)
3) f(a) > g(b)

dac are o prioritate mai mare dect .

Exemplu: (operator unar) mai prioritar dect & (operator binar). Conform
acestor reguli, expresia E& E&E va fi evaluat astfel: (E&( E)) &E.
Dac operatorul unar este n acelai timp i binar (cazul semnului -) situaia
se complic foarte mult, chiar dac cei doi operatori, identici ca form, ar avea
aceeai preceden.. Pentru exemplificare se poate studia tratarea irului id-id,
conform tabelei anterioare. O soluie posibil este modificarea ANLEX astfel nct
s returneze coduri lexicale diferite pentru cele dou situaii de utilizare a semnului
"-". Dac se realizeaz acest lucru, operatorul unar minus devine un operator
distinct i poate fi tratat cu regulile de mai sus. Trebuie totui menionat c nu este
simplu pentru ANLEX s disting ntre cele dou situaii, deoarece este nevoie s
priveasc operatorul n contextul n care apare.

a < b
a = b
a > b

dac
dac
dac

n acest fel, determinarea relaiei de preceden ntre a i b se reduce la


simpla comparare numeric ntre f(a) i g(b). Un dezavantaj al utilizrii funciilor
de preceden este acela c nu mai pot fi sesizate acele cazuri de eroare marcate n
tabel prin intrri vide (lipsa relaiei de preceden). Cauza este aceea c ntre
numerele f(a) i g(b) exist ntotdeauna una dintre relaiile 1), 2) sau 3).
Dezavantajul nu este ns foarte mare pentru c erorile nu se pierd ci doar se amn
detectarea lor pn n momentul ncercrii de reducere, cnd nu va putea fi gsit un
capt corespunztor.
Nu orice tabel a relaiilor de preceden poate fi codificat prin funcii de
preceden pentru c nu pot fi construite funciile astfel nct s respecte cerinele
de mai sus pentru toate relaiile. Totui, pentru multe cazuri practice, funciile
exist i se pot construi.
Exemplu: Tabela de preceden anterioar are urmtoarea pereche de funcii
de preceden:
f
g

+
2
1

2
1

4
3

4
3

4
5

(
0
5

)
6
0

id
6
5

$
0
0

Se observ c f(id) > g(id) id > id, dei, n realitate, ntre id i id nu exist
relaie de preceden caz de eroare.

Algoritmi de construire a funciilor de preceden:


Metoda

1)
2)

Creaz simbolurile fa i ga pentru fiecare terminal a, inclusiv $.


Se partiioneaz simbolurile create n grupuri, astfel nct dac
= b atunci fa i gb sunt n acelai grup.
3)
Se creaz un graf orientat ale crui noduri sunt constituite din
grupurile gsite anterior iar arcele se stabilesc astfel:
a) pentru toate perechile a i b pentru care a < b se duce un arc de
la grupul lui gb la grupul lui fa;
b) dac a > b, se duce un arc de la grupul lui fa la grupul lui gb.
Existena unui arc sau a unui drum de la fa la gb nseamn c
valoarea lui f(a) trebuie s depeasc pe cea a lui g(b). Invers,
un drum de la gb la fa nseamn c trebuie ca g(b) > f(a).
4)
Dac graful construit la punctul 3) are un ciclu, atunci nu
exist funcii de preceden. Dac nu exist cicluri atunci,
pentru orice terminal a, inclusiv $, f(a) va primi ca valoare
lungimea celui mai lung drum care ncepe n grupul lui fa iar
g(a) va fi egal cu lungimea celui mai lung drum care ncepe n
grupul lui ga.
Exemplu: Se consider matricea de preceden redus (pentru simbolurile id, +,
* i $). Nu exist relaia = aa c fiecare simbol constituie el nsui un
grup conform algoritmului, rezult urmtorul graf:
gid

fid

f*

g*

g+

f+

f$

g$

Revenirea din erori n analiza sintactic bazat pe precedena


operaiilor.
n procesul de ASPO exist dou situaii n care se pot detecta erori
sintactice:
1) Dac s-a gsit un capt (conform relaiilor de preceden) dat nu exist
nici o producie avnd acel capt ca parte dreapt.
2) Dac ntre terminalul din vrful stivei i simbolul curent de intrare nu
exist relaie de preceden.
ntr-un capt detectat n stiv apar numai simboluri terminale ns trebuie
inut cont i de poziiile n care exist neterminale care, dei nu sunt nominalizate,
au totui locuri rezervate n stiva de analiz. Ca atare, erorile de tipul 1) constau n
negsirea unei producii care s aib n partea dreapt aceleai terminale i n
aceeai ordine ca i cele din capt i aceleai poziii pentru neterminale. Pentru
aceasta, algoritmul de ASPO prezentat anterior trebuie completat, n poriunea de
tratare a reducerilor i cu verificarea corespondenei ntre captul extras din stiv i
partea dreapt a unei producii. Aceast operaie are ca efect i localizarea
produciei pe baza creia se face reducerea, operaie esenial la analiza semantic,
deoarece regulile semantice sunt asociate produciilor i ele se execut n timpul
reducerilor.
Alte situaii de eroare, n afara celor semnalate la punctele 1) i 2) de mai sus
nu pot s apar. De exemplu, la extragerea din stiv, exist certitudinea c se va
localiza extremitatea stng a captului (apariia unei relaii <), cel trziu ntre $-ul
de la baza stivei i primul simbol situat deasupra lui, deoarece $ < simbol. Ca
atare, extragerea din stiv, operaie care reprezint efectiv reducerea, se va putea
finaliza cu certitudine.

Nu exist cicluri exist funcii de preceden


f
g

+
2
1

4
3

id
4
5

$
0
0

f($)=g($)=0 deoarece f$ i g$ nu au arce de ieire. g(+)=1 pentru c cel mai


lung drum este format dintr-un singur arc. . a. m. d.
9

10

Tratarea erorilor n timpul reducerilor (tipul 1)


n momentul detectrii unei erori de tipul 1), pentru a emite un mesaj
potrivit, trebuie cutat o parte dreapt a unei producii, asemntoare cu captul
extras.
Exemple:
a)
Dac s-a extras un capt ce conine terminalele abc i exist o parte
dreapt de forma aEcE n care apar terminalele ac dar nu i b, se poate emite
mesajul: b ilegal n linia ...
b)
n alt situaie se poate cere s inserm un terminal pentru a gsi
corespondena cu partea dreapt:
abEdc
lipsete d n linia ...
c) n situaia aEbc iar captul extras nu solicit prezena unui neterminal
ntre a i b, se poate emite mesajul lipsete E n linia ...
Posibilitatea de a emite un mesaj de eroare exact n situaia n care captul nu
corespunde cu partea dreapt a nici unei producii din gramatic este direct legat
de existena unui numr finit sau infinit de iruri care pot fi extrase ca i capete.
Considernd un astfel de ir, notat b1 b2 ... bk, dac el este capt, atunci ntre
simbolurile adiacente care l compun este valabil doar relaia de preceden = ,
adic b1 = b2 = ... = bk. Dac din analiza tabelei de preceden a operatorilor rezult
existena unui numr finit de secvene de terminale legate prin = , atunci fiecare
astfel de caz se poate trata distinct i, avnd ca element de referin partea dreapt
cea mai apropiat, se poate elabora un mesaj de eroare potrivit.
Pentru a evidenia irurile care pot fi extrase din stiv ca i capete se va
construi un graf orientat ale crui noduri sunt terminalele gramaticii iar arcele leag
nodurile ntre care exist relaia = . Capetele posibile sunt toate irurile date de
etichetele nodurilor care formeaz drumuri n acest graf. n plus, pentru ca un drum
b1 b2 ... bk s poat fi capt, trebuie s existe dou simboluri notate a i c (terminale
sau $) astfel ca a < b1 i respectiv bk > c. Dac respect i aceast condiie, nodurile
corespunztoare lui b1 i bk se vor numi nod iniial i respectiv nod final. Cu
aceste notaii, concluzia va fi urmtoarea: dac n graful construit exist cel puin
un drum care s conin un ciclu, atunci numrul posibil de capete este infinit,
astfel este finit.

11

Exemplu: Se consider gramatica:


EE+EE-EE EEEEE(E)id
a crei tabel de preceden a fost dat anterior. Graful corespunztor este
urmtorul:

id

Singura pereche de noduri legate este cea corespunztoare parantezelor


(singurul = din tabel). Toate nodurile, mai puin ), pot fi noduri iniiale i toate
nodurile, mai puin (, pot fi noduri finale. Deci exist urmtoarele drumuri (n
numr finit) de la un nod iniial la unul final: +, , , /, , id de lungime 1 i ( ) de
lungime 2 i toate corespund terminalelor din partea dreapt a unei producii. Ca
atare, rutina de tratare a erorilor n timpul reducerilor trebuie s verifice doar
existena marcajelor de neterminale, pe poziiile corecte, ntre irurile de terminale
care se reduc. Pot exista urmtoarele situaii:
1)
Dac se reduce un capt care conine unul din terminalele +, , , /, ,
atunci trebuie verificat c apare cte un neterminal n ambele pri ale terminalului.
Altfel, se va emite mesajul: Lipsete operand n stnga/dreapta operatorului ....
2)
Dac se reduce id, atunci trebuie verificat s nu apar neterminal nici
la stnga i nici la dreapta sa. Dac apare un neterminal, se emite mesajul Lipsete
operator la stnga/dreapta identificatorului ....
3)
Dac se reduce captul ( ), atunci pot aprea urmtoarele situaii de
eroare:
a)
Nu exist neterminal ntre paranteze. Se poate emite mesajul:
Lipsete expresie ntre ( )
b)
Exist neterminale adiacente n exterior cu parantezele, de o parte
sau de alta. Se pot da mesaje similare cu cel de la punctul 2): Lipsete
operator la stnga ( sau la dreapta )
Dac numrul de iruri ce pot fi extrase ca i capete este infinit, mesajele de
eroare nu se pot stabili cu exactitate. n aceste cazuri, rutina de tratare a erorilor ar
putea determina dac exist o parte dreapt apropiat de irul extras (de exemplu, la
distana de 1 sau 2, unde distana nseamn numrul de atomi inserat, ters sau
schimbat). Dac exist o astfel de producie, se poate emite un mesaj concret, n
sensul c se ateapt s apar acea parte dreapt. Dac nici o parte dreapt nu este
suficient de aproape de capt, nu se poate emite dect un mesaj general, de genul:
Eroare de sintax n linia ....
12

Exemplu: Se consider din nou matricea de preceden din 5. 2. 3. Se rein


din aceast matrice doar liniile i coloanele pe care apar intrri vide, completate cu
numele rutinelor de tratare a erorilor:

Tratarea erorilor deplasare reducere (tipul 2)


Dac la consultarea matricei de preceden se constat c, ntre simbolul din
stiv i cel din intrare, nu exist relaie de preceden atunci, pentru a continua
analiza, trebuie s se modifice fie stiva, fie intrarea, fie ambele structuri.
Modificarea va consta n inserarea, tergerea sau nlocuirea unui simbol. La inserri
sau tergeri exist pericolul de a se provoca un ciclu infinit. De exemplu, inserarea
repetat de simboluri n intrare, fr a putea reduce sau deplasa simbolurile
inserate.
Pentru a preveni ciclurile infinite, rutina de tratare a erorii trebuie s
garanteze c, dup modificare i revenire, simbolul curent de intrare poate fi
deplasat n stiv. Pentru cazul particular cnd, iniial, simbolul curent de intrare este
$, se evit inserarea de simboluri n intrare i se reduce stiva. S considerm
configuraia:
STIVA

INTRARE

... ab

cd ...$

Configuraia conduce la eroare ntruct ntre b i c nu exist relaie de


preceden. Pot exista urmtoarele variante de tratare a erorii:
a)
Dac a c (nseamn < sau = ), se poate extrage b din stiv.
b)
Dac b d, se terge c din intrare.
c)
Se caut un simbol e, astfel nct b e c care s se insereze n
intrare, n faa lui c. Dac nu exist un astfel de simbol, se poate cuta pentru
inserare un ir de simboluri e1, e2, ..., en astfel ca b e1 e2 ... en c.
Aciunea exact ce se alege reflect, n general, intuiia proiectantului
compilatorului relativ la cea mai probabil eroare din fiecare caz. Pentru fiecare
intrare necompletat din matricea de preceden trebuie s se specifice o rutin de
revenire din erori (nu neaprat distinct de cea corespunztoare altor intrri) n care
se execut modificarea adecvat a stivei i/sau a intrrii i se emite mesajul de
eroare.

id
(
)
$

id
e3
<
e3
<

>
=

>

>
e2

e4
>
e1

n esen, cele patru rutine cuprind urmtoarele operaii:


e1:
Se apeleaz dac lipsete ntreaga expresie.
Se trateaz prin inserarea unui id n intrare.
Mesajul: Lipsete operand.
e2:
Se apeleaz cnd expresia ncepe cu o ).
Se trateaz prin tergerea ) din intrare.
Mesajul: ) fr pereche n plus.
e3:
Se apeleaz cnd id sau ( urmeaz dup id sau ).
Se trateaz prin inserarea unui operator, de ex. +, n intrare.
Mesajul: Lipsete operator.
e4:
Se apeleaz cnd expresia se termin cu (.
Se trateaz prin extragerea ( din stiv.
Mesajul: Lipsete parantez dreapt.
Pentru a analiza modul de funcionare al acestui mecanism, s considerm
irul de intrare eronat id + ). Dup primele aciuni (deplasarea lui id, reducerea la E
i deplasarea lui +) se ajunge n urmtoarea configuraie:
STIVA
$E

INTRARE
)$

Deoarece + > ) urmeaz o reducere a captului + iar, n timpul reducerii, se


observ absena lui E din dreapta operatorului. Mesaj: Lipsete operand n dreapta
operatorului +. Dup efectuarea reducerii, se ajunge la configuraia:
STIVA
$E

INTRARE
)$

Pentru $ i ) nu exist relaie de preceden i se apeleaz rutina e2. Mesaj: )


fr pereche n plus Prin eliminarea ) din intrare, se ajunge la configuraia
final a analizorului:
STIVA
$E

13

(
e3
<
e3
<

14

INTRARE
$

15

16

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