Professional Documents
Culture Documents
Programski Prevodioci
Programski Prevodioci
Programski Prevodioci
Predgovor 1
1 Uvod 3
1.1 Vrste programskih prevodilaca . . . . . . . . . . . . . . . . . . . 3
1.2 Struktura kompilatora . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 Hibridni prevodioci . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.4 Prenosivost koda . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.5 Viejeziki kompilator . . . . . . . . . . . . . . . . . . . . . . . . 9
1.6 Proces prevoenja programa . . . . . . . . . . . . . . . . . . . . . 9
1.7 Kratak osvrt na istoriju kompilatora . . . . . . . . . . . . . . . . 13
1.8 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
i
ii SADRAJ
4 Leksiki analizator 59
4.1 Namena leksikog analizatora . . . . . . . . . . . . . . . . . . . . 59
4.1.1 Tokeni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.1.2 abloni . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.1.3 Tabela simbola . . . . . . . . . . . . . . . . . . . . . . . . 63
4.2 Realizacija leksikog analizatora . . . . . . . . . . . . . . . . . . . 64
4.3 Programska realizacija leksikog analizatora . . . . . . . . . . . . 67
4.3.1 Tehnika dvostrukog bafera . . . . . . . . . . . . . . . . . . 68
4.4 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.5 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5 Sintaksna analiza 73
5.1 Redosled primene pravila . . . . . . . . . . . . . . . . . . . . . . 73
5.2 Osnovni algoritam za top-down sintaksnu analizu . . . . . . . . . 79
5.2.1 Problem leve rekurzije . . . . . . . . . . . . . . . . . . . . 81
5.2.2 Eliminisanje leve rekurzije . . . . . . . . . . . . . . . . . . 83
5.3 Osnovni algoritam za bottom-up analizu . . . . . . . . . . . . . . 86
5.4 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.5 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
8 LR analizatori 135
8.1 Opis analizatora . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
8.1.1 Shift-reduce algoritam analize . . . . . . . . . . . . . . . . 137
8.2 Realizacija LR analizatora . . . . . . . . . . . . . . . . . . . . . . 139
8.2.1 Vidljivi preksi . . . . . . . . . . . . . . . . . . . . . . . . 139
8.2.2 LR(k ) gramatike . . . . . . . . . . . . . . . . . . . . . . . 140
8.2.3 Tipovi LR analizatora . . . . . . . . . . . . . . . . . . . . 140
8.3 Realizacija SLR analizatora . . . . . . . . . . . . . . . . . . . . . 141
8.3.1 LR(0) lanovi . . . . . . . . . . . . . . . . . . . . . . . . . 141
8.3.2 Funkcija zatvaranja (closure) . . . . . . . . . . . . . . . . 142
8.3.3 Funkcija iniciranja novih skupova LR(0) lanova (goto) . 142
8.3.4 Postupak sinteze LR analizatorata . . . . . . . . . . . . . 142
8.4 Reeni zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
8.5 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
8.6 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
12 Meukodovi 231
SADRAJ v
16 Dodatak 313
16.1 Java bajtkod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Slike
vii
viii SLIKE
7.1 Relacija istog prioriteta (a = b) . . . . . . . . . . . . . . . . . . . 112
7.2 Relacija nieg (a < b) i b) prioriteta
vieg (a > . . . . . . . . . . 112
7.3 Sintaksna stabla uz tabelu 7.2 (prvi deo) . . . . . . . . . . . . . . 115
7.4 Sintaksna stabla uz tabelu 7.2 (drugi deo) . . . . . . . . . . . . . 116
7.5 Sintaksna stabla uz tabelu 7.2 (trei deo) . . . . . . . . . . . . . 117
7.6 Sintaksna stabla uz tabelu 7.2 (etvrti deo) . . . . . . . . . . . . 118
7.7 Graf za odreivanje funkcija prvenstva uz primer 7.3 . . . . . . . 123
7.8 Sintaksna stabla uz tabelu 7.4 (prvi deo) . . . . . . . . . . . . . . 128
7.9 Sintaksna stabla uz tabelu 7.4 (drugi deo) . . . . . . . . . . . . . 129
6.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
xi
xii TABELE
1
2 TABELE
Uvod
Obino je jezik sa kog se prevodi vieg nivoa od jezika na koji se vri prevoenje,
mada, u optem sluaju, moemo da prevodimo sa jednog jezika visokog nivoa
na drugi jezik visokog nivoa, ali i da se kod niskog nivoa prevodi u kod vieg
nivoa (tako npr. rade krosasembleri).
Tabela 1.1 daje klasikaciju programskih jezika prema njihovom nivou i nekoj
hronologiji razvoja.
3
4 GLAVA 1. UVOD
asemblerski makroasemblerski
jezici niskog nivoa
jezici jezici
proceduralni
jezici visokog nivoa
jezici
problemski
jezici veoma viskog nivoa
jezici
Drugu generaciju jezika ine asemblerski jezici kod kojih se mainske naredbe
predstavljaju simboliki, uz korienje simbolikih adresa naredbi i podataka.
Ovi jezici su vieg nivoa od mainskih ali su i dalje mainski zavisni. Naime,
asemblerski jezik se denie zajedno sa procesorom raunara tako da struktura
procesora bitno utie na strukturu asemblerskog jezika i obrnuto. Za prevoenje
zapisa sa nivoa asemblerskog jezika na mainski nivo potreban je programski
prevodilac koji se u ovom sluaju naziva asembler (assembler, slika 1.2) odakle
dolazi i naziv ovih jezika.
mainski
jezik
asemblerski jezik asembler CPU rezultati
podaci
Slika 1.2: Asembler
makroasemblerski
makroprocesor
jezik
asemblerski jezik
mainski
jezik
asembler CPU rezultati
podaci
Slika 1.3: Makroprocesor
izvorni program
leksiki analizator
sintaksni analizator
sintaksno stablo
meukod
generator koda
mainski kod
CPU
Kod koji kompilator generie u prvom prolazu obino sadri puno redundantno-
sti pa se zato vri optimizacija koda. Ova optimizacija moe da bude mainski
nazavisna, kada se vri na nivou meukoda ali i mainski zavisna, kada se vri
na nivou generisanog koda.
izvorni program
interpretator podaci
rezultati
Slika 1.5: Interpretator
Ovaj koncept se na primer standardno koristi kod programskog jezika Java, kod
kojeg se najpre generie meukod programa (bytecode ) a zatim taj meukod in-
terpretira na Java virtuelnoj maini kao interpretatoru. Primena ovog koncepta
omoguila je laku prenosivost Java koda sa jedne maine na drugu, to je i bila
osnovna ideja kod projektovanja ovog jezika. Naime, programski jezik Java je
projektovan tako da se moe koristiti na razliitim raunarskim platformama, a
pre svega kod ugraenih (embedded ) raunarskih sistema.
1. Prvi sluaj je, ve pomenuti nain, kada se Java program prevodi u meu-
kod i interpretira na Java virtuelnoj maini koja generie mainske naredbe
koje se izvravaju u procesoru raunara (slika 1.7a).
8 GLAVA 1. UVOD
izvorni program
leksiki analizator
sintaksni analizator
sintaksno stablo
generator meukoda
meukod
interpretator podaci
rezultati
Slika 1.6: Hibridni prevodilac
2. U drugom sluaju koristi se tzv. just in time Java kompilator koji bajt-
kod programa preslikava u mainski kod namenjen odreenoj maini, po
principu po kome rade i drugi kompilatori (slika 1.7b).
(b) Java just-in-time kompilator (bri): konveruje sve instrukcije u maonski jezik kad
je instrukcija potrebna (dinamiko prevoenje), a zatim izvrava mainski jezik.
(c) Java kompilator (bri): izvorni kod se prevodi u mainski kod i izvrava kao C ili
C++ program.
Java aplikacija
(bajt-kod) Java CPU
(d) Java procesor (najbri): Java procesor izvrava Java bajt-kod na nain na koji
drugi CPU izvravaju odgovarajui mainski kod.
kod na kod na
programskom programskom
jeziku 1 jeziku 2
optimizacija meukoda
n op
va t
m imi
izo od e zo
ptim uk uk va
od n
o m e
naredba
id1 := izraz1 :=
id2 izraz
4 * izraz5 id2 *
Postupkom sintaksne analize odreuje se skup i redosled pravila koja treba pri-
meniti da bi se generisala zadata re. Redosled primene pravila se moe predsta-
viti sintaksnim stablom (slika 1.9 za razmatrani primer). Na osnovu sintaksnog
stabla generie se apstraktno sintaksno stablo (AST abstract syntax tree ) u
kome se u vorovima nalaze operatori a grane vode do operanada (slika 1.10).
Ovo stablo predstavlja osnovu za generisanje ciljnog koda.
t1 := real(60)
t2 := r * t1
t3 := init + t2
pos := t3
MOV r, R2
MULV #60.0, R2
MOV init, R1
ADD R2, R1
MOV R1, pos
:=
id1 .real +
id2 .real
CPU
rezultati
Slika 1.12: Potpuna struktura kompilatora
Nakon ovog poetnog perioda veoma brzo je prihvaena ideja o korienju viih
programskih jezika za razvoj programa. Time su programeri osloboeni zavisno-
sti od maine i mogli su vie da se posvete algoritmima za reavanje problema.
Kako su programski jezici i arhitekture raunara postajali sve kompleksniji i
programi samih kompilatora su bili sve sloeniji.
1.8 Pitanja
1. Objasniti namenu progrmskih prevodilaca.
2. ta je to asembler?
6. Objasniti ta je to meukod.
7. ta su to viejeziki kompilatori?
Za sva ova tri nivoa opisa jezika koriste se formalni jezici i formalne gramatike
15
16 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA
2.2.2 Re
Re u kontekstu formalnih jezka se denie kao konaan niz simbola azbuke V.
Niz koji ne sadri nijedan simbol naziva se prazna re i oznaava sa .
1. je re nad azbukom V.
2.2. ELEMENTI JEZIKA 17
xx = x2 , xxx = x3 ,
x = x1 , x0 = .
2.2.5 Transponovana re
Transponovana re rei x, u oznaci x| , denie se sledeim pravilima:
18 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA
1. | =
2. (xa)| = ax|
Rezultat operacije transponovanja rei je re u kojoj su slova ispisana u obrnu-
tom redosledu u odnosu na originalnu re.
Preks rei x je niz koji se dobija izbacivanjem nijednog ili vie krajnjih slova
rei x.
Suks rei x je niz koji se dobija izbacivanjem nijednog ili vie poetnih simbola
rei x.
Podniz rei x je re koja se dobija kada se izbaci neki preks i/ili neki suks
rei x. Svaki preks i svaki suks rei x su podnizovi rei x, dok svaki podniz
rei x ne mora da bude ni suks ni preks rei x. Za svaku re x rei x i su
njeni preksi, suksi i podnizovi.
Svaki niz koji se dobija izbacivanjem nijednog ili vie sukcesivnih simbola iz rei
x, naziva se podsekvencom rei x.
Naglasimo jo jednom, formalni jezik L nad azbukom V je bilo koji skup rei
nad tom azbukom.
Prema ovoj deniciji, formalni jezik je i prazan skup rei , kao i skup {} koji
sadri samo praznu re .
V = {a, b, c, . . . , x, y, z}.
Ako su L i M formalni jezici, onda je L M unija ova dva jezika i obuhvata sve
rei koje pripadaju ili jeziku L ili jeziku M:
L M = {x | x L x M}.
Ako su LiM formalni jezici, onda je LM proizvod ova dva jezika i obuhvata
sve rei koje nastaju operacijom nadovezivanja rei jezika M na rei jezika L.
L M = {xy | x L y M}.
[
L+ = Li .
i=1
Kako se slova azbuke mogu posmatrati kao rei duine 1, onda je svaki od
skupova L i D i formalni jezik. Operacijama nad ovim jezicima mogu se
denisati sledei jezici:
LD skup svih rei koje se sastoje od slova iza kog stoji cifra,
L 4
skup svih etvoroslovnih rei,
L
skup svih nizova slova ukljuujui i ,
L (L D)
skup nizova slova i cifara koji zapoinju slovom,
D +
skup svih celih brojeva, nizova koji se sastoje od jedne ili vie
cifara.
2.4. OPIS JEZIKA 21
Gramatika je skup pravila kojima se denie koje rei neke azbuke pripadaju
odreenom jeziku. Skup pravila gramatike moe da bude zadat na bilo koji
nain, uz uslov da je skup rei jezika jednoznano denisan.
izraz id
izraz const
izraz izraz + izraz
izraz izraz izraz
izraz (izraz )
naredba id := izraz
naredba while (izraz ) do naredba
naredba if (izraz ) then naredba
naredba
id1 := izraz1
izraz2 + izraz3
Terminalni simboli :
x ::= y ili xy
z w.
24 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA
x u1 , u1 u2 , u2 u3 , ..., un y,
umesto termina direktno izvoenje i direktna redukcija koriste se termini izvo-
enje i redukcija . Kaemo y se izvodi od xiy se redukuje na x. Izvoenje je
viestruko primenjeno direktno izvoenje i obino se oznaava sa:
x
y.
1. S CD
2.5. FORMALNE GRAMATIKE 25
2. C aCa
3. C bCB
4. AD aD
5. BD bD
6. Aa bA
7. Aa bA
8. Ba aB
9. Bb bB
10. C
11. D
Datom gramatikom je opisan jezik
1. W aW
2. W Z
3. W X
4. Z aZ
26 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA
5. Xa
6. Y aa
je primer neredukovane gramatike iz sledeih razloga:
izraz izraz
const const
izraz + izraz izraz + izraz
izraz
izraz + sabirak
sabirak faktor
const
sabirak * faktor
faktor const
const
To znai da se rei sa leve strane pravila mogu preslikavati samo u rei koje su
jednake ili vee duine. Drugim reima, nisu dozvoljena pravila oblika:
x .
Gramatike tipa jedan, kao i gramatike tipa nula se obino nazivaju i konteksnim
gramatikama . To je zbog toga to se neterminal koji je obavezan na levoj
strani smene kod ovih gramatika nalazi u nekom kontekstu i itav taj kontekst
se preslikava u novu re.
1. S 0B0
2. C0 100
3. B 0BC
4. B1
5. C1 1C
je konteksna gramatika tipa jedan.
1 3 3 2
S
0B0
000BCC0
0000BCC0
0000BCC100
5 0 5
0000BC1C00
000BC11000
0000B1C1000
5 2 4
0000B11C000
0000B1110000
000011110000
A y, gde je A Vn i y V .
E EAE | (E ) | -E | id
A+|||
E EAE
id1 AE
id1 E
id1 (E)
id1 (EAE)
id1 (id2 AE)
id1 (id2 + E)
id1 (id2 + EAE)
id1 (id2 + id3 AE)
id1 (id2 + id3 E)
id1 (id2 + id3 id4 )
A aB ili A a, gde je A, B Vn i a Vt .
Naziv regularne gramatike dolazi odatle to se gramatikama tipa tri generiu re-
gularni izrazi koji se ekasno mogu prepoznavati konanim automatima. Regu-
larne gramatike imaju iroku primenu u mnogim oblastima u kojima se problem
svodi na prepoznavanje nizova. U kontekstu programskih prevodilaca koriste se
za opis leksikih elemenata jezika (identikatora, konstanti, literala i sl) koje
prepoznaje leksiki analizator, o emu e biti rei kasnije.
30 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA
A 0B | 1D B 0C | 1F C 0C | 1F |
D 1E | 0F E 1E | 0F | F 0G | 1G
G 0G | 1G |
Primer izvoenja:
Gramatike tipa tri pokrivaju najui skup jezika ali je za ove jezike najjednostav-
nije reiti problem prepoznavanja. Prepoznaju se pomou konanih automata.
E EAE | (E ) | E | id A+|||/
2.7. NORMALNE FORME GRAMATIKA 31
E EAE E + E E + EAE.
2.6.5 Fraze
Fraze se deniu za beskonteksne gramatike. Ako je xuy reenina forma, u
je fraza za neterminal A ako se izvodi iz neterminala A. To znai da sve rei
izvedene od istog neterminalnog simbola ine skup fraza tog simbola. Fraza
koja ne sadri druge fraze istog neterminla je prosta fraza.
Posmatrajmo izvoenje:
Rei EAE , (E), ((E)), ((E)), (id) su primeri fraza neterminala E ; sve
nastaju od neterminala E . Pri tome su EAE , (E), ((E)) i (id) proste
fraze, dok ((E)) nije prosta fraza zato to sadri frazu (E).
x A y x r y, gde je A Vn , x, y V i r V+
32 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA
Na osnovu ove normalne forme jasno se vidi zbog ega su ove gramatike dobile
naziv konteksne gramatike. Vidi se da se neterminal A zamenjuje nizom r samo
ako se nae u kontekstu rei x i y.
S , A B C, Aa A, B Vn , a Vt .
S , A a, A a B, A aBC A, B, C Vn , a Vt .
2.8 Pitanja
1. Denisati pojam azbuke.
2.9 Zadaci
1. Odrediti skup V azbuke V = {alo, hula}.
2. Za datu re w = go odrediti w2 i w3 .
2.9. ZADACI 33
3. Neka je L1 = {ja, ti, on, ona, mi, vi, oni}, a L2 = {spava, radi}. Odre-
diti jezike LR
1 i L1 L2 .
A cifra B | +C | C
B cifra B | , D
C cifra B
D cifra D |
S S+I |I
I (S ) | fun(S ) | id
ulazna traka
# a1 a2 ai an #
ulazna glava
funkcionalni organ
radna glava
beskonana memorija
35
36 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA
ulazna glava se pomera za jedno mesto napred ili nazad ili ostaje na poziciji
na kojoj se nalazi.
2N dvosmerni nedeterministiki,
1N jednosmerni nedeterministiki,
2D dvosmerni deterministiki i
1D jednosmerni deterministiki.
Tjuringova maina,
magacinski automat i
konani automat.
ulazna traka
# a1 a2 ai an #
ulazna glava
funkcionalni organ
radna memorija
A1 A2 Ai An
Tm = (Q, V, S, P, q0 , b, F),
gde je:
P preslikavanje denisano sa
Q (V #) S {Q S {1, 0, +1}}.
(q, #a1 a2 ai an #, X1 X2 Xm )
q Q, ai V, i = 1, 2, . . . , n Xj S, j = 1, 2, . . . , m,
40 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA
ulazna traka
# a1 a2 ai an #
ulazna glava
funkcionalni organ
magacin kao
Ai
radna memorija
A2
A1
koju ine stanje u kome se nalazi funkcionalni organ, niz na ulaznoj traci ije
se prepoznavanje vri i niz simbola u radnom magacinu. Pri tome je sa Xm
oznaen simbol koji se nalazi u vrhu magacina.
(q, #a1 a2 ai #, X1 X2 Xm ) 7
(p, #a1 a2 ai + d an #, X1 X2 Xm1 , r)
S 0S1 S a.
Ma = (Q, V, S, P, q0 , Z0 , F),
gde je:
ulazna traka
# a1 a2 ai an #
ulazna glava
funkcionalni organ
Q = {q0 , q1 , q2 , q3 },
V = {0, 1},
F = {q0 },
P (q0 , 0) = q2 , P (q0 , 1) = q1 ,
P (q1 , 0) = q3 , P (q1 , 1) = q0 ,
P (q2 , 0) = q0 , P (q2 , 1) = q3 ,
P (q3 , 0) = q1 , P (q3 , 1) = q2 .
start q0 q1
1
0 0 0 0
q2 q3
1
qj = qi a.
qkraj = f (qpo ).
3.5. KONANI AUTOMATI 45
qi = qi a qj b qi = qj ba
jer je:
qi a \qi aa = qj ba
qi { a a2 a3 }\qi a{ a a2 a3 } = qj ba
qi = qj ba
1
start q0 q1 1
0
1
q2 q3 0
1. q0 = q0 q2 1
2. q1 = q1 1 q0 1
3. q2 = q1 0 q3 1
4. q3 = q2 0 q3 0
Napomena: Kako je q0 poetno stanje, njegovoj jednaini stanja se dodaje
i q0 .
Krajnje stanje automata je q2 , da bi odredili sve rei koje poetno stanje
preslikavaju u ovo stanje potrebno je da se na osnovu jednaina stanja
odredi q2 = f (q0 ):
4 q3 = q2 00
40 3 q2 = q1 0 q2 00 1 (30 )
46 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA
20 q1 = q0 11
20 30 q2 = q0 11 0 q2 00 1 (300 )
00
13 q2 = q0 11 0 q2 111 0 q2 00 1
q2 = q0 11 (111 0 00 1)
L(G) = 11 0(111 0 00 1)
Automat Gramatika
a
A B a aB i b
B b b bB
B b b bB i B ili
b bB i B b
1. hOznaceniCeoBroji +hNeoznaceniCeoBroji
2. hOznaceniCeoBroji hNeoznaceniCeoBroji
3. hNeoznaceniCeoBroji cifra hNizCifarai
4. hNizCifarai cifra hNizCifarai
5. hNizCifarai
Graf automata koji prepoznaje jezik denisan gramatikom dat je na slede-
oj slici.
cifra
start OCB NCB NC cifra
-
Vn = {Q0 , Q1 , Q2 , Q3 }
Vt = {0, 1}
S = Q0
Skup smena P:
Q0 1Q1 Q1 1Q1
Q1 0Q2 Q2 1Q0
Q2 0Q3 Q2
Q3 0Q3 Q3 1Q2
im skupom smena:
A 0B | 1D, B 0C | 1F, C 0C | 1F | ,
D 1E | 0F, E 1E | 0F, F 0G | 1G,
G 0G | 1G | .
A = A (1)
B = A0 (2)
C = B0 + C0 (3)
D = A1 (4)
E = D1 + E1 (5)
F = B1 + C1 + E0 (6)
G = F 0 + F 1 + G0 + G1. (7)
B = A0. (8)
C = A000 . (9)
D = A1. (10)
3.6. REGULARNI IZRAZI 49
E = A111 . (11)
Iz (7) sledi:
G = F (0 + 1) + G(0 + 1)
(13)
= F (0 + 1)(0 + 1) .
L= 000 + (01 + 000 1 + 111 0)+ (01 + 000 1 + 111 0)(0 + 1)(0 + 1) .
(3.1)
0 0
start A B C 0
1
1 1 1
1 0 0/1
D E F G 0/1
2. je regularni izraz.
, a, ((c a) t),
((m e) (o) w), (a | (e | (i | (o | u)))), (a | (e | (i | (o | u)))) .
1. kk je prazan skup .
2. kk je {}, skup singlton koji sadri samo element .
3. Ako je a V, onda je kak skup {a}, skup singlton koji sadri samo a.
4. Ako su r1 i r2 dva regularna izraza ija denotacija je kr1 k i kr2 k, re-
spektivno, tada je k(r1 | r2 )k jednako kr1 k kr2 k, a k(r1 r2 )k jednako
kr1 k kr2 k.
5. Ako je r regularni izraz ija je denotacija jednaka krk, onda je kr k jednako
krk .
a {a}
((c a) t) {cat}
((m e) (o) w) {mew, meow, meoow, meooow, . . .}
(a | (e | (i | (o | u)))) {a, e, i, o, u}
skup svih rei koje se sastoje od sa-
(a | (e | (i | (o | u))))
moglasnika, ukljuujui i
Aksiom Opis
r(s | t) = rs | rt
distributivnost nadovezivanja u odnosu na |
(s | t) = sr | tr
r=r
je jedinini element z operaciju nadovezivanja
r = r
r = (r | ) relacija izmeu
i
r =r iteracija je idempotentna operacija
Operator je najvieg prioriteta. Operator nadovezivanja je sledei po priori-
tetu, dok je operator | najnieg prioriteta. Svi ovi operatori su levo asocijativni.
V = {a, b, c, . . . , x, y, z}.
start A Z
a
start A Z
Regularni izraz r+s ili r|s se prepoznaje automatom koji ima dve paralelne
grane, jednu u kojoj je automat za izraz r i drugu u kojoj je automat za izraz
s, prikazan na slici 3.7.
3.7. PRESLIKAVANJE REGULARNIH IZRAZA U KONANE AUTOMATE53
Ka(s)
start A Z
Ka(r)
Slika 3.7: Automat za regularni izraz r | s
Ka(s) Ka(r)
start A Z
start A Z
q0 u q1 n q2 d q3
start
q6 q5 q4
n n
cifra cifra
+
cifra .
start A B C D
e E
cifra F E
cifra
q0
q0 a q1
a
q0 c q1 a q2 t q3
((c a) t)
o
(((m e) (o) ) w) q0 m q1 e q2 w q3
a, e, i, o, u
q0 q1
(a | (e | (i | (o | u))))
q0 a, e, i, o, u
(a | (e | (i | (o | u))))
3.8 Pitanja
1. ta su to automati? Objasniti kako tee proces prepoznavanja rei auto-
matom.
3.9 Zadaci
1. Gramatika G zadata je sledeim skupom smena:
S aSdd | aAd,
56 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA
A bAc | b.
A 0C | 1B, B 0B | 1C,
C 0A | 1D, D 1D | .
A 0B | 1D, B 0C | 1F,
C 0C | 1F | , D 1E | 0F,
E 1E | 0F | , F 0G | 1G,
G 0G | 1G | .
V = {a, b, c, . . . , x, y, z, 0, 1, . . . , 9}
V = {0, 1} :
Leksiki analizator
Jednostavnija realizacija.
59
60 GLAVA 4. LEKSIKI ANALIZATOR
tabela
simbola
if (i == j)
z = 0;
else
z = 1;
leksiki analizator e ovo videti kao sledei niz slova:
4.1.1 Tokeni
Jedan token u sutini predstavlja skup nizova (rei). Na primer:
DO 10 I = 1, 100
bilo napisano
DO 10 I = 1. 100,
to je od strane leksikog analizatora prepoznato kao da promenljiva DO10I
dobija vrednost 1.100 umesto kao zaglavlje DO petlje. Ova greka je bila razlog
pada letilice.
62 GLAVA 4. LEKSIKI ANALIZATOR
Leksiki analizator se obino realizuje tako da se uvek gleda jedan ili vie simbola
unapred da bi se pravilno identikovala leksema .
Primera jezika u kojima su neke stvari bile loe postavljene pa su zbog toga
oteavale analizu ima mnogo. Pomenuemo jo neke:
Foo<Bar>,
dok je strim sintaksa:
Foo<Bar<Bazz>{}>.
4.1.2 abloni
Potreban nam je nain da jednoznano deniemo koji nizovi odgovaraju kom
tokenu. U te svrhe se obino koriste regularni izrazi. Meutim, prilikom deni-
sanja ovih regularnih izraza koristi se neto izmenjena notacija u odnosu na ve
korienu, to ilustruje sledei primer.
U ovoj notaciji vai da se simbol | koristi kao operator ili, simbol kao oznaka
za interval dok je
(r)? = r | i r+ = r \ .
4.1. NAMENA LEKSIKOG ANALIZATORA 63
Da zakljuimo:
leksiki analizator generie tabelu simbola u kojoj se pamte svi atributi rele-
vantni za odreeno simboliko ime. Da bi se kasnije moglo pristupiti odgovara-
juem slogu u tabeli simbola, uz token ID kojim se zamenjuju simbolika imena,
kao dodatni atribut se prenosi i pointer na slog u tabeli simbola koji odgovara
tom simbolikom imenu. Nekada se neki atributi prenose uz sam token, kao na
primer vrednosti konstanti i sl, kako je to pokazano u sledeem primeru.
E = M * C ** 2
Tokeni sa pridruenim atributima:
/
start q1
/ not *
* *
q2 q3 q4 *
not (* | /)
Ovaj primer pokazuje kako se tretiraju dvoznaci. U ovom sluaju za niz od dva
znaka koja ine jedan operator generie se jedan token.
start q1
<
q5 = q6
> q7
>
q8 = q9
=
q10
nema leksiki smisao: tek sa pojavom znaka = iza dvotake prelazi se u stanje
q17 koje je zavrno i u kome se generie odgovarajui token.
start q1
(
q11
)
q12
+
q13
-
* q14
*
q15
q16 = q17
slici 4.7 prikazan je graf automata koji prepoznaje celobrojne i realne konstante
zapisane u normalnom i eksponencijalnom zapisu, prema njihovoj deniciji u
programskom jeziku Pascal. Ove konstante denisane su regularnim izrazom
start q1
;
q18
slovo
q19 slovo | cifra
' '
q20 q21
'
not '
Slika 4.5: Prepoznavanje identikatora i literala
start q1
cifra
ostalo
q22 cifra
start q1
- +
E
ra
q2
cif
E
. +
a
cifr E
cifra q3 q16 q17
-
.
.
cif
ra
q4 q15
E
cifra
cifra
cifra q5
Slika 4.7: Automat koji prepoznaje brojeve prema deniciji u jeziku Pascal
Zbog toga je bitno kako su denisani leksiki elementi jezika. Ve smo pomenuli
problem sa duinom naredbe DECLARE u progrskom jeziku PL-1 koji se javljao
zbog toga to u ovom jeziku kljune rei nisu bile zatiene, ve su mogle da se
koriste i kao identikatori promenljivih.
E:= C * P + 90 EOF
pPo pKraj
Pseudokod algoritma koji se koristi pri analizi tehnikom dvostrukog bafera dat
je u nastavku.
pKraj := pKraj + 1;
if (pKraj <> eof) then begin
if pKraj na kraju prve polovine
then
reload druge polovine;
pKraj := pKraj + 1;
end
70 GLAVA 4. LEKSIKI ANALIZATOR
4.4 Pitanja
1. Objasniti namenu leksikog analizatora.
3. ta su to tokeni?
6. ta je to tablica simbola?
4.5 Zadaci
1. Identikovati lekseme u sledeem delu koda napisanog na programskom
jeziku C.
nonzero-digit 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
octal-digit 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
hexadecimal-digit 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
|a|b|c|d|e|f
| A | B | C | D | E | F.
=, *=, /=, %=, +=, -=, <<=, >>=, &=, =, |=,
Sintaksna analiza
73
74 GLAVA 5. SINTAKSNA ANALIZA
hidi hidihcifrai
hidihcifraihcifrai
hidihcifraihcifraihcifrai
hslovoihcifraihcifraihcifrai
ahcifraihcifraihcifrai
a1hcifraihcifrai
a11hcifrai
a111.
hidi hidihcifrai
hidi1
hidihcifrai1
hidi11
hidihcifrai11
hidi111
hslovoi111
a111.
hidi
hidi hcifrai
1
hidi hcifrai
hidi hcifrai 1
hslovoi 1
Sintaksno stablo koje se dobija jednim ili drugim postupkom izvoenja mora da
bude jednoznano denisano. Sintaksno stablo je osnova za generisanje asem-
blerskog koda, tako da bi dobijanje razliitog stabla znailo da se za isti ulazni
kd dobija razliiti skup asemblerskih naredbi, odnosno kd bi bio vieznano
denisan to je nedopustivo. Sledei primer predstavlja sluaj nejednoznano
denisane gramatike kod koje levo i desno izvoenje daju razliita sintaksna
stabla.
gde je P:
A B + hizrazi
A B + hidi
A B + A.
hizrazi
hizrazi * hizrazi
hidi
hizrazi + hizrazi
A
hidi hidi
B A
hizrazi
hizrazi + hizrazi
hidi
hizrazi * hizrazi
A
hidi hidi
A B
A B + A.
hizrazi
hizrazi + hsabiraki
hsabiraki hfaktori
hidi
hsabiraki * hfaktori
A
hfaktori hidi
hidi B
Prilikom realizacije ovog algoritma obino se koriste dva pokazivaa, pUlaz koji
pokazuje na znak u ulaznom nizu koje se u odreenom trenutku prepoznaje i
pRadni koji pokazuje na tekui znak u nizu koji se izvodi.
Prilikom analize obino se koristi neki specijalni znak kao zavrni, granini znak
niza. U naem sluaju e to biti simbol #.
Algoritam se formalno moe formulisati na sledei nain:
sa skupom pravila P:
1. S aAd,
2. S aB ,
3. A b,
4. A c,
5. B ccd,
6. B ddc.
Primenu algoritma pokazaemo na primeru rei a c c d #.
5.2. OSNOVNI ALGORITAM ZA TOP-DOWN SINTAKSNU ANALIZU 81
10 a ccd# a B# prepoznaje se a
11 a c cd# aB# primenjuje se (5)
a B
c c d
gramtike kod kojih postoje levo rekurzivna pravila , odnosno pravila oblika:
A Ar, gde je A Vn , r V .
S aAc,
S Aa,
S .
a A c
A a
A a
A a
S Aa | b,
A Sd | c | .
5.2. OSNOVNI ALGORITAM ZA TOP-DOWN SINTAKSNU ANALIZU 83
Ako gramatika sadri skup pravila za isti neterminalni simbol, meu kojima su
neka levo rekurzivna, a neka ne:
A A1 | A2 | | An | 1 | 2 | | m ,
A 1 | 2 | | m | 1 A0 | 2 A0 | | m A0 ,
A0 1 | 2 | | n | 1 A0 | 2 A0 | | n A0 .
A 1 A0 | 2 A0 | | m A0 ,
A0 1 A0 | 2 A0 | | n A0 .
E E + T | T,
T T F | F,
F (E) | a.
E T | T E0,
E 0 +T | +T E 0 ,
T F | F T 0,
T 0 F | F T 0 ,
F (E) | a.
X Y ,
84 GLAVA 5. SINTAKSNA ANALIZA
Y X1 | X2 | | Xn
x X1 | X2 | | Xn .
1. S Aa
2. Sb
3. A Sd
4. Ac
5. A
Prvo eliminiemo indirektna levo rekurzivna pravila. U datoj gramatici
pravila (1) i (3) su indirektno rekurzivna. Transformacija se vri tako
to se u smeni (1) neterminal A zameni desnim stranama svih smena za
taj neterminal. Kako se posle te zamene neterminal A ne pojavljuje u
desnoj strani ni jedne smene, neterminal A (kao i smene za preslikavanje
tog neterminalnog simbola) se moe eliminisati iz gramatike. Nakon ove
transformacije, gramatika e sadrati sledei skup smena:
S Sda, S ca,
S a, S b.
S ca, S a,
S b, S caS 0 ,
S aS 0 , S bS 0 .
Proveriti da li je blok
zamenjujemo smenama:
NizNar 0 (4)
86 GLAVA 5. SINTAKSNA ANALIZA
Dodela ID
:= Izraz (7)
Izraz CONST
Izraz 0 (8)
Izraz 0 + CONST
Izraz 0 (9)
Izraz 0 (10)
Blok
Naredba NizNar
Dodela
ID := Izraz
CONST Izraz
Pri realizaciji ovog algoritma koristi se magacin u koji se ubacuje slovo po slovo
iz ulaznog niza. Pri tome se u svakom koraku ispituje da li je mogue izvriti
redukciju niza koji je u vrhu magacina. Ako redukacija nije mogua, u maga-
cin se ubacuje novo slovo, a ako je mogua, prepoznati niz sa vrha magacina
se redukuje na neterminal koji je na levoj strani primenjene smene, odnosno
neterminal zamenjuje redukovani niz u magacinu. Analiza je uspeno izvrena
kada se doe do graninog simbola, a u magacinu ostane samo startni simbol.
sa skupom smena P:
S aAd (1)
S aB (2)
Ab (3)
Ac (4)
B ccd. (5)
Ulazni Niz u
niz magacinu Akcija
1 accd#
2 ccd# a Nema smene, ubacuje se novo slovo
5.4 Pitanja
5.5 Zadaci
1. Primenom osnovnog algoritma za top-down sintaksnu analizu proveriti da
li niz # READ ( ID , ID , ) # pripada jeziku gramatike G zadate
sledeim skupom pravila:
S S+I |I I I F |F
F a(S) | a.
93
94 GLAVA 6. PREDIKTIVNA ANALIZA LL-1 ANALIZATORI
A 1 1 | 2 2 | | n n , gde je ai Vt , i V , ai 6= aj za i 6= j.
S aS S bA
Ad A ccA,
pop,
ako je A = a, a Vt ,
acc,
ako je A = # a #,
Ts(A, a) =
(a, i), ako je A a i-to pravilo,
err,
u svim ostalim sluajevima.
6.1. PROSTE LL-1 GRAMATIKE 95
S (aS, 1) (bA, 2)
A (ccA, 4) (d, 3)
a pop
b pop
c pop
d pop
# acc
az , deo ulaznog niza koji tek treba da bude prepoznat, pri emu je a prvi
simbol u tom nizu, tj. a Vt i az Vt ,
A generisani niz u magacinu, pri emu je A simbol u vrhu magacina,
A V i V ,
p je niz smena koje su do tog trenutka primenjene za generisanje niza.
Ts(A, a) = pop,
(z, , p),
ako je
kraj,
ako je Rs(A, a) = acc,
(az, A, p) =
(az, , pi),
ako je Ts(A, a) = (, i) i-to pravilo,
greka Ts(A, a) = err.
ako je
A 1 | 2 | | n | , gde je , 1 , . . . , n , V A Vn ,
takva gramatika sigurno nije LL-1 gramatika, ali se lako moe transformisati u
LL-1 gramatiku primenom sledeih smena:
A aA0 |
A0 1 | 2 | | n
S 0 S# (1)
Ac (2)
S Abe (3)
B AS (4)
A dB (5)
Bb (6)
A aS (7)
1. A0 A#
2. A iB e
3. B SB
4. B
Za koji terminalni simbol e biti primenjeno takvo pravilo oigledno zavisi od
toga koji se simboli nalaze iza neterminala koji se ukida. U ovom primeru pravilo
B e moi da se primeni za one terminalne simbole koji mogu da se nau
iza neterminala B.
Kako bi u deniciji LL-1 gramatika obuhvatili sve ove sluajeve deniu se dve
funkcije koje nalaze primenu i kod nekih drugih tipova sintaksnih analizatora.
To su funkcije First i Follow.
V+ First() = {s |
s, gde je s Vt , V }.
6.2. POMONE FUNKICIJE ZA DEFINISANJE OPTIH LL-1 GRAMATIKA99
S 0 S# S Abe S dB A dB
A aS Ac B AS Bb
Tada je:
s, s Vt , V } = {a, c, d},
First(A) = {s | A
s, s Vt , V } = {a, c, d}.
First(ABe) = {s | ABe
1. Z Xx x Vt x Follow(x),
2. Z XY Y Vn First(Y ) Follow(X),
(Napomena: ukoliko postoji izvoenje Y , simbol Y se preskae i
gleda se nastavak smene.)
3. Z X Follow(Z) Follow(X).
A0 A# A iB B SB e B
100 GLAVA 6. PREDIKTIVNA ANALIZA LL-1 ANALIZATORI
S [eC] S i C eC C
Vai:
A0 A#
iB e#
isB e#
i[eC]B e#
i[e]B e#
i[e] e#
i
Follow(C) = {s Vt | A0
Cs} = {]}.
First(i ) First(j ) = , i 6= j.
pop,
ako je A = a, a Vt ,
acc,
ako je A = # a #,
Ts(A, a) =
(, i),
ako je a First() i A je i-to pravilo,
err, u svim ostalim sluajevima.
Sam postupak sintaksne analize je potpuno isti kao i kod prostih LL-1 gramatika.
sledei.
1
S0
S#
3
ABe#
5
dBBe#
4
dASBe#
2
dcSBe#
3
dcABeBe#
2
dccBeBe#
6
dccbeBe#
6
dccbebe#.
6.4. LL-1 GRAMATIKE SA -PRAVILIMA 103
2. Ako je i
, tada mora da vai i
A0 A# A iB e B SB B
S [eC] S i C eC C .
Kako je presek ova dva skupa prazan skup, uslov je ispunjen za ovaj ne-
terminal.
Za neterminal C vai:
pop,
ako je A = a , a Vt ,
acc,
ako je A = # a #,
Ts(A, a) = (, i), ako je a First() i A je i-to pravilo,
ili je a Follow(A) i A je i-to pravilo, za A Vn
err,
u svim ostalim sluajevima.
Prema ovoj deniciji sledi da se -pravila upisuju u polja odreena vrstom koja
odgovara neterminalnom simbolu koji se preslikava u i kolonama svih termi-
nalnih simbola koji pripadaju funkciji Follow za taj neterminalni simbol.
A (iB e, 1)
B (, 3) (SB, 2) (SB, 2)
S ([eC], 4) (i, 5)
C (eC, 6) (, 7)
i pop
pop
e pop
[ pop
] pop
pop
# acc
Sintaksna tabela se koristi u algoritmu za analizu na isti nain kao i kod pret-
hodno razmatranih jednostavnijih sluajeva LL-1 gramatika (primer 6.12).
NizNar' (4)
Izraz' (10)
Reenje. Vrimo analizu skupova smena koje na levoj strani imaju isti neter-
minalni simbol.
First(Dodela) = {id}
First(Blok) = {begin}
First(Dodela) First(Blok) =
S aT T SA | A
A bB | c Bd|
6.6 Pitanja
1. Dati deniciju proste LL-1 gramatike.
Tabela 6.1
S (aT, 1)
T (SA, 2) (A, 3) (A, 3)
A (bB, 4) (c, 5)
B (, 7) (, 7) (d, 6) (, 7)
a pop
b pop
c pop
d pop
# acc
6.7 Zadaci
1. Za LL-1 gramatiku zadatu skupom smena
E (E) T | i T T +E | E |
E (E) T | const T T +E | E | .
Korienjem generisane tabele proveriti da li izraz
Ulaz READ(NizPromenljivih)
NizPromenljivih NizPromenljivih , ID | ID
u gramatiku tipa LL-1 i kreirati odgovarajuu tablicu sintaksne analize.
Korienjem kreirane tabele proveriti da li izraz
# READ ( ID , ID , ) #
pripada jeziku date gramatike.
S aT T SA | A
A bB | c Bd|
S aT T SA | A
A bB | c Bd|
tipa LL-1. Ako jeste, kreirati njenu sintaksnu tabelu.
#aaabbcdd#
pripada jeziku koji je odreen ovom gramatikom.
S if b then S E | a
E else S | .
Korienjem formirane tabele proveriti da li niz
Analiza zasnovana na
relacijama prvenstva
U ovom poglavlju bie opisan poseban tip beskonteksnih gramatika koje omo-
guavaju bottom-up sintaksnu analizu bez vraanja unatrag koja se zasniva na
relacijama prioriteta. Ove gramatike nalaze primenu kod denisanja aritme-
tikih izraza, relacija i sl. koji kao delovi naredbi dodeljivanja ine veliki deo
programskog jezika.
C AB gde je A, B, C Vn i , V .
Postoje tri osnovne relacije prvenstva: < , >
i =.
111
112 GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA
C C
a b a A b
C C
a A
A b
b a
C aA i A
b ili A
Db
C Ab i A
a ili A
aD,
E E+T |T
T T F |F
F id
E 0 #E#.
b Ako se jo jednom primeni prva smena za preslikavanje simbola #E#, ne bi se dobile nove relacije; zato primenjujemo E T
7.2. OPERATORSKA GRAMATIKA PRVENSTVA 115
# E # # E # # E #
E + T E + T
E + T
# E # # E # # E #
E + T E + T E + T
E + T E + T E + T
T T T
T F T F
T F
# E # # E # # E #
E + T E + T E + T
id id id + T id id id + T id id id + T
T F T F T F
7.2. OPERATORSKA GRAMATIKA PRVENSTVA
F F
id
id + #
id
>
>
>
+ <
> <
>
<
>
>
>
# < < < =
Ulazni niz (t) dopuni se graninim simbolom (#) sa desne strane i u pomoni
stek () takoe se upie granini simbol (#). Zatim se na osnovu relacije prven-
stva koja vai izmeu poslednjeg terminalnog simbola u steku i sledeeg simbola
u ulaznom nizu odreuje akcija koja e se izvriti.
1. Ako vai relacija < ili relacija =, tekui terminalni simbol iz ulaznog niza
se upisuje u stek i ita se novi simbol iz ulaznog niza. Uz terminalni
simbol upisuje se i oznaka relacije prvenstva koju ima sa prethodnim sim-
bolom.
Osnovna ideja kod ovog postupka sinteze je da se identikuju fraze koje su vieg
prioriteta u odnosu na okruenje i da se one prve redukuju. Ukoliko je fraza nie
u sintaksnom stablu ona je vieg prioriteta redukuje se pre simbola iz okruenja.
t t + #;
0 #;
SP 0; /* SP je pokaziva na vrh magacina */
prepoznat 0;
greka 0;
next nextlex(t); /* poziv leksikog analizatora */
repeat
if SP Vt {#} then
i SP
end
else
i SP 1; /* i pokazuje na poslednji terminalni simbol u
magacinu */
end
if i < next i = next then
SP SP + 1;
SP = next;
next nextlex(t);
end
else if i >
next then
repeat
temp i ;
i i 1;
if i = P then
i i 1;
end
until i < temp;
if fraza i+1 , . . . , SP postoji u listi desnih strana smena then
SP i + 1;
SP P;
if SP = 2 next = # then
prepoznat 1
end
end
else
greka 1
end
end
else
greka 1
end
until prepoznat greka;
return prepoznat;
Algorithm 1: Pseudokod sintaksnog analizatora operatorskih gramatika pr-
venstva.
7.2. OPERATORSKA GRAMATIKA PRVENSTVA 121
# id + id id # # < id
# < id id + id id # id >
+
# < P id + id id # # < +
# < P + id + id id # + < id
# < P + < id id + id id # id >
# < P + P id + id id # + <
# < P + < P id + id id # < id
# < P + < P < id id + id id # id >
#
# < P + < P < P id + id id # >
#
# < P + P id + id id # #
+>
#P id + id id # izraz je prepoznat
Ako vai relacija a < b, postoji poteg od vora g(b) prema voru f (a).
Ako vai relacija
a = b, postoje potezi od vora f (a) prema voru g(b) i
od vora g(b) prema voru f (a).
Vrednost funkcije prvenstva se odreuje kao duina najdueg puta koji polazi
iz vora koji odgovara toj funkciji. Pod duinom puta podrazumeva se broj
vorova kroz koje put prolazi ukljuujui i sam taj vor.
i + #
F 5 3 5 0
G 6 2 4 0
Q2
Q1 > i Q2 < Q1 .
Q2 i Q2 >
Q1 > Q1 , ako su operatori levo asoscijativni i
7.3. OPTA PRAVILA PRIORITETA 123
g(i) f (i)
f () g()
g(+) f (+)
f (#) g(#)
Primeri:
+
+>
+> >
>
+ <
3. Levi granini simbol je nieg prioriteta od svih drugih simbola, dok svi
ostali simboli vieg prioriteta u odnosu na desni gramini simbol, tj.
# < Q i #.
Q>
Q < ( ( < Q Q
)> )
Q>
Napomena: Otvorena i zatvorena zagrada su istog prioriteta jedna u od-
nosu na drugu dok preioritet izmeu zatvorene i otorene zagrade ne treba
124 GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA
Q < id id >
Q # < id id >
# ( < id id >
)
+ / id ( ) #
+
>
> < < < < <
>
>
>
> < < < < <
>
>
>
>
>
> < < <
>
>
/
>
>
>
> < < <
>
>
>
>
>
> < < <
>
>
id
>
>
>
>
>
>
>
( < < < < < < < =
)
>
>
>
>
>
>
>
# < < < < < < < =
s=t
ako postoji smena oblika A st gde su s, t V, , V i
A Vn .
s < t ako postoji smena oblika A sB i B
t gde su s, t V,
, , V i A, B Vn .
s > t ako postoji smena oblika
A Bt i B
s ili ako postoji smena
A XZ i X 1 s i t2 , gde su s, t V, , , , 1 , 2 V i
y
A, B, X, Z Vn .
Beskonteksna gramatika kod koje se izmeu bilo koja dva simbola moe postaviti
najvie jedna relacija prvenstva naziva se gramatika prvenstva.
start = NizNaredbi.
X A A A
se zamenjuje smenama
X A A A0 A0 A0
126 GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA
Odnosno, smene
X A A A
zamenjuju se sa
X A A A0 A0 A
Program P
NizNaredbi N
NizNaredbi' NN'
Naredba N
P 0 # P #.
Kao rezultat ove analize dobija se tabela prvenstva data u tabeli 7.5.
P0 P0 P0
# P # # P # # P #
NN'
P0 P0
# P # # P #
NN' NN'
NN' ; N NN' ; N
P0 P0 P0
# P # # P # # P #
N N N
P0 P0 P0
# P # # P # # P #
izvriti:
1. Ako vai relacija < ili relacija =, tekui simbol iz ulaznog niza smestiti u
stek i prei na analizu sledeeg simbola.
2. Ako vai relacija treba ii dublje u stek i traiti prvi simbol u steku koji je
>
< od svog sledbenika i proveriti da li fraza sa vrha steka (sadraj magacina
od uoenog simbola do vrha) predstavlja desnu stranu neke smene. Ako
jeste, umesto cele fraze u stek treba ubaciti simbol sa leve strane te smene
(tj. izvriti redukciju), u suprotnom, u zapisu postoji greka i analizu treba
prekinuti. Kada se redukcija uspeno izvede treba ispitati da li je sledei
ulazni simbol #, a sadraj steka #S (gde je S startni simbol gramatike).
Ako su ti uslovi zadovoljeni, znai da je ceo ulazni niz redukovan na startni
simbol gramatike, tj. niz je prepoznat.
t t + #;
0 #;
SP 0; /* SP je pokaziva na vrh magacina */
prepoznat 0;
greka 0;
next nextlex(t); /* poziv leksikog analizatora */
repeat
if SP < next SP = next then
SP next;
SP SP 1;
next nextlex(t);
end
else if i >
next then
i SP;
repeat
temp i ;
i i 1;
until i < temp;
if postoji smena oblika i+1 , . . . , SP then
SP i + 1;
SP P;
if SP = 2 SP = s next = # then
prepoznat 1
end
end
else
greka 1
end
end
else
greka 1
end
until prepoznat greka;
return prepoznat;
Algorithm 2: Pseudokod algoritma za sintaksnu analizu gramatika prvenstva.
132 GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA
# start <
# start ulaz <
# start ulaz ;
>
# start N ;
>
# start NN' ;
=
# start NN' ; dodela <
# start NN' ; dodela ;
>
# start NN' ; N ;
>
# start NN' ;
=
# start NN' ; izlaz <
# start NN' ; izlaz end
>
# start NN' ; N end
>
# start NN' end
>
# start NN end
=
# start NN end #
>
# P # X
7.5 Pitanja
7.6 Zadaci
1. Proveriti da li je gramatika iz primera 7.1 gramatika prvenstva. Ako nije,
dodenisati je tako da zadovoljava uslove gramatike prvenstva i kreirati
njenu tablicu prvenstva.
SS+I|I
I ( S ) | f ( S ) | id
# id + f ( id + f ( id ) ) ) #
SP
P R or Q | Q
QT
T T and R | R
R V | not V
V ( S ) | true | false.
# READ ( id , id , ) #
enum id { id , id = const } ;
pripada jeziku ove gramatike.
S S+I |I
I (S) | a(S) | a
LR analizatori
135
136 GLAVA 8. LR ANALIZATORI
ulazni niz
# a1 a2 ai an #
LR sintaksni
magacin
Sn
analizator
Xn
Sn1
LR sintaksna tabela
.
.
.
S0
err (error ) znai da u ulaznom nizu postoji greka i teba prekinuti dalju
analizu.
8.1. OPIS ANALIZATORA 137
E E+T (1)
ET (2)
E EF (3)
T F (4)
F (F ) (5)
F id (6)
id + ( ) # E T F
0 s5 s4 1 2 3
1 s6 acc
2 r2 s7 r2 r2
3 r4 r4 r4 r4
4 s5 s4 8 2 3
5 r6 r6 r6 r6
6 s5 s4 9 3
7 s5 s4 10
8 s6 s11
9 r1 s7 r1 r1
10 r3 r3 r3 r3
11 r5 r5 r5 r5
0 id id + id# shift 5
0 id 5 id + id# reduce(F id)
0F 3 id + id# reduce(T F )
0T 2 id + id# shift 7
0T 2 7 id + id# shift 5
0 T 2 7 id 5 + id# reduce(F id)
0 T 2 7 F 10 + id# reduce(T T F )
0T 2 + id# reduce(E T )
0E 1 + id# shift 6
0E1+ 6 id # shift 5
0 E 1 + 6 id 5 # reduce(F id)
0E1+6F 3 # reduce(T F )
0E1+6T 9 # reduce(E E + T )
0E 1 # acc
E E+T
E+F
E + id
E + T + id
E + F + id.
E, E+ i E + F.
E + T
E + T F
F id
Gramatika G je LR(k) gramatika ako se za bilo koji ulazni niz, u svakom koraku
izvoenja fraza (podniz) moe detektovati na osnovu preksa i skaniranjem
najvie k znakova niza t.
Izvoenje (na osnovu nekog pravila) sa takom u bilo kojoj poziciji u nizu se
naziva LR(0) lan.
E E + T
E E +T
E E + T
EE + T
E E+T (1)
ET (2)
T T F (3)
T F (4)
F (E) (5)
F id (6)
E0 E
E E + T
E T
T T F
T F
F (E)
F id
I1 = goto(I0 , T )
E0 E
E E +T
I2 = goto(I0 , T )
ET
T T F
I3 = goto(I0 , F )
T F
I4 = goto(I0 , ()
F (E)
E E + T
E T
T T F
8.3. REALIZACIJA SLR ANALIZATORA 145
T F
F (E)
F id
I5 = goto(I0 , id)
F id
I6 = goto(I1 , +)
E E + T
T F
T F
F (E)
F id
I7 = goto(I2 , )
T T F
F (E)
F id
Kako skup I3 sadri samo jedan lan kod kojeg je taka na kraju, nad njim
se ne moe primeniti funkcija goto i formirati novi skup.
I8 = goto(I4 , E)
F (E)
E E +T
Meutim premena goto funkcije nad skupom I4 gnerie i neke skupove koji
ve postoje, pa zato te skupove ne uzimamo kao nove. Naime, vai sledee.
goto(I4 , T ) = I2
146 GLAVA 8. LR ANALIZATORI
goto(I4 , F ) = I3
goto(I4 , ( ) = I4
goto(I4 , id) = I5
Primena goto funkcije nad skupom I5 takoe nije mogua zato to, kao i
skup I3 , sadri samo jedan lan sa takom na kraju.
I9 = goto(I6 , T )
E E + T
T T F
goto(I6 , F ) = I3
goto(I6 , () = I4
goto(I6 , id) = I5
I10 = goto(I7 , F )
T T F
kao i
goto(I7 , () = I4 ,
goto(I7 , id) = I5 .
Skup I8 daje
I11 = goto(I8 , ) )
E (E)
kao i
goto(I8 , +) = I6 .
8.4. REENI ZADACI 147
Skup I9 daje
goto(I9 , ) = I7
P start NN end.
Kako smo rekli da taka razdvaja prepoznati deo (vidljivi preks) od neprepo-
znatog, to znai da, kada se analizator nae u posmatranom stanju, u nastavku
148 GLAVA 8. LR ANALIZATORI
id
5
(
4
start 0
F
3
E
+ T
1 6 9 7
T
F
F
2 7 10
(
(
4
id id
5
3 T
E )
4 8 11
+
( id 6
analize oekujemo pojavu simbola koji se nalaze iza taaka u pravilima koja
pripadaju tekuem zatvaranju. U konkretnom primeru, simboli koji se oekuju
u stanju I0 su P i start. To znai da treba denisati dva prelaza iz zatvaranja
I0 kada se pojavi simbol P i kada se pojavi simbol start.
I1 = goto(I0 , P )
P0 P .
Poto se taka nala na kraju pravila, ovo stanje je redukciono stanje za smenu iz
koje je pravilo izvedeno (tj. za smenu P 0 P ). Poto je ovo pomona (ktivna)
smena, ova redukcija se ne vri, ve kad analizator doe do ovog stanja, ukoliko
je ceo ulazni kod analiziran, ulazni kod se prihvata (tj. korektan je).
I2 = goto(I0 , start :
P start NN end.
NN NN ; N
NN N
N ulaz
N izlaz
N dodela
I3 = goto(I2 , NN :
I5 = goto(I3 , ;) NN NN ; N
N ulaz
N izlaz
N dodela
I6 = goto(I5 , N ) NN NN ; N
I7 = goto(I2 , N ) NN N
I8 = goto(I2 , ulaz) N ulaz
I8 = goto(I2 , izlaz) N izlaz
I8 = goto(I2 , dodela) N dodela
goto(I5 , ulaz) = I8
goto(I5 , izlaz) = I9
goto(I5 , dodela) = I10
Upis reduce akcija. reduce akcije se piu u vrstama koje odgovaraju zavrnim
stanjima automata. Na primer, zavrno stanje I4 sadri redukciono pravilo
8.4. REENI ZADACI 151
P
start I0 I1
start
NN end
I2 I3 I4
N ;
N
I7 I5 I6
ulaz
I8 ulaz
izlaz
izlaz
I9
dodela
dodela
I10
Follow(N N ) = {end, ;}
Follow(N ) = Follow(NN) = {end, ;}.
1 acc
2 s8 s9 s10 3 7
3 s4 s5
4 r1
5 s8 s9 s10 6
6 r2 r2
7 r3 r3
8 r4 r4
9 r5 r5
10 r6 r6
0 start s2
0 start 2 ulaz s8
0 start 2 NN 3 ; 5 izlaz s9
EE+I|I
Ia(E)|a
Reenje. Kanoniki skup lanova ove gramatike dat je u nastavku, graf prelaza
konanog automata za prepoznavanje vidljivih preksa na slici 8.4, a sama LR
sintaksna tabela u tabli 8.3.
I0 : E 0 E
E E + I
E I
I a(E)
I a
I1 = goto(I0 , E) : E 0 E
E E +I
I2 = goto(I1 , +) : E E + I
I a(E)
I a
I3 = goto(I2 , I) : E E + I
I4 = goto(I0 , I) : E I
I5 = goto(I0 , a) : I a (E)
I a
I6 = goto(I5 , () : I a(E)
E E + I
E I
I a(E)
I a
I7 = goto(I6 , E) : I a(E)
E E +I
8.5. PITANJA 155
I8 = goto(I7 , )) : I a(E)
S + I
start 0 1 2 3
a
I
4 5
I
(
a )
S
5 6 7 8
a
Slika 8.4: Graf automata za prepoznavanje vidljivih preksa uz zadatak 4
a + ( ) # S I
0 s5 1 4
1 s2 acc
2 s5 3
3 r1 r1 r1
4 r2 r2 r2
5 r4 s6 r4 r4
6 s5 7 4
7 s2 s8
8 r3 r3 r3
8.5 Pitanja
1. Objasniti strukturu LR analizatora.
8.6 Zadaci
1. Kreirati LR sintaksnu tabelu za gramatiku zadatu skupom smena
case 1 : ID = CONST ;
case 2 : ID = ID ; break ;
E ( E ) T | const T
T +E|E|
S S+I |I
I ( S ) | f ( S ) | id
# id + f ( id + *f ( id ) ) ) #
E E + E | E E | E + + | E | id.
SSAT |T
T T M F |F
A + | | or
M | / | mod | div | and
F id
S S+I |I
I ( S ) | F ( S ) | id
F sin | cos | abs | sqr
begin d ; d ; s ; s end
pripada jeziku koji je denisan datom gramatikom.
E E O E | ( E ) | num
O+|||/
Tabele simbola
Na primer,
ime,
159
160 GLAVA 9. TABELE SIMBOLA
at pristup kod koga jedinstvena struktura podataka sadri sve podatke
koji se mogu pamtiti o svim moguim vrstama entiteta (odnosno tipova) i
struct TypeNode {
static const Int = 0, Char = 1, Float = 2,
Double = 3, Struct = 4, Arr = 5;
struct ObjectNode {
// konstante kojima se definie vrsta entiteta
static const int Con = 0, Var = 1, Type = 2,
Fld = 3, Meth = 4;
String name;
int kind; // Con, Var, Type, Fld, Meth
TypeNode* type;
ObjectNode* next;
struct Polinom {
int power;
float* coefficients;
};
name: Polinom
king: Type
next: null
adr: /
parametersNo: /
parameters: /
value: /
type
name: power name: coefficients
kind: Fid kind: Fid
kind: Struct elds adr: 0x00FF0052 next adr: 0x00FF0054
elementsType: / parametersNo: / parametersNo: /
eldsNo: 2 parameters: / parameters: /
value: / value: /
type type
elementsType
kind: Float
elementsType: /
eldsNo: /
elds: /
- eldsNo: int
1
TypeNode
- elementsType
- kind: int
1
- type 1
next 1
ObjectNode
- name: string *
- kind: int - parameters
Constant Method
Variable Type Field
- adr: int - parametersNo: int
- adr: int - adr: int
- value: objct - adr: int 1
- elds *
164
sintaksni i semantiki
analizator
tabela simbola
symbols
brisanje simbola je, takoe, brzo (uvek se briu najpre simboli sa poetka
liste to e biti objanjeno u sledeem poglavlju).
Tabela simbola realizovana kao ureeno binarno stablo prikazana je na slici 9.5.
Osobine ovako realizovane tabele simbola su:
traenje simbola je bre nego u sluaju lanane liste (proseno vreme tra-
enja u ureenom binarnom stablu je log2 n, ali, s obzirom da je ovako kre-
irano binarno stablo prilino neizbalansirano, to vreme moe biti i mnogo
due),
symbols
name: m
kind: Meth
name: a name: T
kind: Var kind: Type
name: b name: n
kind: Var kind: Const
name: c
kind: Var
utroak memorijskog prostora je vee nego kod lanane liste jer se uz svaki
element pamte po dva pokazivaa na potomke.
name: b
0
kind: Var
name: c name: m
3 kind: Var kind: Meth
Na slici 9.6 je prikazana tabela simbola realizovana kao hash tabela pri emu
je pretpostavljeno da se za smetanje sinonima koristi spoljanje ulanavanje.
Osobine ovako realizovane tabele simbola su:
utroak memorijskog prostora je vei nego kod lanane liste jer u hash
tabeli uvek ostaje dosta nepopunjenih polja (ak i kada se unapred zna
9.5. TABELE SIMBOLA I OBLAST VAENJA SIMBOLIKIH IMENA 167
Na listingu 2 prikazan je jedan deo Java koda u kojem su obeleene oblasti va-
enja pojedinih imena. Uzet je programski jezik Java jer se u njemu implemen-
tacija funkcija lanica klasa pie u samoj klasi pa je lake uoiti ugnjedavanje
opega.
Ako se uzme u obzir postojanje opsega, traenje imena u tabeli simbola bi tre-
balo modikovati tako da se prvo vri traenje u poslednjem otvorenom opsegu,
pa tek ako se tu ime ne nae, trai se u spoljanjem, pa u prethodnom, itd. To
znai da se u tabeli simbola mora da uva i informacija o tome u kom opsegu
je simbol denisan. Ovaj problem se reava na dva naina:
Ako se pristupa nekom imenu koje nije denisano u tekuem opsegu, pre-
trauje se vei broj tabela simbola to usporava traenje.
Ako su tabele realizovane kao hash tabele, za svaki opseg se kreira nova
tabela pa kada je broj imena u opsegu mali dolazi do velikog rasipanja
memorijskog prostora. Zbog toga se u ovakvim sluajevima tabele simbola
obino realizuju kao lanane liste.
Ukoliko se koristi jedinstvena tabela simbola za sve opsege javlja se, opet, pro-
blem troenja dodatnog memorijskog prostora jer se uz svaki simbol pamti i
opseg kojem pripada. to se brzine traenja u tabeli tie, prednost korienja
hash tabela naroito dolazi do izraaja u ovom sluaju jer opseg kojem simbol
pripada ne utie na njegov poloaj u hash tabeli pa je svejedno da li je korieni
simbol denisan u tekuem opsegu ili nekom dalekom spoljanjem. Ureena
binarna stabla su daleko najnepogodnija za jedinstvenu tabelu simbola, jer e
simboli denisani u tekuem opsegu uvek biti na najniim nivoima u stablu.
Zbog toga se preporuuje da kada se koristi jedinstvena tabela simbola, koristi
hash tabela, a kada se prave posebne tabele za svaki opseg, prednost se daje
9.5. TABELE SIMBOLA I OBLAST VAENJA SIMBOLIKIH IMENA 169
Primer 9.2
// tacka 1
const double pi = 3.14;
class Polinom {
int stepen;
int koef[100];
// tacka 2
double vrednost(dbouel x) {
double s = 0;
// tacka 3
for (int i = 0; i < stepen; i++) {
s = s * x + koef[i];
}
}
// ...
};
void main() {
Polinom p;
// tacka 4
// ...
}
Prvi sluaj. Jedinstvena tabela simbola pored svakog simbola se pamti
i nivo na kojem je denisan.
symbols
symbols
Taka 4: Ova taka se nalazi u opsegu funkcije main. Osim lokalnih pro-
menljivih ove funkcije, u taki su vidljiva i imena iz spoljanjih opsega
(globalnog i opsega samog jezika).
symbols
top
scope
symbols
name: int name: cin language
kind: Type kind: Var scope
next
top
scope
symbols
name: koef name: stepen class
kind: Fld kind: Fld scope
next
symbols
name: Polinom name: pi global
kind: Type kind: Const scope
next
symbols
name: int name: cin language
kind: Type kind: Var scope
next
top
scope
symbols
name: s name: x method
kind: Var kind: Var scope
next
symbols
name: vrednost name: koef name: stepen class
kind: Meth kind: Fld kind: Fld scope
next
symbols
name: Polinom name: pi global
kind: Type kind: Const scope
next
symbols
name: int name: cin language
kind: Type kind: Var scope
next
top
scope
symbols main
name: p
method
kind: Var
next scope
symbols
name: main name: Polinom name: pi global
kind: Meth kind: Type kind: Const scope
next
symbols
name: int name: cin language
kind: Type kind: Var scope
next
9.6 Pitanja
1. ta je tabela simbola?
9.7 Zadaci
1. Proiriti sturkuru podataka koja se koristi za predstavljanje tipova u at
metodi tako da bude primenljiva i na jezike koje sadre i klase kao kori-
snike tipove podataka. Graki predstaviti strukutu podataka kojim bi
se korienjem tako denisane strukture klasa Krug predstavila u tabeli
simbola:
class Krug
{
private:
int r;
public:
void postaviR(int r);
float obima();
174 GLAVA 9. TABELE SIMBOLA
float povrsina();
};
2. Za zadati deo koda prikazati kako bi izgledala ogranizacija tabele simbola
u obliku lanane u obeleenim takama, ako se koristi:
Generatori leksikih i
sintaksnih analizatora
Lex i Yacc su izabrani jer su to alati ovog tipa koji su se prvi pojavili. Razvi-
jeni su Bell -ovim laboratorijama kao deo UNIX operativnog sistema jo 1975.
godine. Format njihovih specikacija se, sa nekim sitnim izmenama, koristi i u
svim alatima ove vrste koji su razvijani kasnije. Prve verzije ovih alata generiu
kod na programskom jeziku C. Iako su poetno denisani u UNIX-u, Lex i Yacc
su kasnije postali i obavezan deo Honeywell -ovog operativnog sistema GCOS,
kao i IBM-ovih operativnih sistema.
JFlex i Cup su alati koji generiu kod u jeziku Java. Njihova dobra osobina je
to su to programi otvorenog koda (open source ; kod im je besplatno raspoloiv
na internetu), zbog ega nalaze veoma iroku primenu u praksi.
Lex generie kod na osnovu ulazne Lex specikacija koja sadri tri osnovna dela
koja se zapisuju na sledei nain:
<definicije>
%%
175
176GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA
<pravila>
%%
<korisniki_potprogrami>
Lex specikacija se upisuje u fajl ije ime obavezno ima ekstenziju .l.
%%
<pravila>
Jedno pravilo Lex specikacije sadri dva dela:
[1-9][0-9]*.
Ovim regularnim izrazom izdvajaju se podnizovi koji poinju nekim od
simbola iz intervala [1 . . . 9], nakon kojeg se simboli iz intervala [0 . . . 9]
pojavljuju nijednom ili vie puta.
znak znaenje
( ) grupisanje simbola
~ prihvata sve simbole do pojave znaka ili grupe koja sledi, uklju-
ujui i taj znak/grupu
znaka, ime se dolazi do denicija celog broja. Celi broj se defnie kao
oznaeni ili neoznaeni niz dekadnih cifara, moe ali ne mora da sadri
predznak. Odgovarajui regularni izraz je
[+-]?[1-9][0-9]*.
Konano, numerika konstanta se u veini programskih jezika denie kao
oznaeni ili neoznaeni niz dekadnih cifara koji opciono sadri decimalnu
taku i/ili eksponent. Kompletan regularni izraz za prepoznavanje nume-
rikih konstanti je:
[+-]?[0-9]+(\.[0-9]+)?([Ee][=-]?[1-9]+)?.
\. oznaava da se na toj poziciji oekuje pojavljivanje ba take (ne bilo
kog simbola to taka kao metasimbol oznaava). Decimalna taka i niz
cifara iza nje su opcioni, zbog toga su udrueni u grupu (navedeni unutar
okruglih zagrada) iza koje stoji simbol ?. Na isti nain je navedeno i
opciono pojavljivanje eksponenta.
C.
-$
denicije makroa.
%x COMMENT1 COMMENT2
%%
\/\/ begin(COMMENT1);
<COMMENT1> \n begin(0);
<COMMENT2> . ;
\/\* begin(COMMENT2);
<COMMENT2> \*\/ begin(0);
<COMMENT2> . ;
ImeMakroa RegularniIzraz
Kao to je u tabli 10.1 ve navedeno, u uzorcima se makro poziva navoenjem
imena makroa, na sledei nain:
{ImeMakroa}
10.1. LEX GENERATOR LEKSIKIH ANALIZATORA 181
cifra [0-9]
%%
[+-]?{cifra}+(\.{cifra}+)?((Ee)[+-]?{cifra}+)?
lex <ime_specifikacije>.l
i on generie izlazni fajl pod imenom lex.yy.c. Kada se ovaj kod dalje prevodi
UNIX-ovim kompilatorom cc, treba u pozivu kompilatora navesti opciju -ll,
tj. generisani kod se dalje prevodi komandom:
cc ll lex.yy.c.
U generisanom C kodu, glavna funkcija, funkcija koja izdvaja sledei podstring
iz ulaznog teksta, ili ako se radi o leksikom analizatoru, funkcija koja izdvaja
sledeu re programskog jezika je funkcija int yylex().
Funkcija vraa rezultat tipa int, jer se u daljem toku analize sve rei pro-
gramskog jezika identikuju pomou svog jedinstvenog celobrojnog identika-
tora (tokena). Osim funkcije yylex(), Lex generie i niz pomonih promenljivih
i funkcija koje denie na globalnom nivou, tako da korisnik moe da ih koristi
u svojim akcijama ili korisnikim potprogramima.
Za izvesne tipove rei za dalji tok prevoenja nije dovoljno znati samo kojoj vrsti
pripadaju. Recimo, ako se radi o konstanti, treba znati koja je njena vrednost,
ako se radi o simbolikom imenu, treba znati njegovo ime (a kasnije i ostale
informacije ta imenuje, koji mu je tip...). Informacije o simbolikim imenima
10.1. LEX GENERATOR LEKSIKIH ANALIZATORA 183
// Tokens.h
#define END 257
#define READ 258
#define WRITE 259
#define ID 260
#define CONST 261
#define ERRSIMBOL 262
union AttributeType
{
float value;
int index;
};
// Symbol.h
struct Symbol
{
char name[32];
// ...
};
#include "Tokens.h"
#include "Symbol.h"
/* definicije makroa */
cifra [0-9]
slovo [a-zA-Z]
%%
/* pravila */
/* kljucne reci */
"end" return ( END );
"read" return ( READ );
"write" return ( WRITE );
10.1. LEX GENERATOR LEKSIKIH ANALIZATORA 185
/* simbolicka imena */
{slovo}|_({slovo}|{cifra}|_)*
{
attribute.index = getSymbol();
return (ID);
}
/* konstante */
{cifra}+(\.{cifra}*)?([Ee][+-]?{cifra}+)?
{
attribute.value = atof(yytext);
return (CONST);
}
/* operatori i separatori */
[+*=();] return( yytext[0] );
%%
/* korisnicki potprogrami */
symbolNo=0;
lineNo=1;
od sledeih delova:
definicije
%%
pravila
%%
korisniki potprogrami
Obavezni deo, kao i u Lex specikaciji, su pravila, dok su denicije i korisniki
potprogrami opcioni .
Zaglavlje koje se upisuje u generisani C program ima isti format i istu ulogu
kao u Lex specikaciji (poinje linijom sa simbolom %{, a zavrava se linijom sa
simbolom %}).
Yacc denicijama se deniu terminalni simboli gramatike (tokeni), startni sim-
bol gramatike, prioritet i asocijativnost operatora, tip dodatnih atributa termi-
nalnih i neterminalsnih simbola gramatike.
Poto se Yacc imena tokena zamenjuju celim brojevima, imena tokena ne smeju
biti kljune rei programskog jezika u kojem se generie kod analizatora.
188GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA
%union
{
<type1> <value1>;
<type2> <value2>;
...
<typeN> <valueN>;
}
Da se ne bi, pri korienju dodatnih atributa, stalno pisala komponenta koja je
aktivna, u Yacc specikaciji se moe za svaki terminalni i neterminalni simbol
denisati koji lan iz navedene unije se koristi kao njegov atribut. Denisanje
tipa dodatnih atributa terminalnih simbola se navodi u deniciji %token, dok
se za denisanje tipa dodatnih atributa neterminalnih simbola koristi denicija
%type.
Format denicije %token koja odreuje i tip dodatnih atributa navedenih tokena
je:
%union
{
float floatValue;
int intValue;
struct Symbol
{
char name[32];
char type[12];
} symbolValue;
/* ... */
}
/* ... */
%token<floatValue> CONST
%token<symbolValue> ID
%type<intValue> PARAMETERLIST
// npr. atribut je broj parametara
/* ... */
Ukoliko u gramatici postoji vei broj smena koje preslikavaju isti neterminalni
simbol, mogue je za svaku smenu pisati nezavisno pravilo; npr:
A : B C D;
A : E F;
A : G;
Alternativno, moe se koristiti skraeni zapis za viestruko preslikavanje:
A : B C D
| E F
| G
;
U akcijama se vrlo esto koriste vrednosti dodatnih atributa simbola koji ue-
stvuju u smeni za koju je akcija vezana. Promenljive koje se koriste kao dodatni
atributi simbola su:
{ $$ = $1; }
S obzirom da tip atributa simbola koji se nalazi na levoj strani smene i prvog
simbola na desnoj strani ne mora da bude isti, korienje ove podrazumevane
akcije je vrlo rizino (kompajler moe da prijavi greku u neslaganju tipa koju
vi u kodu ne moete da uoite). Zbog toga je preporuljivo da se, kada prilikom
neke redukcije analizator ne treba nita dodatno da uradi, odgovarajuoj smeni
pridrui akcija bez dejstva:
{ ; }
int yyparse();
Rezultat ove funkcije je 0 ukoliko je analiza uspeno izvrena do kraja ulaznog
fajla.
%{
#include <ctype.h>
%}
192GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA
//definicija tokena
%token NUM
%%
//pravila
E1 : E '\n' {puts("prepoznat aritmeticki izraz");};
E : E '+' E {;};
| E '-' E {;};
| E '*' E {;};
| E '/' E {;};
| '(' E ')' {;};
| NUM {;};
;
%%
int yylex()
{
int c;
while ((c = getchar()) == ' ');
if (isdigit(c))
return NUM;
return c;
}
void main()
{
yyparse();
}
E : '(' E ')'
Oporavak od ove greke bi podrazumevao da, kada zagrada nedostaje, prijavimo
greku, a da se analiza ipak nastavi. To znai da treba uvesti ktivnu smenu po
kojoj e se vrsiti redukcija ako zagrada nedostaje. U takvim smenama koristi se
kljuna re error koja zamenjuje skup simbola proizvoljne duine za koji akcija
u odreenom stanju nije denisana. U ovom sluaju, ako zagrada nedostaje,
vrie se redukcija po smeni:
// Fajl Symbol.h
struct Symbol
{
char name[32];
// linija u kojoj je symbol poslednji put definisan
int lastDef;
// linija u kojoj je symbol poslednji put korien
int lastUse;
};
194GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA
// Fajl Program.y
%{
#include "Symbol.h"
#include <stdio.h>
extern int yylex();
extern int lineNo;
extern int symbolNo;
extern struct Symbol symbolTable[];
extern FILE* yyin;
extern char* yytext;
%}
%union
{
int index;
float value;
}
%%
Program : NizNar END { printf("analiza je zavrsena\n"); };
NizNar : NizNar ';' Naredba { ; }
| NizNar ';' error
{ printf("linija %d: oekuje se naredba nakon ;",
lineNo); }
| NizNar error
{ printf("linija %d: oekuje se ; ili end",
lineNo); }
| Naredba { ; }
| error
{ printf("linija %d: neoekivani simbol %s\n",
lineNo, yytext); }
;
Naredba : Ulaz { ; }
| Izlaz { ; }
| Dodela { ; }
;
{
printf("linija %d: nedostaje )\n", lineNo );
symbolTable[$3].lastDef = lineNo;
}
| READ '(' error
{ printf("linija %d: nedostaje identifikator\n", lineNo); }
| READ error
{ printf("linija %d: nedostaje (\n", lineNo); }
;
%%
#include "lex.yy.c"
void main()
{
int i;
lineNo = 1;
symbolNo = 0;
yyin = fopen("ulaz.ml", "r");
yyparse();
for (i = 0; i < symbolNo; i++)
if (symbolTable[i].lastDef > symbolTable[i].lastUse)
{
printf("upozorenje: vrednost %s postavljena u liniji %d",
symbolTable[i].name, symbolTable[i].lastDef);
printf("nije nigde koriscena.\n");
}
}
Za generisanje potrebnog leksikog analizatora se moe koristiti Lex speci-
kacija iz primera 10.11 uz sledee promene.
%{
#include <ctype.h>
%}
//definicija tokena
%token NUM
%%
//pravila
E1 : E '\n' { printf(%d\n, $1); };
E : E '+' E { $$ = $1 + $3; }
| E '-' E { $$ = $1 - $3; }
| E '*' E { $$ = $1 * $3; }
| E '/' E { $$ = $1 / $3; }
| '(' E ')' { $$ = $2; }
| NUM { $$ = $1; }
;
%%
int yylex()
{
int c;
while ((c=getchar()) == ' ');
if (isdigit(c))
{
yylval = c - '0';
return NUM;
}
return c;
198GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA
void main()
{
yyparse();
}
// Fajl Symbol.h
struct Symbol
{
char name[32];
// linija u kojoj je symbol poslednji put definisan
int lastDef;
// linija u kojoj je symbol poslednji put korien
int lastUse;
// vrednost simbola
float value;
};
// Fajl Program.y
%{
#include "Symbol.h"
#include <stdio.h>
extern int yylex();
extern int lineNo;
extern int symbolNo;
extern struct Symbol symbolTable[];
extern FILE* yyin;
extern char* yytext;
%}
%union
{
int index;
float value;
}
%token<vrednost> CONST
%type<vrednost> Izraz Proizvod Faktor
%%
Naredba : Ulaz { ; }
| Izlaz { ; }
| Dodela { ; }
;
| ID
{
if (symbolTable[$1].lastDef == 0)
{
printf("linija %d: promenljiva %s se",
lineNo, yytext );
printf(" koristi pre nego to");
printf(" je inicijalizovana\n");
return 1;
}
$$ = symbolTable[$1].value;
tabelaSimbola[$1].posKor = brLinije;
}
| CONST { $$ = $1; }
;
%%
void main()
{
lineNo = 1;
symbolNo = 0;
yyin = fopen("ulaz.ml", "r");
yyparse();
}
10.3 JFlex
Na Prinston univerzitetu 1996. godine razvijen je alat JLex, koji generie izvorni
kod leksikih analizatora u programskom jeziku Java. JFlex je modikacija i
nadgradnja funkcionalnosti JLex-a. Ovo je besplatan i open source alat.
JFlex specikacija, takoe, sadri tri osnovna dela, ali su drugaije rasporeeni
nego u Lex specikaciji. Dakle, format JFlex specikacije je:
<korisniki_kod>
%%
<opcije_i_direktive>
%%
<pravila>
Korisniki kod sadri java naredbe koje se prepisuju na poetak generisanog
fajla. Tu se uglavnom piu import i package naredbe. Opcije i deklaracije
sadre:
JFlex direktive i
denicije makroa.
%class <ImeKlase > denie ime generisane klase. Ukoliko ova ocija
nije navedena, ime generisane klase je Yylex.
%implements <intrefejs1 >[,<interfejs2 >][,...] ukoliko je
ova direktiva navedena, generisana klasa implementira navedene in-
terfejse.
%debug generie se main metod koji poziva leksiki analizator sve dok
se ne doe do kraja ulaznog fajla. Na standardni izlaz (tj. u Java
konzoli) ispisuju se svi izdvojeni tokeni kao i kod akcije koja je tom
prilikom izvrena.
Delovi Java koda koji se ugrauju u razliite delove generisane klase se deniu
na sledei nain.
%{
<code>
%}
%init{
<code>
%init}
%eofval{
<code>
%eofval}
10.3. JFLEX 203
10.3.4 Pravila
I pravila u JFlex specikaciji se deniu na isti nain kao i u Lex-u. Jedina
razlika u tome je to akcija mora da bude navedena kao blok naredbi (izmeu
zagrada {} i kada ona sadri samo jednu Java naredbu).
// sym.java
public class sym
{
public static int EOF; // kraj ulaznog teksta
public static int END; // kljuna re end
public static int READ; // kljuna re read
public static int WRITE; // kljuna re write
public static int PLUS; // operator +
public static int MUL; // operator *
public static int ASSIGN; // separator =
public static int LPAR; // separator (
public static int RPAR; // separator )
public static int NEWLINE; // separator '\n'
public static int ID; // identifikator
public static int CONST; // konstanta
}
Drugi kroak. Kreiramo klasu ije e objekte vraati funkcija za leksiku ana-
lizu. Ova klasa obino sadri:
izdvojenu re,
Primer 10.18 Primer Java klase koja predstavlja rezultat leksikog analizatora
// Yytoken.java
10.3. JFLEX 205
class Yytoken {
public int _token;
public String _text;
public int _line;
public int _charBegin;
public int _charEnd;
public Object _value;
// import section
package compiler;
%%
// declaration section
%class MyScanner
%function scan
%line
%column
%debug
206GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA
%eofval{
return cretetoken(sym.EOF, null);
%eofval}
//definicije makroa
cifra = [0-9]
Slovo = [a-zA-Z]
%%
// pravila
// kljucne reci
"end" { return createToken(sym.END, null); }
"read" { return createToken(sym.READ, null); }
"write" { return createToken(sym.WRITE, null); }
// simbolika imena
{slovo}|_({slovo}|{cifra}|_)*
{
return createToken(sym.ID, yytext());
}
// konstante
{cifra}+(\.{cifra}*)?([Ee][+-]?{cifra}+)?
{
return createToken(sym.CONST, new Float(yytext()));
}
// operatori
\+ { return createToken(sym.PLUS, null); }
\* { return createToken(sym.MUL, null); }
10.4. CUP GENERATOR SINTAKSNIH ANALIZATORA 207
// separatori
= { return createToken(sym.ASSIGN, null); }
\( { return createToken(sym.LPAR, null); }
/) { return createToken(sym.RPAR, null); }
\n { return createToken(sym.NEWLINE, null) };
Privatnu klasa CUP$action koja sadri denicije akcija (akcije koje korisnik
denie u Cup specikaciji). Najbitinija funkcija ove klase je CUP$do_action().
Na osnovu strukture koda koji Cup generie, moe se zakljuiti da leksiki ana-
lizator koji se koristi u sintaksnom analizatoru genrisanom pomou Cup-a treba
da zadovolji sledee uslove:
%implements java_cup.runtime.Scanner
%function next_token
%type java_cup.runtime.Symbol
%eofval {
return new java_cup.runtime.Symbol(<CUPSYM>.EOF);
%eofval }
10.4. CUP GENERATOR SINTAKSNIH ANALIZATORA 209
Umesto svih ovih direktiva, dovoljno je navesti direktivu %cup koja kae da
generisani kod treba da bude kompatibilan sa kodom koji generie Cup.
import sekcija,
korisniki kod,
opis gramatike.
Import sekcija
Korisniki kod sadri delove java koda koji se ugrauju u razliite take generi-
sanih klasa.
Asocijativnost operatora
Prioritet operatora
Opis gramatike
Vie smena koje na levoj strani imaju isti neterminalni simbol se mogu skraeno
navoditi na isti nain kao u Yacc specikaciji.
tikih izraza
Pretpostavimo da su aritmetiki izrarzi denisani gramatikom navednom
u primeru 10.20.
10.5 Pitanja
1. ta je Lex/JFlex?
6. ta je Yacc/Cup?
11. Objasniti deo koda sintaksnog analizatora koji se generie na osnovu Cup
specikacije.
10.6 Zadaci
1. Napisati Lex/Jex specikaciju za analizator iz zadatka 2 u poglavlju 4.
q20
\t | \n | \b (
=
:
q21 q0 q1 * q2 * q3
start
(
ostalo
ostalo ostalo *
q19 . q4
slov
o
slovo
, ostalo
q18 q5 q6
cifra
; ostalo
q17 q7 q8
cifra
cifra | slovo
*
q16
q9 ostalo q10
+
q15
cifra
) bilo
q14 ta
' '
q11 q12 q13
Atributne gramatike
Opis naredbi jezika preko beskonteksnih gramatika obino nije dovoljan za uspe-
no prevoenje jezika. Postoji mnogo problema koji se ne mogu predstaviti for-
malnim opisom jezika. Zbog toga se kod praktinih reenja pravilima kojima
se denie jezik pridruuje skup dodatnih informacija tako to se simbolima
gramatike dodaju odreeni atributi . Vrednosti ovih atributa se izraunavaju
preko semantikih rutina koje se pridruuju pravilima gramatike. Koriste se dva
naina da se semantike rutine pridrue pravilima gramatike:
217
218 GLAVA 11. ATRIBUTNE GRAMATIKE
Za pravila oblika
X Y1 Y2 . . . Yn
semantike rutine su oblika
Y1 Y2 Yn Y1 .a Y2 .a Yn .a
U tabeli 11.1 dat je skup pravila gramatike kojom se denie jednostavan kal-
kulator koji izvrava sabiranje i mnoenje cifara.
L E# print(E.val)
E E+T E.val := E.val + T.val
ET E.val := T.val
T T F T.val := T.val F.val
T F T.val := F.val
F (E) F.val := E.val
F digit F.val := top. get(digit.lexval)
E1 .val = 35 #
T1 .val = 35
T2 .val = 5 F2 .val = 7
F1 .val = 5
dig.lexval = 5
( E2 .val = 7 )
E2 .val = 7
E3 .val = 3 + T3 .val = 4
T4 .val = 3 F3 .val = 4
F4 .val = 3 dig.lexval = 4
dig.lexval = 3
F1 F1 .val = digit.lexval 5
T2 T2 .val := F1 .val 5
F3 F3 .val = digit.lexval 3
T4 T4 .val := F3 .val 3
E3 E3 .val := T4 .val 3
F4 F4 .val = digit.lexval 4
T3 T3 .val := F4 .val 3
E2 E2 .val := T4 .val + T3 .val 3+4=7
F2 F2 .val := E2 .val 7
T1 T1 .val := T2 .val F2 .val 5 7 = 35
E1 E1 .val := T1 .val 35
L print(E1 .val) 35
X X.a
Y1 Y2 Yk Yn Y1 .a Y2 .a Yk .a Yn .a
DT L L.in := T.type
T int T.type := integer
T real t.type := real
L L1 , id L1 .in := L.in i addtype(id.entry, L.in)
L id addtype(id.entry, L.in)
real
L.in = real , id3
id1
Slika 11.4: Oznaeno stablo za deniciju tipa uz primer 11.2
var x;
var z;
x := ...;
z := ...;
P DS S.dl = D.dl
D1 var V D2 D1 .dl = addlist(V.name, D2 .dl)
D1 D1 .dl = NULL
S1 V := E ; S2 check(V.name, S1 .dl), S2 .dl = S1 dl
S1 /
V x V.name = x
V y V.name = y
V z V.name = z
D1 S1
var V1 ; D2 V3 := E1 ; S2
x var V2 ; D3 x V4 := E2 ; S3
z x
D D; D | id : T
T char | integer | array[num] of T | T
E literal | num | id | E mod E | E[E] | E
U tabeli 11.7 data su semantika pravila kojima se generiu atributi tipa za iden-
tikatore i pomou funkcije addType(id.entry, T.type) upisuju u tabelu simbola
226 GLAVA 11. ATRIBUTNE GRAMATIKE
V1 V1 .name = x generisani
V2 V2 .name = z generisani
V3 V3 .name = x generisani
V4 V4 .name = z generisani
P D; E
D D; D
D id : T addType(id.entry, T.type)
T char T.type := char
T integer T.type := integer
T T1 T.type := pointer(T1 .type)
T array[num] of T1 T.type := array(1 . . . num.val, T1 .type)
E id E.type := lookup(id.entry)
(
integer, E1 .type = integer E2 .type = integer
E E1 mod E2 E.type =
type error, inae
(
t, E2 .type = integer E1 .type = array(s, t)
E E1 [E2 ] E.type =
type error, inae
(
t, E1 .type = pointer(t)
E E1 E.type =
type error, inae
(
Pozivi funkcija t, E2 .type = s E1 .type = s t
E.type =
11.4. PROVERA TIPOVA PODATAKA (TYPE CHECKING)
Pravilo
Semantiko pravilo
gramatike
(
void, id.type = E.type
S id := E S.type =
type error, inae
(
S1 .type, E.type = boolean
S if E then S1 S.type =
type error, inae
(
S1 .type, E.type = boolean
S while E do S1 S.type =
type error, inae
(
void, S1 .type = void S2 .type = void
S S1 ; S2 S.type =
type error, inae
Pravilo
Semantiko pravilo
gramatike
E id E.type := lookup(id.entry)
integer, E1 .type = integer E2 .type = integer
real, E 1 .type = integer E2 .type = real
E E1 op E2 E.type = real, E1 .type = real E2 .type = integer
real, E1 .type = real E2 .type = real
type error, inae
11.5 Pitanja
1. Objasniti ulogu atributa i semantikih rutina atributnih gramatika.
11.6. ZADACI 229
11.6 Zadaci
1. Pokazati kako se izraunava izraz (5 + 3 + 4) (2 + 5) korienjem grama-
tike i semantikih pravila datih u tabeli 11.1. Izraunavanje predstaviti
obeleenim sintaksnim stablom.
D=0 D.val = 0
Meukodovi
231
232 GLAVA 12. MEUKODOVI
Izraz
P.nptr := mkleaf(id, id.entry)
predstavlja poziv funkcije kojom se generie list stabla (terminalni vor) za
identikator ija se prava vrednost preiuzima iz tabele simbola preko pokazivaa
id.entry, a P.nptr je pokaziva na taj vor.
p1 = mkleaf(d, d.entry)
p2 = mkleaf(c, c.entry)
p3 = mknode(0 +0 , p1 , p2 )
p4 = mkleaf(b, b.entry)
p5 = mknode(0 0 , p3 , p4 )
p6 = mkleaf(d, d.entry)
p7 = mkleaf(c, c.entry)
p8 = mknode(0 +0 , p6 , p7 )
p9 = mkleaf(b, b.entry)
p10 = mknode(0 0 , p8 , p9 )
p11 = mknode(0 +0 , p5 , p10 )
p12 = mknode(0 :=0 , mkleaf (a, a.entry), p11 )
id := E
E + E
E E E E
id ( E ) id ( E )
E + E E + E
id id id id
Slika 12.3: Sintaksno stablo stablo za primer 12.1. Odgovarajue apstraktno sintaksno
stablo je dato na slici 12.4.
12.3. IMPLEMENTACIJA APSTRAKTNOG SINTAKSNOG STABLA 235
:=
id a +
id b + id b +
id d id c id d id c
Slika 12.4: Apstraktno sintaksno stablo za primer 12.1. Odgovarajue sintaksno stablo je
dato na slici 12.3.
:=
id a +
id b +
id d id c
t1 = y z
t2 = t1 + x
0 id d
1 id c
2 + 0 1
3 id b
4 2 3
5 id d
6 id c
7 + 5 6
8 id b
9 7 8
10 id a
11 := 10 9
potprograma, na primer:
param x1
param x2
.
.
.
param xn
call p, n
a := b * (d + c) + b * (d + c),
bie generisan sledei troadresni meukod.
t1 := d + c
t2 := b t1
t3 := d + c
t4 := b t1
t5 := t2 + t4
a := t5
a := b (d + c) + b (d + c)
0 + t1 d c
1 t2 b t1
2 + t3 d c
3 t4 b t3
4 + t5 t2 t4
5 = a t5
240 GLAVA 12. MEUKODOVI
a := b (d + c) + b (d + c)
op arg1 arg2
0 + d c
1 b 0
2 + d c
3 b 2
4 + 1 3
5 = a 4
a := b (a + c) + b (a + c)
35 ( 0) 0 + d c
36 ( 1) 1 b 0
37 ( 2) 2 + d c
38 ( 3) 3 b 2
39 ( 4) 4 + 1 3
40 ( 5) 5 = a 4
a := b (a + c) + b (a + c)
b = c[i] + a[i][j],
id := E.addr = t5
t5 := t2 + t4
E.addr = t2 + E.addr = t4
t2 := b * t1 t4 := b * t3
id id
( E.addr = t1 ) ( E.addr = t3 )
t1 := d + c t3 := d + c
id id id id
12.5. TROADRESNI MEUKOD ZA NAREDBE DODELJIVANJA
Slika 12.6: Oznaeno sintaksno stablo za generisanje troadresnog meukoda izraza iz primera 12.6
243
244 GLAVA 12. MEUKODOVI
b = c[i] + a[i][j]
t1 := i 4
t2 := c[t1 ]
t3 := i 12
t4 := j t4
t5 := t1 + t2
t6 := a[t5 ]
t7 := t2 + t6
b := t7
id := E
E + E
L L
id [ E ]
L [ E ]
c id
id [ E ] id
i
a id j
b := t7
id := E.addr = t7
t7 := t2 + t6
b
E.addr = t2 + E.addr = t4
t2 := c[11] t6 := a[t5]
L.array = c L.array = a
L.type = c[i].type L.type = a[i][j].type
L.addr = t1 t = t4
t1 := i * 4 L.addr = t5
t4 := j * 4
id [ E.addr = i ] t5 := t3 + t4
c id
i L.array = a [ E.addr = j ]
L.type = a[i].type
id
L.addr = t1
t3 := i * 12 j
id [ E.addr = i ]
a id
if ( B ) S1
id5 := con3
B1 || B2
E1 < E2
B3 && B4
id1 con1
E3 > E4 E5 6= E6
Slika 12.9: Sintaksno stablo za naredbu if (x < 100 || x > 200 && x != y) x := 0; iz
primera 12.8
12.6. TROADRESNI MEUKOD UPRAVLJAKIH NAREDBI 251
Tabela 12.11: Generisanje troadresnog koda za naredbu if (x < 100 || x > 200 && x !=
y) x := 0; iz primera 12.8
E1 E1 .addr = x
E2 E2 .addr = 100
B1 B1 .code = if x < 100 goto B1 .code goto B1 .false
E3 E3 .addr = x
E4 E4 .addr = 200
B3 B3 .code = if x > 200 goto B3 .code goto B3 .false
E5 E5 .addr = x
E6 E5 .addr = y
B4 B4 .code = if x 6= y goto B4 .code goto B4 .false
B3 .true = Lab1
B3 .false = B2 .false
B4 .true = B2 .true
B2 B4 .false = B2 .false
B2 .code = if x > 200 goto Lab1 goto B2 .false
Lab1: if x 6= y goto B2 .true goto B2 .false
B1 .true = B.true
B1 .false = Lab2
B2 .true = B.true
B B2 .false = B.false
B.code = if x < 100 goto B.true goto Lab2
Lab2: if x > 200 goto Lab1 goto B.false
Lab1: if x 6= y goto B.true goto gotoB.false
S1 S1 .code = x := 0
B.true = Lab3
B.false = S1 .next = S.next
S.code = if x < 100 goto Lab3 goto Lab2
S Lab2: if x < 100 goto Lab1 goto S.next
Lab1: if x 6= y goto Lab3 goto .next
Lab3:
x := 0
S.next = Lab4
P.code = ifx < 100 goto Lab3 goto Lab2
Lab2: if x < 100 goto Lab1 goto Lab4
P
Lab1: if x 6= y goto Lab3 goto Lab4
Lab3: x := 0
Lab4:
252 GLAVA 12. MEUKODOVI
t1 := (x = 0)
t2 := not t1
if t2 then goto L1
u := 0
goto L2
L1 : t3 := x 1
param t3
t4 = fcall fact, 1
u := t4 x
L2 : fret u
12.7 Pitanja
1. Objasniti mesto i namenu meukoda u strukturi kompilatora.
6. ta je to troadresni meukod?
14. Dati primer semantikih pravila kojima se generie troadresni kod osnov-
nih upravljakih struktura.
12.8 Zadaci
1. Generisati apstraktno sintaksno stablo za sledee aritmetike izraze.
a+bc+ad
b + c (a) + d + c (a)
sum := 0
while (num != 0)
sum := sum + a[num]
num := num - 1;
12. Korienjem semantikih pravila iz tabela 12.9 i 12.10 i generisati oznaeno
sintaksno stablo za sekvencu naredbi iz prethodnog zadatka.
Optimizacija koda
Strategija generisanja koda naredba za naredbom esto daje ciljni kod programa
koji sadri redundatne naredbe i neoptimalne konstrukcije. Zbog toga se nakon
generisanja prve verzije koda uvek vri optimizacija iji je cilj da se smanji broj
naredbi i memorijski prostor koji generisani kod zahteva.
Ova optimizacija se obino izvodi tako to vie puta prolazi kroz kod i nastoji
da se primene jednostavne transformacije kojima se optimizuje kod. Pri tome
se transformacije vre lokalno nad grupom od svega nekoliko naredbi. Naime
kroz kod se prolazi tako to se u jednom trenutku posmatra samo mali deo koda
i nastoji da se izmeni tako da se smanji broj naredbi, sloenije naredbe zamene
jednostavnijim ili utie na memorijski prostor koji kod zahteva.
255
256 GLAVA 13. OPTIMIZACIJA KODA
Zbog same tehnike kojom se izvodi ova transformacija, kod se posmatra kroz
uski prozor, procep (peephole ), ova optimizacija se u literaturi sree pod imenom
peephole optimizacija.
algebarska uproenja i
Najpoznatiji takav primer su parovi naredbi STORE i LOAD, koji se pojavljuju zato
to se jedan korak algoritma za generisanje koda zavrava naredbom STORE, a
naredni korak zapoinje naredbom LOAD. Pogledajmo sledei primer.
STORE T1, R1
LOAD T1, R1
Oigledno je da je ovaj par naredbi bezefektan. Naime, prvo se jedna vrednost
iz registra R1 prebacuje u memorijsku lokaciju T1 , a zatim se ista ta vrednost
vraa iz memorijske lokacije u registar R1 registar procesora.
GOTO L1
L1: GOTO L2
moemo zameniti naredbom
GOTO L2
L1: GOTO L2
U ovom sluaju je broj naredbi ostao isti, ali je nova sekvenca naredbi ekasnija
zato to se umesto para naredbi GOTO L1 i GOTO L2, izvrava samo naredba
GOTO L2, dok je naredba sa labelom L1 ostala samo zbog mogunosti da postoji
skok na ovu naredbu iz nekog drugog dela programa.
Sekvenca naredbi
IF a < b GOTO L1
L1: GOTO L2
se moe zameniti sledeom sekvencom:
IF a < b GOTO L2
L1: GOTO L2
Objanjenje je isto kao u prethodnom sluaju, samo to se prvi skok izvrava
uslovno kada je vrednost izraza a<b jednaka true.
GOTO L1
;...
L1: IF a < b GOTO L2
L3:
258 GLAVA 13. OPTIMIZACIJA KODA
;...
L2:
Navedena sekvenca se moe zameniti sledeom:
IF a < b GOTO L2
GOTO L3
L3:
L2:
Broj naredbi je ostao isti, ali je drugi sluaj optimalniji. Dok se u prvom sluaju
uvek izvrava GOTO i IF, u drugom se uvek izvrava IF, a GOTO L3 samo u sluaju
kada uslov a < b nije ispunjen.
# define debug 0
if (debug) { /* tampanje poruke o greki */ }
Meukod ove naredbe je:
IF debug = 1 GOTO L1
GOTO L2
L1: print ;...
L2:
Posle eliminisanja GOTO na GOTO, ova sekvenca dobija oblik:
IF debug /= 1 GOTO L2
print ;...
L2:
Meutim, kako je debug = 0, ubacivanjem konstanti u program, to je jedna
od faza grerisanja koda, dobija se:
IF 0 /= 1 GOTO L2
print ;...
L2:
Kako je uslov IF naredbe uvek ispunjen, uslovna naredba moe biti zamenjena
bezuslovnom naredbom GOTO L2, pa se i sekvenca naredbi za tampanje poruke
u ovom sluaju moe potpuno eliminisati jer e biti nedosegljiva.
13.1. OSNOVNA OPTIMIZACIJA KODA (PEEPHOLE OPTIMIZACIJA)259
X = X + 0
X = X * 1
Iz istog razloga mogue je uprostiti naredbe
X = Y + 0
X = Y * 1
i zameniti ih jednostavnijim:
X = Y
X = Y
samoindeksiranja,
samoinkrementiranja,
specinih adresiranja,
korienje steka.
260 GLAVA 13. OPTIMIZACIJA KODA
(1) i := m 1
(2) j := n
13.2. DODATNA OPTIMIZACIJA 261
(3) t1 := 4 n
(4) v := a[t1 ]
(5) i := i + 1
(6) t2 := 4 i
(7) t3 := a[t2 ]
(8) if t3 < v goto (5)
(9) j := j 1
(10) t4 := 4 j
(11) t5 := a[t4 ]
(12) if t5 > v goto (9)
(13) if i j goto (23)
(14) t6 := 4 i
(15) x := a[t6 ]
(16) t7 := 4 i
(17) t8 := 4 j
(18) t9 := a[t8 ]
(19) a[t7 ] := t9
(20) t10 := 4 j
(21) a[t10 ] := x
(22) goto (5)
(23) t11 := 4 i
(24) x := a[t11 ]
(25) t12 := 4 i
(26) t13 := 4 n
(27) t14 := a[t13 ]
(28) a[t12 ] := t14
(29) t15 := 4 n
(30) a[t15 ] := x
(1) i := m 1
(2) j := n
(3) t1 := 4 n
(4) v := a[t1 ]
(5) i := i + 1
(6) t2 := 4 i
(7) t3 := a[t2 ]
(8) if t3 < v goto B2
(9) j := j 1
(10) t4 := 4 j
(11) t5 := a[t4 ]
(12) if t5 > v goto B3
(13) if i j goto B6
Neki izraz se naziva zajednikim ako je pre toga ve bio izraunat. Na primer,
u bloku B5 generisana je promenljiva t6 kojoj je dodeljena vrednost t6 := 4 i.
Neto nie u kodu se ista vrednost pamti i kao t7 . Isto vai i za izraze kojima
se dodeljuju vrednosti promenljivima t8 i t10 . Na svim mestima gde se koristi
t7 moe da stoji t6 , a umesto t10 moe da stoji t8 .
t6 := 4 i
x := a[t6 ]
t8 := 4 j
t9 := a[t8 ]
a[t6 ] := t9
a[t8 ] := x
goto B2
t11 := 4 i
x := a[t11 ]
t13 := 4 n
t14 := a[t13 ]
a[t11 ] := t14
a[t13 ] := x
x := t3 x := t3
a[t2 ] := t5 t14 := a[t1 ]
a[t4 ] := x a[t2 ] := t14
goto B2 a[t1 ] := x
x := t3
a[t2 ] := t5
a[t4 ] := t3
goto B2
x := t3
t14 := a[t1 ]
a[t2 ] := t14
a[t1 ] := t3
direktna redukcija.
266 GLAVA 13. OPTIMIZACIJA KODA
t := limit - 2;
while (i <= t)
t4 := 4 j
t4 := t4 4
t5 := a[t4 ]
if t5 > v goto B3
t2 := 4 i
t2 := t2 + 4
t3 := a[t2 ]
if t3 < v goto B2
Direktna redukcija
13.3 Pitanja
1. Objasniti razloge zbog kojih se vri osnovna optimizacija koda.
(10 ) i := m 1
(20 ) j := n
(30 ) t1 := 4 n
(40 ) v := a[t1 ]
(50 ) t2 := 4 i
(60 ) t4 := 4 j
(70 ) t2 := t2 + 4
(80 ) t3 := a[t2 ]
(90 ) if t3 < v goto B2
(100 ) t4 := t4 4
(110 ) t5 := a[t4 ]
(120 ) if t5 > v goto B3
(130 ) if i j goto B6
Generisanje koda
Osnovni zadatak generatora koda je da generie ispravan kod pri emu je bitno
da taj kod bude i to je mogue ekasniji.
tabela
simbola
Generator koda moe da bude realizovan tako da generie direktno mainski kod
sa apsolutnim adresama, mainski kod sa relativnim adresama ili asemblerski
kod koji zatim prolazi kroz proces asembliranja.
271
272 GLAVA 14. GENERISANJE KODA
Ovaj procesor sadri etiri esnaestobitna regisra opte namene: AX, BX, CX
i DX, pri emu se moe pristupati posebno njihovim bajtovima niih teina
(AL, BL, CL i DL) i viih teina (AH, BH, CH i DH). Uobiajeno je, mada ne
obavezno, da se ovi registri koriste na sledei nain:
AX kao akumulator,
CS (code segment ),
DS (data segment ),
SS (stack segment ) i
ES (extra segment ).
Instrukcija Znaenje
Instrukcija Znaenje
Instrukcija Znaenje
Instrukcija Znaenje
Polja src, dst i adr u navedenim naredbama ponekad sadre stvarni podatak
sa kojim e se denisana operacija izvoditi, ali ee adresu podatka gde se
on nalazi. S obzirom da se podatak moe nalaziti u nekom od registara ili u
razliitim zonama operativne memorije, svaki procesor podrava isvestan skup
naina adresiranja podataka. Skup naina adresiranja procesora 8086 koji e se
koristiti pri generisanju koda u ovom poglavlju dat je u tabeli 14.5.
U ovom jeziku postoji i ogranienje da kod instrukcija koje imaju dva operanda
bar jedan od njih mora da bude u nekom od registara procesora.
14.1. ODREDINA MAINA PROCESOR INTEL 8086 275
Nain
Format Primer Znaenje
adresiranja
Kod dinamikih jezika se u toku samog izvrenja programa mogu dodavati novi
delovi koda, rezervisati prostor za nove podatke i izbacivati iz memorije podaci
koji se vie ne koriste. Ovoj grupi pripadaju uglavnom skript jezici kao to su:
PHP, Perl, Prolog, Pyton, Ruby, JavaScript ali i jezci opte namene poput Jave
i C#-a (kod kojih se dodavanje novih delova koda vri korienjem reeksije).
Kod ovih programskih jezika se koristi takozvana dinamika alokacija memorije.
procesorski
stek
dinamiki
podaci
statiki podaci
kod programa
aju aktivacioni slog ima strukturu prikazanu na slici 14.3. Meutim, struktura
aktivacionog sloga nije ista kod svih jezika niti kod svih kompilatora za jedan
jezik. Ona se obino prilagoava potrebama kompilatora.
rezultat programa
stvarni parametri
link prema aktivacionom
slogu pozivajueg modula
link prema podacima
pozivajueg modula
stanje procesora
u trenutku poziva
lokalni podaci
privremeni podaci
Primer 14.1
PROGRAM CONSUME
CHARACTER * 50 BAF
INTEGER NEXT
CHARACTER C, PRODUCE
DATA NEXT /1/, BUF /' '/
6 C = PRODUCE ( )
BUF(NEXT:NEXT) = C
NEXT = NEXT + 1
IF (C .NE. ' ') GOTO 6
WRITE (*, '(A)') BUF
END
Primer 14.2
quiksort(1,9);
}
Uoimo da se u datoj proceduri poziva potprogram partition kao i sam
potprogram quicksort rekurzivno i to dvostrukom rekurzijom. U glav-
nom programu pre poziva potprograma quicksort poziva se i potprogram
readaray. Redosled poziva potprograma najbolje se moe prikazati akti-
vacionim stablom koje je za dati primer prikazano na slici 14.5.
Svaki vor u aktivacionom stablu sa slike 14.5 predstavlja jedan poziv potpro-
grama. Pozivi potprograma koji se izvre iz jedne instance potprograma pred-
stavljeni su vorovima do kojih vode potezi iz vora koji odgovara toj instanci.
Pri tome redosled poziva odgovara redosledu vorova posmatrano sleva udesno.
program
readarray quicksort(1,9)
partition(1,9) quicksort(1,3) quicksort(5,9)
partition(1,3) quicksort(1,0) quicksort(2,3) partition(5,9) quicksort(5,5) quicksort(7,9)
partition(1,3) quicksort(1,0) quicksort(2,3) partition(7,9) quicksort(7,7) quicksort(9,9)
Slika 14.5: Aktivaciono stablo za program iz primera 14.2
282
14.5. DINAMIKA ALOKACIJA MEMORIJE 283
program
program
readarray
readarray
program
program
quicksort(1, 9)
readarray quicksort(1, 9)
program
program
quicksort(1, 9)
readarray quicksort(1, 9)
partition(1, 9)
partition(1, 9)
program
program
quicksort(1, 9)
readarray quicksort(1, 9)
quicksort(1, 3)
partition(1, 9) quicksort(1, 3)
Slika 14.6: Dinamika ubacivanja aktivacionih slogova u stek za program iz primera 14.2
284 GLAVA 14. GENERISANJE KODA
program
program
readarray
readarray quicksort(1, 9)
quicksort(1, 9)
Slika 14.7: Dinamika ubacivanja aktivacionih slogova u heap za program iz primera 14.2
Dakle, stara vrednost baznog pokazivaa mora biti, takoe, zapamena u steku
i lokacija gde se ona uva se naziva kontrolnom vezom. Upravo je i to lokacija
na koju ukazuje bazni pokaziva za sve vreme izvrenja potprograma. U skladu
sa tim, struktura aktivacionog sloga koja e se koristiti u ovom poglavlju je
prikazana na slici 14.8.
rezultat programa
stvarni parametri
adresa povratka
staro BP
(kontrolna veza) BP
prethodni sadraj
radnih registara
lokalne promenljive
privremene promenljive SP
SUB SP, 2
Inae, kod ovog asemblerskog jezika je uobiajeno da se rezultati celobroj-
nog tipa ili tipa pokazivaa (koji su veliine jedne memorijske rei) vraaju
kroz registar CX.
2. Smetanje u stek stvarnih parametara potprograma. Nepisano
je pravilo da se parametri u stek upisuju u obrnutom redosledu od onog
kojim su oni navedeni u pozivu potprograma. Jedino o emu treba voditi
rauna je da se naredbom PUSH u stek smeta jedna memorijska re. To
znai da ako je vrednost parametra zapamena u vie memorijskih rei,
potrebno je generisati vie PUSH naredbi za njegov upis u stek.
PUSH BP
2. Denisanje nove vrednosti baznog pokazivaa. Poto bazni poka-
ziva treba da ukazuje na lokaciju gde je zapamena njegova prethodna
vrednost, a nakon izvrenja prethodno generisane instrukcije ona e biti
na vrhu steka, baznom pokazivau treba dodeliti trenutnu vrednost poka-
zivaa steka, odnosn generisati instrukciju:
286 GLAVA 14. GENERISANJE KODA
MOV BP,SP
3. Smetanje u stek stanja procesora. Ovaj korak nije obavezan, ali
ukoliko se ne generie skup instrukcija za pamenje stanja procesora, u
pozivajuem modulu se nakon poziva potprograma ne smeju koristiti vred-
nosti zapamene u registrima pre poziva. Zato je preporuivo da se ove
instrukcije generiu.
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
4. Rezervacija prostora za lokalne promenljive. U fazi prevoenja je
poznata veliina memorijskog prostora potrebna za smetanje lokalnih pro-
menljivih denisanih na poetku potprograma, pa se rezervacija prostora
vri jednostavnim umanjenjem vrednosti pokazivaa steka za tu vrednost,
odnosno za rezervisanje prostora za lokalne promenljive treba generisati
naredbu:
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
4. Preuzimanje iz steka stare vrednosti baznog pokazivaa. Za ovu
akciju treba generisati naredbu:
POP BP
5. Izvrenje return naredbe. Return naredba automatski izbacuje iz ma-
gacina povratnu adresu i smeta je u broja naredbi IP. Dakle, dovoljno
je generisati samo naredbu:
RET
Pozivajui modul treba iz steka da izbaci stvarne parametre i rezultat pot-
programa, tj. deo sekvence povratka koja se generie u pozivajuem modulu
sadrae sledee akcije.
Primer 14.3
n
m
adresa povratka
staro BP BP
SP i
quicksort(1, 9);
U pozivajuem modulu, u taki poziva ove funkcije generisae se sledee
instrukcije.
; prelaz na potprogram
CALL QUICKSORT
; PROCEDURA QUICKSORT
; DEO SEKVENCE POZIVA
; smetanje u stek stare vrednosti baznog pokazivaa
PUSH BP
; definisanje nove vrednosti baznog pokazivaa
MOV BP, SP
; rezervacija prostora za celobrojnu lokalnu promenljivu i
SUB SP, 2
; TELO METODE
;...
Primer 14.4
register int i;
static int j;
int a;
static int *b;
i = j;
a = *b;
Zadatak kompilatora je da rezervie prostor za promenljive denisane u
ovoj funkciji, a zatim i da prevede navedene naredbe dodele.
2. Ako prva solucija nije mogua, za L uzimamo prazan registar, ako takav
postoji.
3. Ako ni druga solucija nije mogua i ako se x koristi dalje u istom bloku,
ili je op operator koji zahteva upotrebu registara, onda biramo neki od
zauzetih registara R. Vrednost koja je trenutno zapisana u registru preba-
cujemo u memoriju (generiemo naredbu MOV M, R) ako ta vrednost ve
nije zapamena u memoriji, korigujemo deskriptor adrese za M i vraamo
R kao L. Ako je u registru R zapisana vrednost veeg broja promenlji-
vih (to moe da bude posledica naredbi za kopiranje) treba generisati
odgovarajuu MOV naredbu za svaku od tih promenljivih.
Primer 14.5
d = (a - b) + (a - c) + (a - c)
na osnovu koje je generisan sledei meukod:
t1 := a b
t2 := a c
t3 := t1 + t2
d := t3 + t2
MOV AX, a t1 u AX
t1 := a b AX sadri t1
SUB AX, b' a, b i c u memoriji
t1 u AX
MOV BX, a AX sadri t1
t2 := a c a, b i c u memoriji
SUB BX, c BX sadri t2
t2 u BX
t2 u BX
AX sadri t3
t3 := t1 + t2 ADD AX, BX a, b i c u memoriji
BX sadri t2
t3 u AX
d u AX
ADD AX, BX AX sadri d
d := t3 t2 a, b i c u memoriji
Indeks i je na steku
Naredba Indeks i Indeks i je u
sa pomerajem di
meukoda je u registru memoriji Mi
u odnosu na BP
MOV SI, Mi MOV SI, [BP + di]
MOV AX, b[SI]
a := b[i] MOV AX, b[SI] MOV AX, b[SI]
MOV a, AX
MOV a, AX MOV a, AX
MOV AX, b MOV AX, b
MOV AX, b
a[i] := b MOV DI, Mi MOV DI, [BP + di]
MOV a[DI], AX
MOV a[DI], AX MOV a[DI], AX
Pokaziva p je na
Naredba Pokaziva p je Pokaziva p je
steku sa pomerajem
meukoda u registru BX u memoriji Mp
dp u odnosu na BP
MOV BX, Mp MOV BX, [BP + dp]
MOV AX, [BX]
a := p MOV AX, [BX] MOV AX, [BX]
MOV a, AX
MOV a, AX MOV a, AX
MOV BX, Mp MOV BX, [BP + dp]
MOV AX, a
p := a MOV AX, a MOV AX, a
MOV [BX], AX
MOV [BX], AX MOV [BX], AX
Drugi nain se primenjuje kod asemblerskih jezika koji koriste statusni registar
(kakav je i jezik za procesor 8086) registar koji sadri skup bitova kojima
se registruje kakva je rezultujua vrednost poslednje izvrene operacije bilo da
je to bila aritmetika operacija ili operacija prenosa vrednosti iz memorije u
registar ili obrnuto. Ovi jezici obino sadre naredbe skoka koje se vezuju za te
bitove i omoguavaju prenos upravljanja na neku naredbu ako je neki od uslova
ispunjen. U ovom sluaju, naredba meukoda oblika if x < y goto z e biti
preslikana u sledeu sekvencu naredbi:
Primer 14.6
Denisati 8086 kod i izgled aktivacionog sloga funkcije nd koja proverava
da li zadati podatak postoji u lananoj liti. Zadatak reiti uz pretpostavku
da se rezultat funkcije smeta u registar CX i uz pretpostavku da se rezultat
funkcije prenosi kroz listu parametara.
struct list
{
int info;
struct list* next;
};
int find(struct list* l, int x)
{
int res;
if ( l == 0 )
res = 0;
else if ( l->info == x )
res = 1;
else
res = find(l->next, x);
return res;
}
Aktivacioni slog funkcije nd u sluaju kad se rezultat upisuje u registar
CX prikazan je na sledeoj slici.
x
l
adresa povratka
staro BP BP
SP RES
; upis BP na stek:
PUSH BP
; telo funkcije:
MOV AX, [BP + 4]
CMP AX, 0
JNE lab1
MOV [BP - 2], 0
JMP lab2
lab1: MOV BX, [BP + 4]
MOV AX, [BX]
CMP AX, [BP + 6]
JNE lab3
MOV [BP - 2], 1
JMP lab2
; poziv funkcije:
CALL find
rezultat
x
l
adresa povratka
staro BP BP
SP RES
POP AX
MOV [BP - 2], AX
3. Naredbu za smetanje rezultata zameniti naredbama:
14.7 Pitanja
1. ta su zadaci komponente za upravljanje memorijom.
6. Objasniti skup instrukcija koje treba generisati pri prevoenju poziva pot-
programa.
14.8 Zadaci
1. Denisati aktivacioni slog i odgovarajui 8086 kod za funkciju sum. Pret-
postaviti da se rezultat funkcije prenosi kroz registar CX.
struct node
{
int info;
struct node* next;
};
struct node
{
int info;
struct node* left;
struct node* right;
};
Realizacija kompilatora
299
300 GLAVA 15. REALIZACIJA KOMPILATORA
program kompilatora
kompilator za C kompilator za Javu
za Javu napisan na C-u
(EXE) (EXE)
(C kod)
S T
prevoenje (C, Pascal, Java i sl); drugi blok (T ) se odnosi na ciljni jezik, jezik
na koji se vri prevoenje (asemblerski jezik, mainski jezik i sl); dok se trei
blok (I ) odnosi na jezik u kom je predstavljen sam kompilator. Dok je kom-
pilator na nivou programa, taj trei blok e biti neki vii programski jezik (C,
Pascal, Java i sl), a kada se prevede i koristi za prevoenje drugih programa taj
blok e se odnositi na mainski jezik u koji je program preveden. Koristiemo
oznaku SIT za kompilator predstavljen dijagramom na slici 15.2.
FORTRAN IBM360
(program) (EXE)
IBM360
(EXE)
Java M Java M
(program) (EXE) (program) (EXE)
C C M M
(program) (program) (EXE) (EXE)
M
(EXE)
C N C N
(program) (EXE) (program) (EXE)
C C M M
(program) (program) (EXE) (EXE)
M
(EXE)
C N C N
(program) (EXE) (program) (EXE)
C C N N
(program) (program) (EXE) (EXE)
M
(EXE)
U praksi se tehnika butstrepovanja veoma esto koristi i u vie koraka pri emu
se reavaju razliiti problemi. U nastavku emo detaljnije razmotriti dva sluaja
kada je ova tehnika viestruko koriena u komercijalne svrhe.
C M C M
(program) (EXE-opt) (program) (EXE-opt)
C C M M
(program) (program) (EXE) (EXE)
M
(EXE)
C M C M
(program) (EXE-opt) (program) (EXE-opt)
C C M M
(program) (program) (EXE-opt) (EXE-opt)
M
(EXE)
6000
(EXE)
6000
(EXE)
6000
(EXE)
7094. Dobijen je kompilator F7094 360 koji moe na staroj maini IBM
7094 da generie programe za mainu IBM 360 (slika 15.10).
IBM7094
(EXE)
IBM7094
(EXE)
IBM7094
(EXE)
Slika 15.12: Objedinjene prve dve faze butstrepovanja sa slika 15.10 i 15.11
IBM360
(EXE)
na slici 15.15. Inae, ovaj kompilator je bio poznat po tome to su kod njega prvi
put primenjene neke tehnike optimizacije koje se danas smatraju standardnim.
IBM360
(EXE)
IBM7094
(EXE)
Slika 15.15: Sve faze butstrepovanja primenjenog kod generisanja kompilatora za FORTRAN
307
308 GLAVA 15. REALIZACIJA KOMPILATORA
izvorni kod
leksiki analizator
sekvenca tokena
LL analizator
type checker
meukod
generator koda
mainski kod
CPU
rezultati
Slika 15.16: P kompilator za Pascal
izvorni kod
postksna notacija
generator koda
asemblerski kod
post-optimizacija
asemblerski kod
15.3 Pitanja
1. ta su to T-dijagrami i u koje svrhe se koriste?
izvorni kod
leksiki analizator
operator-operand parovi
sintaksni analizator
meukod (quadruples )
optimizacija
modikovan meukod
generator koda
asemblerski kod
[1] Aho. A.V, Sethi, R., Ullman, J. D., Compilers, Principles, Techniques, and
Tool, Addison-Wesley, 1986.
[5] Cooper K., Torczon, L., Engineering a Compiler, Morgan kaufmann Publis-
her, 2004.
[6] Grune, D., Bal, H. E., Jacobs, C. J. H., Langendoen, K. G., Modern Com-
piler Design, John Wiley & Sons, 2000.
[8] Lee, G., Pen-Chung Yew. P. , Interaction Between Compilers and Computer
Architectures, Springer Science & Business Media, 2013.
[9] Morgan B., Building an Optimizing Compiler, Digital Press Elsevier Ser-
vices, 1998. ISBN 1-5558-179-X
[13] Safonov, V. O., Trustworthy Compilers, John Wiley & Sons, 2010.
311
312 BIBLIOGRAFIJA
Dodatak
313
314 GLAVA 16. DODATAK
multianew- c5 indexbyte1, count1, [co- Kreira se novo polje dimen-
array indexbyte2, unt2,...] zija denisanih sa dimensions
dimensions arrayref sa elementima polja tipa koji
je identikovan referencom na
klasu.
wide c4 opcode, in- [isto kao za odgo- Izvrava se opcode, gde je op-
dexbyte1, varajue instruk- code iload, oad, aload, lload,
indexbyte2 cije] dload, istore, fstore, astore,
iinc, in- lstore, dstore ili ret, ali se
dexbyte1, podrazumeva da je index is 16
indexbyte2, bitova;
countbyte1,
countbyte2
Unused
326
INDEKS 327