Programski Prevodioci

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 340

Sadraj

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

2 Elementi teorije formalnih jezika 15


2.1 Opis jezika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.2 Elementi jezika . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2.1 Azbuka . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2.2 Re . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2.3 Proizvod rei . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.4 Eksponent rei . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.5 Transponovana re . . . . . . . . . . . . . . . . . . . . . . 17
2.2.6 Delovi rei . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.3 Formalni jezik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.3.1 Operacije nad jezicima . . . . . . . . . . . . . . . . . . . . 19
2.4 Opis jezika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.4.1 Izvoenje rei . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.4.2 Elementi gramatike . . . . . . . . . . . . . . . . . . . . . . 23
2.4.3 Direkto izvoenje i redukcija . . . . . . . . . . . . . . . . 23
2.5 Formalne gramatike . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.6 Hierarhija gramatika po omskom . . . . . . . . . . . . . . . . . 27
2.6.1 Gramatike tipa jedan ili konteksne gramatike . . . . . . . 27
2.6.2 Gramatike tipa dva ili beskonteksne gramtike . . . . . . . 28
2.6.3 Gramatike tipa tri ili regularne gramatike . . . . . . . . . 29
2.6.4 Reenine forme . . . . . . . . . . . . . . . . . . . . . . . 30
2.6.5 Fraze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

i
ii SADRAJ

2.7 Normalne forme gramatika . . . . . . . . . . . . . . . . . . . . . 31


2.7.1 Normalne forme za konteksne gramatike . . . . . . . . . . 31
2.7.2 Normalne forme za beskonteksne gramatike . . . . . . . . 32
2.8 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.9 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

3 Automati kao ureaji za prepoznavanje jezika 35


3.1 Opti model automata . . . . . . . . . . . . . . . . . . . . . . . . 35
3.2 Tjuringova maina . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.3 Linearno ogranien automat . . . . . . . . . . . . . . . . . . . . . 38
3.4 Magacinski automat . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.5 Konani automati . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.5.1 Odreivanje jezika koji se prepoznaje datim konanim au-
tomatom . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.5.2 Veza izmeu konanih automata i gramatika tipa tri . . . 46
3.6 Regularni izrazi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.7 Preslikavanje regularnih izraza u konane automate . . . . . . . . 52
3.8 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.9 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

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

6 Prediktivna analiza  LL-1 analizatori 93


6.1 Proste LL-1 gramatike . . . . . . . . . . . . . . . . . . . . . . . . 94
6.1.1 Leva faktorizacija . . . . . . . . . . . . . . . . . . . . . . . 97
6.2 Pomone funkicije za denisanje optih LL-1 gramatika . . . . . 97
6.2.1 Funkcija First . . . . . . . . . . . . . . . . . . . . . . . . . 98
6.2.2 Funkcija Follow . . . . . . . . . . . . . . . . . . . . . . . . 99
SADRAJ iii

6.3 LL-1 gramatike bez -pravila . . . . . . . . . . . . . . . . . . . . 100


6.4 LL-1 gramatike sa -pravilima . . . . . . . . . . . . . . . . . . . . 103
6.5 Reeni zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
6.6 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
6.7 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

7 Analiza zasnovana na relacijama prvenstva 111


7.1 Relacije prvenstva . . . . . . . . . . . . . . . . . . . . . . . . . . 111
7.1.1 Relacija istog prioriteta . . . . . . . . . . . . . . . . . . . 111
7.1.2 Relacija nieg prioriteta . . . . . . . . . . . . . . . . . . . 112
7.1.3 Relacija vieg prioriteta . . . . . . . . . . . . . . . . . . . 112
7.2 Operatorska gramatika prvenstva . . . . . . . . . . . . . . . . . . 113
7.2.1 Postupak sintaksne analize . . . . . . . . . . . . . . . . . 119
7.2.2 Funkcije prvenstva . . . . . . . . . . . . . . . . . . . . . . 121
7.3 Opta pravila prioriteta . . . . . . . . . . . . . . . . . . . . . . . 122
7.4 Gramatike prvenstva . . . . . . . . . . . . . . . . . . . . . . . . . 124
7.4.1 Postupak sintaksne analize . . . . . . . . . . . . . . . . . 126
7.5 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
7.6 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

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

9 Tabele simbola 159


9.1 Predstavljanje simbola u tabeli simbola . . . . . . . . . . . . . . 160
9.2 Predstavljanje simbola korienjeme at pristupa . . . . . . . . . 160
9.3 Predstavljanje simbola korienjem objektno-orijentisanog pristupa163
9.4 Predstavljanje tabele simbola . . . . . . . . . . . . . . . . . . . . 163
9.5 Tabele simbola i oblast vaenja simbolikih imena . . . . . . . . . 167
9.6 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
9.7 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

10 Generatori leksikih i sintaksnih analizatora 175


iv SADRAJ

10.1 Lex  generator leksikih analizatora . . . . . . . . . . . . . . . . 175


10.1.1 Pravila u Lex specikaciji . . . . . . . . . . . . . . . . . . 176
10.1.2 Denicije u Lex specikaciji . . . . . . . . . . . . . . . . . 179
10.1.3 Specijalna poetna stanja . . . . . . . . . . . . . . . . . . 179
10.1.4 Denicije makroa . . . . . . . . . . . . . . . . . . . . . . . 180
10.1.5 Korisniki potprogrami . . . . . . . . . . . . . . . . . . . 181
10.1.6 Upotreba Lex generatora . . . . . . . . . . . . . . . . . . 181
10.1.7 Primer kompletne Lex specikacije . . . . . . . . . . . . . 182
10.2 Yacc  generator sintaksnih analizatora . . . . . . . . . . . . . . 186
10.2.1 Denicije u Yacc specikaciji . . . . . . . . . . . . . . . . 187
10.2.2 Denicija startnog simbola gramatike . . . . . . . . . . . 187
10.2.3 Denicije terminalnih simbola gramatike . . . . . . . . . . 187
10.2.4 Denicije prioriteta i asocijativnosti operatora . . . . . . 188
10.2.5 Denicije tipova atributa terminalnih i neterminalnih sim-
bola . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
10.2.6 Pravila u Yacc specikaciji . . . . . . . . . . . . . . . . . 189
10.2.7 Korisniki potprogrami . . . . . . . . . . . . . . . . . . . 190
10.2.8 Upotreba Yacc generatora . . . . . . . . . . . . . . . . . . 191
10.2.9 Oporavak od greaka . . . . . . . . . . . . . . . . . . . . . 192
10.2.10 Generisanje interpretatora pomou Yacc-a . . . . . . . . . 196
10.3 JFlex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
10.3.1 Opcije kojima se podeavaju parametri generisanog lek-
sikog analizatora . . . . . . . . . . . . . . . . . . . . . . . 201
10.3.2 Deklaracije posebnih poetnih stanja . . . . . . . . . . . . 203
10.3.3 Denicije makroa . . . . . . . . . . . . . . . . . . . . . . . 203
10.3.4 Pravila . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
10.3.5 Korienje JFlex-a . . . . . . . . . . . . . . . . . . . . . . 203
10.3.6 Primer JFlex specikacije . . . . . . . . . . . . . . . . . . 204
10.4 Cup  generator sintaksnih analizatora . . . . . . . . . . . . . . . 207
10.4.1 Cup specikacija . . . . . . . . . . . . . . . . . . . . . . . 209
10.4.2 Uvoenje referenci na atribute simbola u smenama . . . . 211
10.4.3 Prevoenje Cup specikacije . . . . . . . . . . . . . . . . 212
10.4.4 Korienje generisanog analizatora . . . . . . . . . . . . . 213
10.5 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
10.6 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

11 Atributne gramatike 217


11.1 Sintaksno upravljane denicije . . . . . . . . . . . . . . . . . . . 217
11.2 Generisani atributi . . . . . . . . . . . . . . . . . . . . . . . . . . 218
11.3 Nasleeni atributi . . . . . . . . . . . . . . . . . . . . . . . . . . 219
11.4 Provera tipova podataka (Type Checking ) . . . . . . . . . . . . . 225
11.4.1 Semantika pravila za proveru tipova podataka . . . . . . 225
11.5 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
11.6 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229

12 Meukodovi 231
SADRAJ v

12.1 Mesto meukoda u procesu prevoenja . . . . . . . . . . . . . . . 231


12.2 Apstraktno sintaksno stablo . . . . . . . . . . . . . . . . . . . . . 232
12.3 Implementacija apstraktnog sintaksnog stabla . . . . . . . . . . . 235
12.4 Troadresni meukod . . . . . . . . . . . . . . . . . . . . . . . . . 235
12.4.1 Quadriples struktura . . . . . . . . . . . . . . . . . . . . . 238
12.4.2 Triples struktura . . . . . . . . . . . . . . . . . . . . . . . 238
12.4.3 Indirect triples struktura . . . . . . . . . . . . . . . . . . 240
12.5 Troadresni meukod za naredbe dodeljivanja . . . . . . . . . . . 241
12.6 Troadresni meukod upravljakih naredbi . . . . . . . . . . . . . 245
12.7 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
12.8 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253

13 Optimizacija koda 255


13.1 Osnovna optimizacija koda (peephole optimizacija) . . . . . . . . 255
13.1.1 Eliminisanje redundantnih naredbi . . . . . . . . . . . . . 256
13.1.2 Optimizacija toka . . . . . . . . . . . . . . . . . . . . . . . 257
13.1.3 Nedosegljiv kod . . . . . . . . . . . . . . . . . . . . . . . . 258
13.1.4 Algebarska uproenja . . . . . . . . . . . . . . . . . . . . 259
13.1.5 Direktna redukcija . . . . . . . . . . . . . . . . . . . . . . 259
13.1.6 Korienje mainskih idioma . . . . . . . . . . . . . . . . . 259
13.2 Dodatna optimizacija . . . . . . . . . . . . . . . . . . . . . . . . 260
13.2.1 Zajedniki podizrazi . . . . . . . . . . . . . . . . . . . . . 263
13.2.2 Zajedniki podizrazi na globalnom nivou . . . . . . . . . . 264
13.2.3 Prostiranje naredbi za kopiranje . . . . . . . . . . . . . . 264
13.2.4 Eliminisanje neaktivnog koda . . . . . . . . . . . . . . . . 265
13.2.5 Optimizacija petlji . . . . . . . . . . . . . . . . . . . . . . 265
13.3 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267

14 Generisanje koda 271


14.1 Odredina maina  procesor Intel 8086 . . . . . . . . . . . . . . 272
14.1.1 Osnovni skup instrukcija . . . . . . . . . . . . . . . . . . . 273
14.1.2 Naini adresiranja . . . . . . . . . . . . . . . . . . . . . . 274
14.2 Upravljanje memorijom u toku izvrenja programa . . . . . . . . 276
14.2.1 Organizacije memorije . . . . . . . . . . . . . . . . . . . . 276
14.2.2 Aktivacioni slogovi . . . . . . . . . . . . . . . . . . . . . . 277
14.3 Statika alokacija memorije . . . . . . . . . . . . . . . . . . . . . 279
14.4 Alokacija memorije pomou steka . . . . . . . . . . . . . . . . . . 280
14.5 Dinamika alokacija memorije . . . . . . . . . . . . . . . . . . . . 281
14.5.1 Generisanje koda za poziv potprograma . . . . . . . . . . 281
14.5.2 Generisanje sekvence poziva . . . . . . . . . . . . . . . . . 285
14.5.3 Generisanje sekvence povratka . . . . . . . . . . . . . . . 286
14.5.4 Smetanje promenljivih i pristup promenljivama u razli-
itim delovima memorije . . . . . . . . . . . . . . . . . . . 289
14.6 Realizacija generatora koda . . . . . . . . . . . . . . . . . . . . . 291
14.6.1 Algoritam generisanja koda . . . . . . . . . . . . . . . . . 291
14.6.2 Funkcija getreg . . . . . . . . . . . . . . . . . . . . . . . . 292
vi SADRAJ

14.6.3 Generisanje koda za neke specijalne naredbe . . . . . . . . 293


14.6.4 Generisanje koda za naredbe sa indeksnim promenljivama 293
14.6.5 Generisanje koda za naredbe sa pokazivaima . . . . . . . 293
14.6.6 Generisanje koda za naredbe uslovnog skoka . . . . . . . . 294
14.7 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
14.8 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298

15 Realizacija kompilatora 299


15.1 Tehnika butstrepovanja . . . . . . . . . . . . . . . . . . . . . . . 299
15.1.1 Kompilator za novi programski jezik . . . . . . . . . . . . 301
15.1.2 Prenoenje kompilatora sa jedne na drugu mainu . . . . 301
15.1.3 Optimizacija postojeeg kompilatora . . . . . . . . . . . 302
15.1.4 Razvoj kompilatora za programski jezik Pascal . . . . . . 302
15.1.5 Razvoj kompilatora za programski jezik FORTRAN . . . 303
15.2 Struktura kompilatora . . . . . . . . . . . . . . . . . . . . . . . . 308
15.2.1 C kompilator za mainu PDP 11 . . . . . . . . . . . . . . 308
15.2.2 FORTRAN H kompilator . . . . . . . . . . . . . . . . . . 308
15.3 Pitanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309

16 Dodatak 313
16.1 Java bajtkod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Slike

1.1 Programski prevodilac . . . . . . . . . . . . . . . . . . . . . . . . 3


1.2 Asembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Makroprocesor . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4 Kompilator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.5 Interpretator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.6 Hibridni prevodilac . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.7 Naini prevoenja java aplikacija . . . . . . . . . . . . . . . . . . 9
1.8 Viejeziki kompilatori . . . . . . . . . . . . . . . . . . . . . . . . 10
1.9 Sintaksno stablo za naredbu pos := int + r * 60.0 . . . . . . 11
1.10 Apstraktno sintaksno stablo za naredbu pos := int + r * 60.0 11
1.11 Oznaeno sintaksno stablo za naredbu pos := int + r * 60.0 12
1.12 Potpuna struktura kompilatora . . . . . . . . . . . . . . . . . . . 13

2.1 Sintaksno stablo za re iz primera 2.11 . . . . . . . . . . . . . . . 22

3.1 ema automata kao ureaja za prepoznavanje jezika . . . . . . . 35


3.2 Model Tjuringove maine . . . . . . . . . . . . . . . . . . . . . . 37
3.3 Magacinski automat . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.4 ema konanog automata . . . . . . . . . . . . . . . . . . . . . . 42
3.5 Automat za regularni izraz r= . . . . . . . . . . . . . . . . . . 52
3.6 Automat za regularni izraz r=a . . . . . . . . . . . . . . . . . . 52
3.7 Automat za regularni izraz r|s . . . . . . . . . . . . . . . . . . . 53
3.8 Automat za regularni izraz rs . . . . . . . . . . . . . . . . . . . 53
3.9 Automat za regularni izraz (s) . . . . . . . . . . . . . . . . . . . 53

4.1 Veza izmeu leksikog i sintaksnog analizatora . . . . . . . . . . 60


4.2 Deo automata kojim se izbacuju komentari . . . . . . . . . . . . 65
4.3 Prepoznavanje relacionih operatora . . . . . . . . . . . . . . . . . 66
4.4 Prepoznavanje aritmetikih operatora . . . . . . . . . . . . . . . 67
4.5 Prepoznavanje identikatora i literala . . . . . . . . . . . . . . . 68
4.6 Prepoznavanje celih brojeva bez znaka . . . . . . . . . . . . . . . 68
4.7 Automat koji prepoznaje brojeve prema deniciji u jeziku Pascal 69
4.8 Dvostruki bafer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

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

8.1 LR sintaksni analizator . . . . . . . . . . . . . . . . . . . . . . . 136


8.2 Graf automata LR analizaora iz primera 8.4 . . . . . . . . . . . . 148
8.3 Graf automata LR analizatora iz zadatka 3 . . . . . . . . . . . . 151
8.4 Graf automata za prepoznavanje vidljivih preksa uz zadatak 4 . 155

9.1 Graf kojim je u tabeli simbola predstavljena struktura Polinom . 162


9.2 Dijagram klasa za predstavljanje simbola . . . . . . . . . . . . . 164
9.3 Izmenjena struktura kompilatora . . . . . . . . . . . . . . . . . . 165
9.4 Tabela simbola realizovana kao lanana lista . . . . . . . . . . . . 165
9.5 Tabela simbola realizovana kao ureeno binarno stablo . . . . . . 166
9.6 Tabela simbola realizovana kao rasuta tablica . . . . . . . . . . . 166
9.7 Taka 1 za drugi sluaj uz primer 9.2 . . . . . . . . . . . . . . . . 171
9.8 Taka 2 za drugi sluaj uz primer 9.2 . . . . . . . . . . . . . . . . 171
9.9 Taka 3 za drugi sluaj uz primer 9.2 . . . . . . . . . . . . . . . . 172
9.10 Taka 4 za drugi sluaj uz primer 9.2 . . . . . . . . . . . . . . . . 172

10.1 Graf automata leksikog analizatora jezika Pascal . . . . . . . . 216

11.1 Generisan atribut . . . . . . . . . . . . . . . . . . . . . . . . . . . 218


11.2 Oznaeno sintaksno stablo za izraz 5 (3 + 4) uz primer 11.1 . . 220
11.3 Nasleeni atributi . . . . . . . . . . . . . . . . . . . . . . . . . . 221
11.4 Oznaeno stablo za deniciju tipa uz primer 11.2 . . . . . . . . . 222
11.5 Oznaeno sintaksno stablo za gramatiku iz primera 11.3 . . . . . 225

12.1 Mesto meukoda u okviru kompilatora . . . . . . . . . . . . . . . 231


12.2 Meukod u vie nivoa . . . . . . . . . . . . . . . . . . . . . . . . 231
12.3 Sintaksno stablo stablo za primer 12.1. Odgovarajue apstraktno
sintaksno stablo je dato na slici 12.4. . . . . . . . . . . . . . . . . 234
12.4 Apstraktno sintaksno stablo za primer 12.1. Odgovarajue sin-
taksno stablo je dato na slici 12.3. . . . . . . . . . . . . . . . . . 235
12.5 Apstraktno sintaksno stablo memorisano kao dijagram . . . . . . 236
12.6 Oznaeno sintaksno stablo za generisanje troadresnog meukoda
izraza iz primera 12.6 . . . . . . . . . . . . . . . . . . . . . . . . 243
12.7 Sintaksno stablo za izraz b = c[i] + a[i][j] iz primera 12.7 . . . . . 246
12.8 Oznaeno sintaksno stablo sa slike 12.7 uz primer 12.7 . . . . . . 247
SLIKE ix

12.9 Sintaksno stablo za naredbu if (x < 100 || x > 200 && x !=


y) x := 0; iz primera 12.8 . . . . . . . . . . . . . . . . . . . . . 250

13.1 Graf toka za meukod iz primera 13.2 . . . . . . . . . . . . . . . 262


13.2 Blok B5 posle eliminacije zajednikih podizraza . . . . . . . . . . 263
13.3 Blok B6 posle eliminacije zajednikih podizraza . . . . . . . . . . 263
13.4 Blokovi B5 i B6 posle eliminacije zajednikih podizraza na glo-
balnom nivou . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
13.5 Blok B5 posle prostiranja naredbe za kopiranje x := t3 . . . . . . 264
13.6 Blok B6 posle prostiranja naredbe za kopiranje x := t3 . . . . . . 265
13.7 Blokovi B5 i B6 posle eliminisanja neaktivnog koda . . . . . . . . 265
13.8 Blok B3 posle eliminisanja indukcionih promenljivih . . . . . . . 266
13.9 Blok B2 posle eliminisanja indukcionih promenljivih . . . . . . . 267
13.10Graf toka za meukod iz primera 13.2 nakon optimizacije . . . . 268

14.1 Pozicija generatora koda u procesu prevoenja . . . . . . . . . . 271


14.2 Organizacija memorije kod polustatikih jezika (stek alokacija) . 277
14.3 Struktura aktivacionog sloga . . . . . . . . . . . . . . . . . . . . 278
14.4 Statika alokacija memorije . . . . . . . . . . . . . . . . . . . . . 280
14.5 Aktivaciono stablo za program iz primera 14.2 . . . . . . . . . . 282
14.6 Dinamika ubacivanja aktivacionih slogova u stek za program iz
primera 14.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
14.7 Dinamika ubacivanja aktivacionih slogova u heap za program iz
primera 14.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
14.8 Aktivacioni slog koji se koristi u jeziku 8086 . . . . . . . . . . . . 284

15.1 Razvoj novog kompilatora . . . . . . . . . . . . . . . . . . . . . . 300


15.2 Kompilator predstavljen T -dijagramom. . . . . . . . . . . . . . . 300
15.3 Kompilator iz primera 15.1 . . . . . . . . . . . . . . . . . . . . . 300
15.4 Generisanje kompilatora za JavaM M . . . . . . . . . . . . . . . . 301
15.5 Realizacija kompilatora CN N pomou kompilatora CM M . . . . . 302
15.6 Optimizacija kompilatora CM M . . . . . . . . . . . . . . . . . . . 303
15.7 Generisanje kompilatora NP6000 6000-opt . . . . . . . . . . . . . . 304
15.8 Generisanje kompilatora NP6000# 6000-opt . . . . . . . . . . . . . 304
15.9 Objedinjeni koraci butstrepovanja sa slika 15.7 i 15.8 . . . . . . . 304
15.10Prva faza butstrepovanja . . . . . . . . . . . . . . . . . . . . . . . 305
15.11Druga faza butstrepovanja . . . . . . . . . . . . . . . . . . . . . . 305
15.12Objedinjene prve dve faze butstrepovanja sa slika 15.10 i 15.11 . 306
15.13Trei korak butstrepovanja . . . . . . . . . . . . . . . . . . . . . 306
15.14etvrti korak butstrepovanja . . . . . . . . . . . . . . . . . . . . 306
15.15Sve faze butstrepovanja primenjenog kod generisanja kompilatora
za FORTRAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
15.16P kompilator za Pascal . . . . . . . . . . . . . . . . . . . . . . . . 308
15.17Kompilator za programki jezik C za mainu PDP 11 . . . . . . . 309
15.18FORTRAN H kompilator . . . . . . . . . . . . . . . . . . . . . . 310
x SLIKE
Tabele

1.1 Klasikacija programskih jezika . . . . . . . . . . . . . . . . . . . 4

3.1 Veze izmeu gramatika tipa tri i konanih automata . . . . . . . 46


3.2 Algebarska svojstva regularnih izraza . . . . . . . . . . . . . . . . 51

5.1 Postupak sintaksne analize iz primera 5.7 . . . . . . . . . . . . . 87

6.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

7.1 Otkrivanje relacije prvenstva uz primer 7.1 . . . . . . . . . . . . 114


7.2 Operatorska tabela iz primera 7.1 . . . . . . . . . . . . . . . . . . 119
7.3 Opte relacije prioriteta . . . . . . . . . . . . . . . . . . . . . . . 124
7.4 Otkrivanje relacija prvenstva za gramatiku prvenstva iz primera 7.4127
7.5 Tabela prvenstva razmatrane gramatike prvenstva iz primera 7.4 130
7.6 Analiza izraza za gramatiku iz primera 7.5. . . . . . . . . . . . . 132

8.1 LR sintaksna tabela dobijena u zadatku 3 . . . . . . . . . . . . . 152


8.2 Postupak analize zadatog niza iz zadatka 3. . . . . . . . . . . . . 153
8.3 LR sintaksna tabela dobijena u zadatku 4 . . . . . . . . . . . . . 155

10.1 Metasimboli za denisanje regularnih izraza u Lex specikaciji . 177

11.1 Sintaksno upravljana denicija jednostavnog kalkulatora . . . . . 219


11.2 Redosled izraunavanje i vrednosti atributa za izraz 5 (3 + 4) uz
primer 11.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
11.3 Sintaksno upravljana denicija za upis tipova podataka . . . . . 222
11.4 Redosled izraunavanja i vrednosti atributa za primer 11.2 . . . . 223
11.5 Sintaksno upravljana denicija za proveru identikatora . . . . . 224
11.6 Izraunavanje atributa za program iz primera 11.3 . . . . . . . . 226
11.7 Semantika pravila za tipove identikatora . . . . . . . . . . . . . 226
11.8 Provera tipova u izrazima. . . . . . . . . . . . . . . . . . . . . . . 227
11.9 Provera strukture naredbe . . . . . . . . . . . . . . . . . . . . . . 228
11.10Konverzija tipova . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
11.11Pravila za izraunavanje vrednosti binarnih brojeva . . . . . . . . 230

xi
xii TABELE

11.12Provera identikatora. je znak za nadovezivanje. . . . . . . . . 230

12.1 Semantika pravila kojima se generie apstraktno sintaksno stablo 232


12.2 Statika implementacija apstraktnog stabla . . . . . . . . . . . . 237
12.3 Osnovne troadresne naredbe predstavljene kao Quadriplesi . . . 239
12.4 Meukod memorisan kao quadriples struktura . . . . . . . . . . . 239
12.5 Meukod memorisan kao triples struktura . . . . . . . . . . . . . 240
12.6 Troadresni kod predstavljen indirect triples strukturom . . . . . . 241
12.7 Semantika pravila za naredbu dodeljivanja . . . . . . . . . . . . 242
12.8 Semantika pravila za generisanje troadresnog meukoda za iz-
raze sa indeksima . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
12.9 Semantika pravila za generisanje troadresnog meukoda za upra-
vljake naredbe . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
12.10Semantika pravila za generisanje troadresnog meukoda za Bu-
love izraze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
12.11Generisanje troadresnog koda za naredbu if (x < 100 || x >
200 && x != y) x := 0; iz primera 12.8 . . . . . . . . . . . . . 251

14.1 Instrukcije za prenos podataka . . . . . . . . . . . . . . . . . . . 273


14.2 Aritmetike instrukcije . . . . . . . . . . . . . . . . . . . . . . . . 273
14.3 Instrukcije za rad sa procesorskim stekom . . . . . . . . . . . . . 274
14.4 Instrkcije za promenu toka izvrenja programa . . . . . . . . . . 274
14.5 Pregled zastupljenih naina adresiranja . . . . . . . . . . . . . . . 275
14.6 Generisani kod za blok naredbi iz primera 14.5 . . . . . . . . . . 293
14.7 Generisani kod za naredbe sa indeksima . . . . . . . . . . . . . . 294
14.8 Generisani kod za naredbe sa pokazivaima . . . . . . . . . . . . 294
Predgovor

Sadraj ove knjige denisan je u skladu sa programom predmeta Programski


prevodioci koji je ve itav niz godina obuhvaen studijskim programom Rau-
narstvo i informatika na Elektronskom fakultetu u Niu. Autori su profesori
koji su do sada uestvovali u realizaciji nastave iz ovog predmeta: prof. ivko
Toi koji je postavio osnove ovog predmeta i uvrstio ga u studijski program
Raunarstvo i informatika, prof. Milena Stankovi koja je dugo godina bila na-
stavnik iz ovog predmeta i nekoliko puta prilagoavala njegov sadraj zahtevima
akreditacija koje su vrene, kao i prof. Suzana Stojkovi koja sada uestvuje
u realizaciji nastave iz ovog predmeta, a dugi niz godina je bila zaduena i za
realizaciju raunskih i laboratorijskih vebi.
Sadraj udbenika obuhvata klasine teme iz oblasti programskih prevodilaca kao
to su formalni jezici i gramatike u funkciji opisa sintakse programskih jezika i
realizacija leksikog i sintaksnog analizatora, ali i novije teme koje se odnose na
semantiku analizu kao deo procesa prevoenja programa. Takoe, obuhvaeno
je i korienje softverskih alata za generisanje leksikih i sintaksnih analizatora.
Sva poglavlja udbenika sadre niz primera koji su kompletno uraeni, a dati sa
ciljem da se olaka razumevanje razmatranih algoritama. Poglavlja se zavravaju
pitanjima i zadacima koji se odnose na sadraj poglavlja, a data su sa ciljem da
se studentima olaka priprema pisanog i usmenog dela ispita.
Autori posebno ele da zahvale recenzentima dr Zoranu Budimcu, redovnom
profesoru na Departmanu za matematiku i informatiku Prirodno matematikog
fakulteta u Novom Sadu, i dr Svetozaru Raniu, docentu na Deparmanu za ra-
unarske nauke Prirodno matematikog fakulteta u Niu, na uloenom trudu da
proitaju i ocene rukopis udbenika, kao i na korisnim predlozima i primedbama.
Takoe, veliku zahvalnost dugujemo studentu Lazaru Ljubenoviu, koji je kom-
pletan tekst knjige dobrovoljno prebacio iz Word-a u LATEX i svojom upornou
znatno doprineo tome da mukotrpni posao konanog uobliavanja teksta bude
doveden do kraja.
Takoe, iskreno se zahvaljujemo i svim studentima sa smera za Raunarsku
tehniku i informatiku Elektronskog fakulteta u Niu, koji su tokom korienja
delova udbenika u predtampi ukazali na razne greke koje su pronali i time

1
2 TABELE

doprineli da se znatno smanji broj greaka ostao u konanom tekstu.


Izvinjavamo se svim buduim korisnicima udbenika ako tokom njegovog korie-
nja naiu na tamparske greke, kojih verovatno jo uvek ima i pored nastojanja
da budu svedene na minimum. Biemo zahvalni za sve ukazane greke predloge
i primedbe od korisnika ovog udbenika.
U Niu, april 2017.
Glava 1

Uvod

Uvek kada softversku aplikaciju razvijamo nekim viim programskim jezikom


treba nam softver koji e taj program da prevede u mainski jezik, zato to svi
raunari, ma koliko sloeni bili, obrauju instrukcije predstavljene u mainskom
(binarnom) obliku. Zadatak tog softvera je utoliko sloeniji koliko je jezik sa
kojeg se prevodi visokog nivoa. Programski prevodioci su softverske kompo-
nente koje generalno prevode programe pisane u jednom programskom jeziku u
odgovarajue programe pisane drugim programskim jezikom (slika 1.1).

ulazni jezik programski prevodilac izlazni jezik

Slika 1.1: Programski prevodilac

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).

1.1 Vrste programskih prevodilaca


Programski prevodioci su se razvijali paralelno sa programskim jezicima i u
velikoj meri su uslovili razvoj programskih jezika, ali i razvoj raunara generalno.

Tabela 1.1 daje klasikaciju programskih jezika prema njihovom nivou i nekoj
hronologiji razvoja.

Mainski jezik je programski jezik najnieg nivoa i podrazumeva da se program


sastoji od naredbi i podataka napisanih u binarnom obliku (preko nizova jedinica
i nula) uz korienje apsolutnih adresa podataka. Na ovom nivou programski

3
4 GLAVA 1. UVOD

Tabela 1.1: Klasikacija programskih jezika

Mainski zavisni Mainski nezavisni

I generacija II generacija III generacija IV generacija

mainski jezik Maini orijentisani jezici

asemblerski makroasemblerski
jezici niskog nivoa
jezici jezici

proceduralni
jezici visokog nivoa
jezici

problemski
jezici veoma viskog nivoa
jezici

prevodilac nije potreban  naredbe se upisuju direktno u operativnu memoriju


i izvravaju.

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 jezici su neto vieg nivoa od asemblerskih jezika i omogu-


avaju skraeno zapisivanje programa tako to se grupa asemblerskih naredbi
predstavi jednom makro-naredbom. Kod programa napisanih na ovom nivou,
najpre se koristi makroprocesor iji je zadatak da pozive makro-naredbi zameni
odgovarajuim sekvencama asemblerskih naredbi. Nakon toga se dobijeni asem-
blerski kod prevodi u mainski pomou odgovarajeg asemblera (slika 1.3).

Kako je asemblerski jezik niskog nivoa, a posebno zbog injenice da svakoj


asemblerskoj naredbi odgovara jedna mainska naredba, realizacija asemblera
nije komplikovan zadatak. Slino je i sa makroproceosorom, iji je zadatak
prvenstveno da pokupi i zapamti denicije makro-naredbi i da zameni pozive
makro-naredbi odgovarajuim sekvencama asemblerskih naredbi.
1.2. STRUKTURA KOMPILATORA 5

makroasemblerski
makroprocesor
jezik

asemblerski jezik
mainski
jezik
asembler CPU rezultati

podaci
Slika 1.3: Makroprocesor

U sluaju viih programskih jezika proces prevoenja na mainski nivo je slo-


eniji. U te svrhe se kao programski prevodioci koriste kompilatori (slika 1.4) i
interpretatori (slika 1.5). Osnovna razlika izmeu kompilatora i interpretatora
je u tome to kompilator najpre vri analizu programa na osnovu koje generie
mainski kod celog programa. Interpretatori koriste drugu strategiju: prevode
naredbu po naredbu programa i, im formiraju celinu koja moe da se izvri,
izvravaju je.

Koncept kompiliranja programa se primenjuje kada se razvijaju aplikacije koje


se kasnije koriste kao gotovi proizvodi dok je koncept interpretiranja pogodniji
u sluaju interaktivne komunikacije sa raunarom.

U okviru ovog predmeta razmatraemo uglavnom probleme vezane za realizaciju


kompilatora.

1.2 Struktura kompilatora


Kompilator zapoinje analizu programa fazom leksike analize. U ovoj fazi
identikuju se leksike celine i nastoji se da se uprosti zapis programa kako bi
se pripremio za sintaksnu analizu. Na primer, za proces sintaksne analize nije
vano da li je neka promenljiva u programu nazvana A ili B ve je vano da
se na odreenom mestu javlja poromenljiva. Imena promenljivih kao i imena
drugih elemenata programa su bitna u narednim koracima prevoenja, zato se
ta imena, kao i mnoge druge informacije o entitetima koje imenuju, pamte u
posebnoj strukturi koja se naziva tabela simbola (symbol table ).
Nakon leksike analize sledi faza sintaksne analize. Zadatak ove faze je da
se utvrdi da li je program napisan u skladu sa pravilima kojima je denisan
programski jezik koji je korien. Danas se koriste formalni opisi programskih
jezika preko odreenih meta-jezika . U sutini, zadatak sintaksnog analizatora
je da ralani sloene naredbe jezika na elementarne. Kao rezultat sintaksne
analize dobija se sintaksno stablo koje pokazuje koja pravila i kojim redosledom
treba primeniti da bi se generisala odreena naredba jezika.
6 GLAVA 1. UVOD

izvorni program

vii programski jezik

leksiki analizator

jezik simbola (tokena)

sintaksni analizator

sintaksno stablo

generator meukoda optimizacija

meukod

generator koda

mainski kod

CPU

Slika 1.4: Kompilator

Na osnovu sintaksnog stabla genrie se meukod programa. Meukod je


reprezentacija programa koja je mainski nezavisna ali se jednostavno preslikava
u mainski ili asemblerski kod za odreenu mainu.

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.

Savremeni kompilatori pored sintaksne vre i semantiku analizu koja se esto


integrie sa sintaksnom analizom ili se izvrava kao nezavisna faza. Zadatak se-
mantike analize je da utvrdi da li su u pisanju programa ispotovana dodatna,
semantika pravila koja se ne mogu formalno denisati kroz formalni opis je-
zika. Takva pravila su recimo pravila vezana za koncept jakih tipova podataka
ili pravila o tome kojim stvarnim parametrima mogu da se zamenjuju ktivni
parametri i sl. Ova dodatna pravila se obino deniu kao procedure koje se
izvravaju prilikom primene odreenog sintaksnog pravila.
1.3. HIBRIDNI PREVODIOCI 7

izvorni program

vii programski jezik

interpretator podaci

rezultati
Slika 1.5: Interpretator

1.3 Hibridni prevodioci


Pored istih kompilatora i interpretatora danas se koriste i hibridni prevodioci
(slika 1.6) koji predstavljaju neku vrstu meavine kompilatora i interpretatora,
vre analizu koda kao kompilatori, generiu meukod programa i nakon toga
interpretiraju taj meukod.

1.4 Prenosivost koda


Koncept korienja meukoda kod kompilatora ima niz prednosti. Kako je me-
ukod mainski nezavisan, jednostavno se moe preslikati u bilo koji drugi ma-
inski jezik. To znai da se na osnovu jednom generisanog meukoda moe
generisati mainski kod za razliite maine i ostvariti prenosivost koda.

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.

Danas se programski jezik Java koristi na vie razliitih naina):

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

vii programski jezik

leksiki analizator

jezik simbola (tokena)

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).

3. U treem sluaju Java kod se ne preslikava u standardni meukod ve


se direkno generie mainski kod za procesor na kome e se izvravati
(slika 1.7c).

4. U poslednjem sluaju interpretator Java meukoda je realizovan kao po-


seban Java ip koji interpretira naredbe meukoda kao to standardni
procesor izvrava mainske naredbe (slika 1.7d).
1.5. VIEJEZIKI KOMPILATOR 9

Java aplikacija Java virtuelna mainski


(bajt-kod) CPU
maina jezik

(a) Java virtuelna maina (interpretiranje  sporo): prevodi instrukcije u mainski


jezik po redosledu pojavljivanja.

Java aplikacija JIT mainski


(bajt-kod) CPU
kompilator jezik

(b) Java just-in-time kompilator (bri): konveruje sve instrukcije u maonski jezik kad
je instrukcija potrebna (dinamiko prevoenje), a zatim izvrava mainski jezik.

mainski jezik CPU

(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.

Slika 1.7: Naini prevoenja java aplikacija

1.5 Viejeziki kompilator


Korienje meukoda, takoe, omoguava realizaciju viejezinih kompilatora
(slika 1.8) . To su kompilatori koji imaju posebne delove za analizu koda za vie
razliitih programskih jezika, pri emu se kod svih ovih analizatora generie isti
meukod programa. Posle toga, taj meukod moe da se prevodi u mainski
jezik odreenog raunara, jednog ili vie razliitih procesora.

1.6 Proces prevoenja programa


U nastavku ovog poglavlja, kako bi donekle stekli utisak o radu kompilatora,
propratiemo jednu naredbu napisanu na hipotetikom viem programskom je-
ziku kroz sve faze kompilatora.

Kao primer uzeemo naredbu dodeljivanja:


10 GLAVA 1. UVOD

kod na kod na
programskom programskom
jeziku 1 jeziku 2

leksiki analizator leksiki analizator

sintaksni analizator sintaksni analizator

generator meukoda generator meukoda


ne n
op va
m tim
e iz izo d
uk ov t im uko
od an op
ne me

optimizacija meukoda
n op
va t
m imi
izo od e zo
ptim uk uk va
od n
o m e

generator koda generator koda


mainski mainski
kod 1 kod 2
CPU CPU

Slika 1.8: Viejeziki kompilatori

pos := init + r * 60.0

Leksika analiza. Leksiki analizator analizira znak po znak ove naredbe i


nastoji da identikuje leksike celine (lekseme), pri emu svaku leksemu zame-
njuje odgovarajuim simbolom (tokenom). U naem primeru rezultat analize
bie sledea sekvenca:

id1 := id2 + id3 * const

Leksiki analizator je prepoznao identikatore pos, init i r i zamenio ih sim-


bolom id. Takoe su prepoznati siboli :=, + i *, koji ostaju nepromenjeni, kao
i konstanta 60.0 koja je zamenjena tokenom const.

Leksiki analizator takoe generie tabelu simbola, kao posebnu strukturu u


kojoj uva podatke o elementima programa koji su prepoznati. Na primer, u
sledeoj tabeli simbola se uvaju imena identikatora za na primer.
1.6. PROCES PREVOENJA PROGRAMA 11

naredba

id1 := izraz1 :=

izraz2 + izraz3 id1 +

id2 izraz
4 * izraz5 id2 *

id3 const id3 const


Slika 1.9: Sintaksno stablo za naredbu Slika 1.10: Apstraktno sintaksno stablo
pos := int + r * 60.0 za naredbu pos := int + r * 60.0

Atribut1 Atribut2 Atribut3


Ime
Vrsta entiteta Tip ...

1 pos var real ...

2 init var real ...

3 r var real ...

Sintaksna analiza. Zadatak sintaksnog analizatora je da utvrdi da li je data


naredba napisana u skladu sa formalnim opisom jezika. U te svrhe sintaksni
analizator koristi skup pravila kojima se opisuje jezik. U naem primeru to bi
bio sledei skup pravila:

1. Svaki identikator je izraz.

2. Svaka konstanta je izraz. Ako su izraz1 i izraz2 izrazi, tada je su izrazi i:

(a) izraz1 + izraz2


(b) izraz1 izraz2
3. Ako je id1 identikator i ako je izraz1 izraz, tada je id1 := izraz1 naredba.

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.

Semantika analiza. Sintaksni analizator moe da bude obogaen dodatnim


semantikim procedurama kojima se proveravaju neka dodatna semantika pra-
vila kojima je dopunjen opis jezika. U naem sluaju, semantiki analizator
12 GLAVA 1. UVOD

moe da proverava da li su u naredbi dodeljivanja ispotovana pravila jakih


tipova podataka. U te svrhe analizator moe da koristi apstraktno sintaksno
stablo obogaeno atributima. Ovakvo stablo se naziva oznaeno sintaksno sta-
blo (annotated syntax tree ); slika 1.11 za na primer. Drugi nain za pamenje
dodatnih atributa simbolikih imena je tabela simbola.

Generisanje meukoda. Na osnovu apstraktnog sintaksnog stabla generie


se meukod programa. U sluaju razmatrane naredbe dodeljivanja, moe da
bude generisana sledea sekvenca naredbi hipotetikog asemblerskog jezika.

t1 := real(60)
t2 := r * t1
t3 := init + t2
pos := t3

Promenljive t1, t2 i t3 su takozvane privremene promenljive, odnosno promen-


ljive koje generie kompilator za smetaj meurezultata.

Generisanje koda. Na osnovu meukoda generie se ciljni kod programa; to


moe da bude zapis u asemblerskom jeziku ciljne maine ili direktno mainski
jezik. Asemblerski kod za posmatrani primer bi bio:

MOV r, R2
MULV #60.0, R2
MOV init, R1
ADD R2, R1
MOV R1, pos

Pored navedenih koraka, relani kompilatori obino ukljuuju i optimizaciju koda


kako na nivou meukoda tako i na nivou generisanog asemblerskog ili mainskog
koda. Slika 1.12 prikazuje potpunu strukturu kompilatora.

:=

id1 .real +

id2 .real

id3 .real const.real


Slika 1.11: Oznaeno sintaksno stablo za naredbu pos := int + r * 60.0
1.7. KRATAK OSVRT NA ISTORIJU KOMPILATORA 13

izvorni program optimizacija meukoda

vii programski jezik meukod

leksiki analizator generisanje


asemblerskog koda
jezik simbola (tokena)
asemblerski kod
sintaksni analizator
optimizacija
apstraktno sintaksno stablo
asemblerskog koda
semantika analiza
asemblerski kod
ozaneno sintaksno stablo
generisanje
generator meukoda mainskog koda

meukod niz bitova

CPU

rezultati
Slika 1.12: Potpuna struktura kompilatora

1.7 Kratak osvrt na istoriju kompilatora


Re kompilator (compiler ) je prvi put upotrebila Grace Murray Hopper. Ori-
ginalno znaenje glaglola kompilirati (to compile ) je izvriti odabir reprezenta-
tivnog materijala i dodati ga kolekciji. Na taj nain se danas, na primer, taj
glagol pravilno koristi kada kaemo kompilacija kompakt diskova. U ranoj fazi
razvoja programskih jezika i kompilatora, prevoenje programskih jezika je vi-
eno na isti nain: kada se u ulaznom kodu nalazi npr. A + b, onda se bira LOAD
a, R1 i ADD b, R1 i dodaje na prethodno generisanu sekvencu naredbi. U toj
fazi kompilator je prevodio deo po deo programa i dodavao ga kodu. Dananji
kompilatori, posebno oni za savremene objektno-orijentisane jezike, su mnogo
sloeniji programi koji obavljaju mnogo sloenije transformacije ulaznog koda.
Takoe ukljuuju i niz specinih semantikih analiza ili automatsku paraleli-
zaciju programa.

Sve do kraja 1950. godine, programiralo se korienjem mainski zavisnih je-


zika, dok su mainski nezavisni jezici samo nauno razmatrani i predlagani. U
to vreme kapaciteti raunara su bili ogranieni i sami programi kratki. Meutim,
poinju da se javljaju ideje o korienju viih programskih jezika i razvijeno je
nekoliko eksperimentalni kompilatora. Prvi kompilator bio je napisan od strane
Grace Hopper 1952. godine za programski jezik A-0. Prvi kompletan kompi-
lator koji je imao iru primenu i bitno uticao na dalji razvoj je kompilator za
14 GLAVA 1. UVOD

FORTRAN realizovan 1957. godine od strane IBM-ovog tima kojim je rukovo-


dio John Backus. U to vreme, negde oko 1960. godine, COBOL je bio prvi jezik
za koji su bili realizovani kompilatori za razliite procesore i koji je mogao da
se koristi na vie razliitih maina.

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.

Prvi kompilatori su bili pisani na asemblerskom jeziku. Prvi tzv. self-hosting


kompilator, gde je isti programski jezik korien i za razvoj kompilatora, bio
je realizovan za programski jezik Lisp, na MIT-u od strane Tim Harta i Mika
Levina. Za generisanje ovog kompilatora posluio je prethodno napravljeni in-
terpretator za Lisp. Posle toga, negde od 1970. godine, postaje uobiajena
praksa da se kompilatori razvijaju na jeziku za koji se i prave. Pri tome se
starije verzije kompilatora koriste za dobijanje novih to je poznato kao teh-
nika butstrepovanja. Naravno, prva verzija nekog kompilatora mora da bude
napisana na nekom drugom programskom jeziku.

1.8 Pitanja
1. Objasniti namenu progrmskih prevodilaca.

2. ta je to asembler?

3. emu slue makroprocesori?

4. Objasniti razliku izmeu kompilatora i interpretatora.

5. Navesti osnovne faze rada kompilatora.

6. Objasniti ta je to meukod.

7. ta su to viejeziki kompilatori?

8. Nacrtati potpunu emu strukture kompilatora.

9. Kada su nastali prvi kompilatori?


Glava 2

Elementi teorije formalnih


jezika

Danas se podrazumeva da se programski jezik formalno denie ve prilikom


njegovog projektovanja. Formalni opis jezika na neki nain predstavlja njegovu
standardizaciju i osnovu za pravilnu primenu i dalji razvoj jezika. Takoe,
formalni opis je jedan od uslova za uspenu realizaciju kompilatora za odreeni
programski jezik.

2.1 Opis jezika


Razmotriemo ta se sve u okviru programskog jezika moe formalno opisati.

Najpre se opisuju leksiki elementi jezika. To su leksike celine, lekseme, koje


imaju neki smisao u jeziku; na primer, broj, identikator, kljuna re i sl. Ove
leksike celine prepoznaje leksiki analizator i prosleuje ih sintaksnom analiza-
toru.

Na sledeem nivou se vri opis sintakse programskog jezika. Formalnim opisom


sintakse jezika deniu se pravilne konstrukcije, odnosno koje kombinacije rei
su dozvoljene i u kom kontekstu. Opis sintakse jezika je osnova sintaksnom
analizatoru da proveri da li su naredbe programskog jezika pravilno napisane i da
ih preslika u strukturu iz koje e moi da budu generisane naredbe asemblerskog
koda.

Trei nivo formalnog opisa jezika moe da se odnosi na semantiku. Odnosno,


ve na nivou formalnog opisa jezika mogu da se deniu neka pravila koja e se
koristiti za semantiku proveru programa.

Za sva ova tri nivoa opisa jezika koriste se formalni jezici i formalne gramatike

15
16 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA

. U nastavku e biti dati osnovni elementi teorije formalnih jezika. To je ira


nauna oblast koja se moe posmatrati i kao lingvistika disciplina. Nalazi iroku
primenu u mnogim oblastime informatike kao to su prepoznavanja uzoraka,
obrada prirodnih jezika i sl.

2.2 Elementi jezika


2.2.1 Azbuka
Prilikom opisa jezika, polazi se od azbuke kao osnovnog pojma. Neka je V
konaan neprazan skup elemenata. Elementi skupa V su simboli ili slova, a
sam skup apstraktna azbuka ili samo azbuka .

Primer 2.1 Primeri azbuka


Primeri azbuka:

V = {0, 1}  azbuci V pripadaju samo cifre 0 i 1;


V = {a, b, c}  azbuci pripadaju samo slova a, b i c.
Za opis programskih jezika se koriste neto sloenije azbuke. Na primer,
jednu takvu azbuku mogu da ine sledei simboli:

specijalni znaci: +, -, *, :=, ...

rei kao to su: begin, end, if, then, ...

Napomena: u ovom sluaju se svaka re tretira kao jedan simbol.

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 .

Primer 2.2 Rei


Neka je V = {a, b, c}. Sledei nizovi su primeri rei azbuke V: , a, b, c,
aa, bb, cc, ab, ac, abc, aabc.

Rei su ureeni nizovi tako da se re ab razlikuje od rei ba (ab 6= ba).


Re se moe i formalno denisati sledeim skupom pravila :

1. je re nad azbukom V.
2.2. ELEMENTI JEZIKA 17

2. Ako je x re azbuke V i ako je a element azbuke V, tada je i xa re azbuke


V.
3. Niz y je re nad azbukom V ako i samo ako je dobijen primenom pravila
1 i 2.

Za oznaavanje rei koristiemo zavrna mala slova abecede napisana boldirano:


u, v, w, x, y, z.
Broj slova (simbola) u rei denie se kao duina rei. Za oznaavanje duine
rei x koristi se simbol |x|.

Primer 2.3 Duina rei


Vai |abc| = 3, |aaaa| = 4, dok je || = 0.

2.2.3 Proizvod rei


Ako su xiy dve rei azbuke V, proizvod ili spajanje rei je operacija kojom se
stvara nova re tako to se na jednu re nadovezuje druga re.

Primer 2.4 Proizvod rei


Neka je x = aA i y = ab. Proizvodom ovih rei nastaje re z = xy = aAab.

Takoe vai da je: x = x = x. Prazna re je neutralni element za operaciju


proizvoda (nadovezivanja) rei.

2.2.4 Eksponent rei


Viestruki proizvod iste rei se denie kao eksponent rei .

Primer 2.5 Eksponent rei


Vae sledee jednakosti:

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.

Primer 2.6 Transponovana re


Neka je data re x = baba. Tada je x| = abab. Ako je x = radar, tada
|
je x = radar. Ovakve rei, kod kojih su original i transponovana re isti,
nazivaju se palindromi.

2.2.6 Delovi rei


Razlikujemo i sledee pojmove:

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.

Primer 2.7 Delovi rei


Neka je data re banana.
Rei , b, ba, ban, bana, banan i banana su njeni preksi; b, ba, ban, bana,
banan su pravi preksi.
Rei , a, na, ana, nana, anana i banana su njeni suksi; a, na, ana,
nana, anana su pravi suksi.

2.3 Formalni jezik


Neka je data azbuka V. Skup svih rei nad azbukom V se oznaava sa V .
Napomenimo da je skup V uvek beskonaan, bez obzira na to kako je denisana
2.3. FORMALNI JEZIK 19

azbuka V. ak i u sluaju kada azbuka V sadri samo jedan simbol V = {a},


skup V = {, a, aa, aaa, aaaa, . . .} je beskonaan.
Formalni jezik nad azbukom V je bilo koji podskup skupa V . Bilo koji podskup
rei nad azbukom V, bilo da je konaan ili beskonaan, predstavlja jezik. Kako
je V uvek beskonaan skup, broj njegovih podskupova je takoe beskonaan.
Drugim reima, ma koliko da je azbuka siromana, ak i kada se sastoji od
samo jednog simbola, nad njom se moe denisati beskonaan broj razliitih
formalnih jezika.

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 .

Primer 2.8 Formalni jezik


Neka je data azbuka V koju ine sva slova latininog alfabeta

V = {a, b, c, . . . , x, y, z}.

Tada skupu V pripadaju svi nizovi koji mogu da se formiraju od slova


latinice. Svaki podskup tog skupa rei je jedan formalni jezik. Na primer,
sledei skupovi su formalni jezici:

1. skup nizova koji se sastoji samo od samoglasnika;

2. skup nizova koji se sastoji samo od suglasnika;

3. skup nizova koji sadre najmanje jedan samoglasnik i najmanje jedan


suglasnik;

4. skup nizova koji su palindromi (itaju se isto sa leve i sa desne strane);

5. skup nizova ija duina je manja od 10;


6. skup nizova koji se sastoje samo od jednog slova;

7. skup {ja, ti, on, mi, vi, oni};


8. prazan skup.

Uoite da su prva etiri jezika beskonana, dok su ostali konani.

2.3.1 Operacije nad jezicima


Ako je L formalni jezik onda se moe denisati i njegov reverzni jezik u oznaci
LR , kao skup svih transponovanih (reverznih) rei jezika L:
R |
L = {x | x L}.
20 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA

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}.

Potpuno zatvaranje jezika L, koje se oznaava sa L , je skup svih rei koje


nastaju kao proizvodi rei jezika L ukljuujui i :

[
L = Li .
i=0

Pozitivno zatvaranje jezika L, za koje se koristi oznaka L+ , denie se kao:


[
L+ = Li .
i=1

To znai da pozitivno zatvaranje iskljuuje iz potpunog zatvaranja praznu re,


tj. vai: L+ = L \ .

Primer 2.9 Operacije nad jezicima


Neka su date azbuke

L = {A, B, C, . . . , Z, a, b, c, . . . , z} i D = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}.

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 slova i cifara,

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

2.4 Opis jezika


Moemo da identikujemo dva osnovna problema u radu sa formalnim jezicima.
Prvi je problem formalnog opisa skupa rei koje pripadaju jeziku, a drugi je
problem utvrivanja da li zadata re pripada odreenom jeziku.

Prvi problem se reava pomou gramatika. Gramatike su sredstvo za opis jezika.


Drugi problem moe da se posmatra kao problem prepoznavanja jezika i to je
kljuni problem koji se reava pomou automata kao ureaja za prepoznavanje
jezika.

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.

Primer 2.10 Pravila gramatike


Naredbe jednog programskog jezika se formalno mogu posmatrati kao rei
tog jezika. Sledeim skupom pravila denie se ta se moe smatrati na-
redbom u kontekstu ovog formalnog jezika.

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

2.4.1 Izvoenje rei


Rei jezika izvode se primenom pravila gramatike. Obino se denie startni
simbol i nastoji se da se primenom pravila gramatike od tog simbola generiu
rei jezika. Na primer, u primeru 2.10 moe se kao startni simbol uzeti po-
jam naredba. Postupak generisanja rei primenom pravila gramatike naziva se
izvoenje rei.

Primer 2.11 Izvoenje rei


Pokazaemo izvoenje rei # alfa := alfa beta + pi + 90.0 # koja pripada
jeziku denisanom skupom pravila iz primera 2.10. Analizator ovu re vidi
22 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA

kao # id1 := id1 id2 id3 + const #.

naredba1 id1 := izraz1


id1 := izraz2 + izraz3
id1 := izraz4 izraz5 + izraz3
id1 := id1 izraz5 + izraz3
id1 := id1 izraz6 + izraz7 + izraz3
id1 := id1 id2 + izraz7 + izraz3
id1 := id1 id2 + id3 + izraz3
id1 := id1 id2 + id3 + const

Napomena: Brojevi koji su dopisani na rei koje oznaavaju odreene


lekseme koriste se da bi se razlikovale razliite instance iste lekseme.

Postupak izvoenja rei jezika primenom pravila gramatike se moe prikazati


preko strukture koje se naiva sintaksno stablo. Pri tome svaki neterminalni
vor u stablu sa svojim granama predstavlja jedno primenjeno pravilo. U za-
vrnim (terminalnim) vorovima prestavljena su slova izvedene rei. Slika 2.1
prikazuje sintaksno stablo koje se dobija prilikom analize naredbe dodeljivanja
iz primera 2.11. Moe se rei da je cilj sintaksne analize generisanje sintaksnog
stabla.

naredba

id1 := izraz1

izraz2 + izraz3

izraz4 * izraz5 izraz6 + izraz7

id2 id3 id4 const1


.

Slika 2.1: Sintaksno stablo za re iz primera 2.11


2.4. OPIS JEZIKA 23

2.4.2 Elementi gramatike


Da bi se denisala gramatika nekog jezika potrebni su sledei elementi:

1. Skup terminalnih simbola  Skup zavrnih simbola koji ulaze u sastav


rei jezika koji se denie.

2. Skup neterminalnih simbola  Skup pomonih simbola koji se koriste


za denisanje pravila za generisanje rei jezika ali ne ulaze u same rei
jezika.

3. Startni simbol  neterminalni simbol od kojeg zapoinje generisanje svih


rei jezika. Obino se ovim simbolom denie glavna sintaksna kategorija
koja je opisana jezikom. Na primer program u okviru programskih jezika.

4. Skup pravila oblika x y, kojima se stvaraju nizovi u procesu generi-


sanja rei jezika koji se opisuje.

Za oznaavanje elemenata ovih skupova obino koristimo sledeu notaciju:

Terminalni simboli :

 mala slova abecede: a, b, c, ...

 simboli operatora: , +, , ...

 specijalni znaci: (, ), <, >, ...


 cifre: 0, 1, ..., 9;
 boldirane rei kao to su id, if, then, i sl.
Neterminalni simboli :

 velika slova: A, B , C , ...

 S , ako se pojavljuje je obino startni simbol;


 rei napisane malim slovima italik: expr, nar, ili izmeu zagrada:
hstri, hnari
Pravila :

 x ::= y ili xy

2.4.3 Direkto izvoenje i redukcija


Ukoliko postoji re z = pxq i pravilo xy, onda se nakon primene ovog pravila
re z preslikava u re w = pyq i kaemo da se re w direktno izvodi od rei z.
To se obino oznaava sa

z w.
24 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA

Na osnovu pravila xy vai i da se y direktno izvodi od x. Takoe vai i da


se svaka re direktno izvodi od same sebe, odnosno x x.
Ovaj proces se moe posmatrati i u suprotnom smeru, odnosno kao direktna
redukcija rei w na re z. Isto tako se y direktno redukuje na x.
Ukoliko se x preslikava u y primenom vie smena, odnosno ukoliko postoji skup
smena oblika

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.

2.5 Formalne gramatike


Noam Chomsky je jo u svojim ranim radovima dao sledeu deniciju formalnih
gramatika:

Svaka formalna gramatika G se moe denisati kao torka


G = (Vn , Vt , S, P),
gde je Vn skup neterminalnih simbola, Vt skup terminalnih sibola, S startni
simbol i P skup smena denaisan na sledei nain:
x y, gde je x V Vn V y V ,
pri emu je S Vn , V = Vt Vn i Vt Vn = .
Uoimo da je uslov da re na levoj strani pravila mora da sadri bar jedan
neterminalni simbol.

Formalni jezik L denisan gramatikom G je skup rei izvedenih iz startnog


simbola gramatike koje se sastoje od terminalnih simbola:

w, w Vt }.
L(G) = {w | S

Primer 2.12 Formalna gramatika


Data je gramatika

G = ({S, A, B, C, D}, {a, b}, S, P),

gde je P sledei skup smena:

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

L(G) = {ww | w {a, b} }.

Primer izvoenja rei abab:


1 2 3 10 8 5 11
S
CD
aCaD
abCBaD abBaD
abaBD
ababD abab

Gramatika mora da bude redukovana. Redukovana gramatika je gramatika koja


ne sadri beskorisna pravila, kao ni beskonana pravila. Beskorisna pravila su
ona koje sadre simbole koji ne mogu da budu izvedeni iz startnog simbola
gramatike, a beskonana ona koja sadre neterminalne simbole koji nikada ne
mogu da budu ukinuti. To se formalno moe denisati preko sledeih pravila.

Za svaki neterminal A postoji izvoenje S



A , gde je S startni simbol
gramatike, a , V .
Za svaki neterminal A postoji izvoenje A

, gde je Vt .
Gramatika ne mora da bude jednoznana. Kod nejednoznanih gramatika za
jedan ulazni niz je mogue kreirati vei broj sintaksnih stabala.

Primer 2.13 Neredukovana gramatika


Gramatika G = ({W, X, Y, Z}, {a}, W, P} gde je P sledei skup pravila:

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:

Pravilo 2 je neupotrebljivo pravilo jer je Z beskonaan simbol, nikada


se ne ukida.

Pravilo 4 je neupotrebljivo iz istog razloga.

Pravilo 6 je neupotrebljivo zato to ne postoji izvoenje kojim se


generie neterminalni simbol Y.

Primer 2.14 Nejednoznana gramatika


Neka je data gramatika

G = ({Izraz}, {const, +, }, Izraz, P),

gde je P sledei skup pravila:

1. Izraz Izraz + Izraz


2. Izraz Izraz Izraz
3. Izraz const
U nastavku prikazana su dva sintaksna stabla koja odgovaraju izvoenju
izraza
const const + const.

izraz izraz

izraz * izraz izraz * izraz

const const
izraz + izraz izraz + izraz

const const const const


Kako stabla na slici nisu ista, gramatika G nije jednoznana.

Jednoznana gramatika ekvivalentna gramatici G moe da se denie na


sledei nain:

G1 = ({Izraz, Sabirak, Faktor}, {const, +, *}, Izraz, P),


2.6. HIERARHIJA GRAMATIKA PO OMSKOM 27

gde je P skup pravila:

1. Izraz Izraz + Sabirak


2. Izraz Sabirak
3. Sabirak Sabirak Faktor
4. Sabirak Faktor
5. Faktor const
U ovom sluaju za izraz const const + const, mogue je jednoznano
kreirati sintaksno stablo koje je prikazano u nastavku.

izraz

izraz + sabirak

sabirak faktor

const
sabirak * faktor

faktor const

const

2.6 Hierarhija gramatika po omskom


Jo u svojim ranim radovima, omski je identikovao etri tipa formalnih gra-
matika i jezika. Gramatike koje zadovoljavaju gore date opte uslove je nazvao
gramatikama tipa nula . Praktino, svaka formalna gramatika je gramatika tipa
nula. Ostali tipovi gramatika imaju stroe denisane uslove koje treba da za-
dovolje pravila. To znai da se tim tipovaima gramtika moe denisati ui skup
jezika ali se zato moe jednostavnije vriti analiza i prepoznavanje takvih jezika.

2.6.1 Gramatike tipa jedan ili konteksne gramatike


Gramatike tipa jedan su formalne gramatike koje pored optih uslova koji za-
dovoljavaju gramatike tipa nula imaju pravila xy koja zadovoljavaju sledei
uslov:
|x| |y|.
28 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA

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.

Primer 2.15 Gramatika tipa jedan  konteksna gramatika


Gramatika G = ({0, 1}, {S, A, B, C}, S, P) gde je P skup smena denisan
sa:

1. S 0B0
2. C0 100
3. B 0BC
4. B1
5. C1 1C
je konteksna gramatika tipa jedan.

Primer izvoenja rei jezika ove gramatike:

1 3 3 2
S
0B0
000BCC0
0000BCC0
0000BCC100
5 0 5

0000BC1C00
000BC11000
0000B1C1000
5 2 4

0000B11C000
0000B1110000
000011110000

2.6.2 Gramatike tipa dva ili beskonteksne gramtike


Gramatike tipa dva su gramatike kod kojih su pravila denisana tako da se na
levoj strani nalazi samo jedan neterminal. Neterminali se preslikavaju u rei.
Kako se neterminali prilikom izvoenja posmatraju izolovano od konteksta u
kome se nalaze, ove gramatike se nazivaju beskonteksnim gramatikama . Znai
smene kod ovih gramatika su oblika

A y, gde je A Vn i y V .

Za opis programskih jezika se obino koriste beskonteksne gramatike.


2.6. HIERARHIJA GRAMATIKA PO OMSKOM 29

Primer 2.16 Gramatika tipa dva  beskonteksna gramatika


Gramatika G denisana je na sledei nain:

G = ({E, A}, {(, ), +, -, *, /, id}, E, P),

gde je P skup smena:

E EAE | (E ) | -E | id
A+|||

Datom gramatikom denisan je jezik koji ine aritmetiki izrazi. Primer


rei koja pripada jeziku denisanom ovom gramatikom: id1 (id2 + id3
id4 ). Izvoenje ove rei bi bilo:

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 )

2.6.3 Gramatike tipa tri ili regularne gramatike


Gramatike tipa tri su formalne gramatike koje zadovoljavaju opte uslove ali su
ograniene na smene oblika:

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

Primer 2.17 Gramatika tipa tri  regularna gramatika


Gramatika G denisana je na sledei nain:

G = ({0, 1}, {A, B, C, D, E, F, G}, A, P),

pri emu je P skup smena:

A 0B | 1D B 0C | 1F C 0C | 1F |
D 1E | 0F E 1E | 0F | F 0G | 1G
G 0G | 1G |

Primer izvoenja:

A 0B 00C 000C 0001F 00011G 00011.

Dakle, re 00011 pripada jeziku denisanom datom gramatikom.

Gramatike tipa nula su najoptije i praktino su sinonim za algoritam. Sva


algoritamska preslikavanja se mogu opisati gramatikama tipa nula.

Gramatike tipa tri pokrivaju najui skup jezika ali je za ove jezike najjednostav-
nije reiti problem prepoznavanja. Prepoznaju se pomou konanih automata.

Izmeu jezika denisanih razliitim tipovima gramatika postoji sledea relacija

L(3) L(2) L(1) L(0).

2.6.4 Reenine forme


Svi nizovi (rei) koji nastaju u postupku generisanja jezika su reenine forme
tog jezika. Sve reenine forme jezika se redukuju na startni simbol.

Primer 2.18 Reenine forme


Gramatika G denisana je na sledei nain:

G = ({E, A}, {(, ), +, -, *, /, id}, E, P),

gde je P skup smena:

E EAE | (E ) | E | id A+|||/
2.7. NORMALNE FORME GRAMATIKA 31

Primeri reeninih formi:

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.

Primer 2.19 Fraza


Neka je data gramatika iz prethodnog primera.

Posmatrajmo izvoenje:

E EAE (E)AE ((E))AE ((E))AE (id)AE

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).

2.7 Normalne forme gramatika


Pod normalnim formama gramatika podrazumevamo standardni nain zadava-
nja gramatika odreenog tipa. To znai da se smene jedne gramatike mogu
prikazati na neki drugi nain a da se pri tome ne promeni jezik koji deniu.
Tako dolazimo i do pojma ekvivalentnih gramatika. Dve gramatike su ekviva-
lentne ako deniu isti jezik.

Nekada je potrebno smene gramatike predstaviti na ba odreeni nain da bi


se mogao primeniti neki odreeni postupak analize. U te svrhe, za odreene
tipove gramatika, denisane su razliite normalne forme.

2.7.1 Normalne forme za konteksne gramatike


Ako je G konteksna gramatika, onda postoji njoj ekvivalentna konteksna gra-
matika G1 u kojoj je svaka smena oblika:

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.

2.7.2 Normalne forme za beskonteksne gramatike


Svaka beskonteksna gramatika G ima ekvivalentnu gramatiku G1 u kojoj svaka
smena ima jedan od sledeih oblika:

S , A B C, Aa A, B Vn , a Vt .

Ova normalna forma se naziva i Normalna forma omskog.

Svaka beskonteksna gramatika G ima ekvivalentnu gramatiku G1 u kojoj svaka


smena ima jedan od sledeih oblika:

S , A a, A a B, A aBC A, B, C Vn , a Vt .

2.8 Pitanja
1. Denisati pojam azbuke.

2. Dati formalnu deniciju pojma rei.

3. Navesti osnovne delove rei.

4. Navesti osnovne operacije koje se mogu izvravati nad reima.

5. Dati formalnu deniciju pojma jezik.

6. Dati primere jezika denisanih nad azbukom V = {a, b, c, d, 0, 1}.


7. Navesti osnovne operacije nad jezicima.

8. ta su to formalne gramatike i kako se deniu?

9. Navesti osnovne tipove gramatika po omskom.

10. ta su to konteksne, a ta beskonteksne gramatike?

11. ta su to normalne forme gramatika?

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 .

4. Gramatika G je zadata sledeim skupom smena:

A cifra B | +C | C
B cifra B | , D
C cifra B
D cifra D |

Kom tipu pripada ova gramatika? Dati izvoenje rei

+ cifra cifra , cifra cifra


koja pripada jeziku opisanom datom gramatikom. Prikazati sintaksno
stablo koje odgovara datom izvoenju.

5. Gramatika G je zadata sledeim skupom smena:

S S+I |I
I (S ) | fun(S ) | id

Odrediti tip gramatike i dati primere nekih reeninih formi i fraza za


neterminal S.
34 GLAVA 2. ELEMENTI TEORIJE FORMALNIH JEZIKA
Glava 3

Automati kao ureaji za


prepoznavanje jezika

Problem prepoznavanja jezika , odnosno utvrivanja da li zadata re pripada


jeziku opisanim odreenom gramatikom, reava se automatima kao ureajima
za prepoznavanje jezika. U ovom poglavlju bie rei o osnovnim karakteristi-
kama etri osnovna tipa automata i bie razmatrana njihova veza sa formalnim
gramatikama i jezicima koje mogu da prepoznaju.

3.1 Opti model automata


Generalno gledano, svi automati se mogu predstaviti emom datom na slici 3.1.

ulazna traka
# a1 a2 ai an #

ulazna glava

funkcionalni organ

radna glava

beskonana memorija

Slika 3.1: ema automata kao ureaja za prepoznavanje jezika

35
36 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA

Niz simbola (re) koji se prepoznaje zapisan je na ulaznoj traci. Po ulaznoj


traci se kree ulazna glava koja u jednom trenutku ita jedan simbol sa trake.
Ova glava se u optem sluaju moe kretati i napred i nazad (desno i levo).

Funkcionalni organ automata je njegov najznaajniji deo. U zavisnosti od toga


kako je opisan jezik koji se prepoznaje, funkcionalni organ moe da se nae u
nekom od konanog broja razliitih stanja. Funkcionalni organ belei predi-
storiju prepoznavanja i za to koristi memoriju koja je u ovom optem modelu
predstavljena kao beskonana memorija. Automat sa beskonanom memorijom
nije praktino izvodljiv tako da se realni automati razlikuju od ovog modela po
tome to koriste neki odreeni tip memorije.

Proces prepoznavanja rei zapoinje tako to se ulazna glava pozicionira na


poetni simbol rei koja se prepoznaje (levi graninik #), a funkcionalni organ
se nalazi u svom poetnom stanju. U svakom koraku prepoznavanja, u zavisnosti
od toga gde je pozicionirana ulazna glava (koji simbol ita), stanja funkcionalnog
organa, kao i simbola u radnoj memoriji koji ita radna glava, dogaaju se
sledee promene u automatu:

menja se stanje funkcionalnog organa,

u radnu memoriju se upisuje jedan ili vie simbola,

radna glava se pomera napred, nazad ili ostaje na poziciji na kojoj se


nalazi,

ulazna glava se pomera za jedno mesto napred ili nazad ili ostaje na poziciji
na kojoj se nalazi.

Proces prepoznavanja rei je uspeno zavren u trenutku kada se ulazna glava


pozicionira na krajnji simbol rei koja se prepoznaje (desni graninik #) i funk-
cionalni organ se nae u jednom od svojih zavrnih stanja.

U optem sluaju automati se mogu podeliti na etiri klase:

2N  dvosmerni nedeterministiki,

1N  jednosmerni nedeterministiki,

2D  dvosmerni deterministiki i

1D  jednosmerni deterministiki.

Podela na jednosmerne i dvosmerne izvrena je na osnovu mogunosti pomera-


nja ulazne glave. Ako se ulazna glava kree samo napred onda su to jednosmerni
automati, a u sluaju kada je dozvoljeno i vraanje glave unatrag onda su to
dvosmerni automati . Podela na deterministike i nedeterministike izvrena je
u odnosu na preslikavanje stanja funkcionalnog organa koje se vri u toku pre-
poznavanja. Ukoliko je stanje u koje prelazi automat, za odreeni ulazni simbol
i odreeno zateeno stanje, jednoznano denisano onda je to deterministiki
automat. Ukoliko je ovo preslikavanje vieznano onda je to nedeterministiki
automat .
3.2. TJURINGOVA MAINA 37

Postoje etri osnovna tipa automata, to donekle odgovara podeli formalnih


gramatika i jezika na tipove. Ova etri tipa automata su:

Tjuringova maina,

linearno ogranieni automat,

magacinski automat i

konani automat.

Osnovna razlika izmeu ovih tipova je u organizaciji memorije koja se koristi za


beleenje predistorije prepoznavanja, to uslovljava i tipove jezika koji se mogu
prepoznavati odreenim tipom automata.

3.2 Tjuringova maina


Slika 3.2 prikazuje emu Tjutingove maine kao osnovnog automata za prepo-
znavanje jezika. Za razliku od opteg modela automata Tjuringova maina ima
radnu memoriju u vidu beskonane trake.

ulazna traka
# a1 a2 ai an #

ulazna glava

funkcionalni organ

radna memorija
A1 A2 Ai An

Slika 3.2: Model Tjuringove maine

2N Tjuringova maina se moe opisati torkom

Tm = (Q, V, S, P, q0 , b, F),

gde je:

Q  skup stanja operativnog organa,

V  skup simbola na ulaznoj traci,

S  skup simbola na radnoj traci,

F  skup zavrnih, krajnjih stanja (podskup skupa Q),


q 0  poetno stanje operativnog organa,
38 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA

b  oznaka za prazno slovo,

P  preslikavanje denisano sa

Q (V #) S {Q (S \ {b}) {1, 0, +1} {1, 0, +1}} .

Ako je (qj , B, d1 , d2 ) P (qi , a, A), gde je qj , qi Q, a V, A S i d1 , d2


{1, 0, 1}, odnosno ako ulazna glava ita simbol a, funkcionalni organ se nalazi
u stanju qi , a radna glava iznad simbola A, automat e prei u stanje qj , na
radnu traku e upisti simbol B i izvrie se pomeranje ulazne glave i radne glave
u skladu sa vrednostima d1 i d2 . Pri tome vai sledea notacija: ako je di = 0,
nema pomeranja odgovarajue glave; za di = 1 glava se pomera za jedno mesto
napred (desno), a za di = 1, glava se pomera za jedno mesto nazad (levo).

Maina zapoinje prepoznavanje tako to je ulazna glava pozicionirana na po-


etnom graninom simbolu, funkcionalni organ se nalazi u poetnom stanju i
radna traka je prazna. Prepoznavanje rei se zavrava uspeno ako se automat
nae u nekom od zavrnih stanja (element skupa F) u trenutku kada je ulazna
glava na krajnjem graninom simbolu #.
Tjuringova maina je deterministika ako se svaki trojka (q, a, X) gde je q Q,
a V i X S, preslikava u najvie jedan element (p, Y, d1 , d2 ), pri emu je
p Q, Y S i d1 , d2 {1, 0, 1}.
Dokazano je da su sve etri klase Tjuringovih maina (2N, 1N, 2D, 1D) me-
usobno ekvivalentne i svaka od njih prepoznaje jezike tipa nula. To u sutini
znai da je za prepoznavanje bilo kog jezika tipa nula mogue denisati bilo koji
tip Tjuringove maine. Odnosno, ako je mogue denisati jedan tip Tjuringove
maine, onda je mogue denisati i ekvivalentne maine ostalih tipova. Jedini
problem je to to model Tjuringove maine podrazumeva beskonanu memoriju,
to u praksi praktino nije izvodljivo. Zbog toga Tjuringova maina ostaje samo
teorijski model, a u praksi se koriste automati sa konanim memorijama, to kao
posledicu ima ogranienje jezika koji se mogu prepoznavati.

Moe se rei da je pojam Tjuringove maine ekvivalent pojmovima algoritam


i jezici tipa nula. To znai da se sva algoritamska preslikavanja mogu opisati
jezicima tipa nula, pri emu je mogue i denisati odgovarajue Tjuringove
maine za prpoznavanje takvih jezika.

3.3 Linearno ogranien automat


Linearno ogranieni automati su u sutini Tjuringove maine sa konanom tra-
kom kao radnom memorijom. Naime, 2N Tjuringova maina kod koje moe da
se odredi konstanta k takva da je duina rei koja se upisuje na radnu traku naj-
vie k puta vea od duine rei koja se prepoznaje, naziva se linearno ogranieni
automat.
3.4. MAGACINSKI AUTOMAT 39

Odnosno, ako se prepoznaje re w V , gde je |w| = n, na radnu traku se


upisuje re duine r, pri emu je r n k.
Posledica ovog ogranienja je da linerano ogranieni automati ne prepoznaju sve
jezike tipa nula. Odnosno, postoje jezici tipa nula za koje nije mogue denisati
linearno ogranieni automat. Naime, dokazana su sledea tvrenja:

Klase 2N i 1N linearno ogranienih automata su meusobno ekvivalentne


i svaka od njih prepoznaje jezike tipa jedan. Drugim reima, za svaki
jezik tipa jedan moe se denisati nedeterministiki linearno ogranieni
automat koji ga prepoznaje.

Klase 2D i 1D linearno ogranienih automatu su meusobno ekvivalentne.


To znai da se za svaki 2D linearno ogranieni automat moe denisati
ekvivalentan 1D linearno ogranieni automat.

Ekvivalentnost 2N i 2D linearno ogranienih automata do sada nije doka-


zana.

Svaka klasa linearno ogranienih automata ne prepoznaje sve jezike tipa


jedan.

3.4 Magacinski automat


Magacinski automat kao radnu memoriju koristi memoriju organizovanu u vidu
magacina. ema strukture ovog automata data je na slici 3.3.

2N Magacinski automat je denisan torkom Ma = (Q, V, S, P, q0 , Z0 , F) gde je:


Q  skup stanja operativnog organa,

V  skup simbola na ulaznoj traci,

S  skup magacinskih simbola,

F  skup zavrnih, krajnjih stanja (podskup skupa Q),


q 0  poetno stanje operativnog organa,

Z 0  poetni simbol na vrhu magacina,

P  preslikavanje denisano sa:

Q (V #) S {Q S {1, 0, +1}}.

Za opis konguracije magacinskog automata u odreenom trenutku obino se


koristi sledea struktura:

(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

Slika 3.3: Magacinski automat

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.

Ako je (p, r, d) P (q, ai , Xm ), gde su p, q Q, ai V , r S i d {1, 0, 1},


u automatu se dogaa sledee preslikavanje:

(q, #a1 a2 ai #, X1 X2 Xm ) 7
(p, #a1 a2 ai + d an #, X1 X2 Xm1 , r)

Napomenimo da se u magacin upisuje re od jednog slova, vie slova ili se ne


upisuje nita kada je r = .

Primer 3.1 Magacinski automat


3.4. MAGACINSKI AUTOMAT 41

Neka je data gramatika G = ({0, 1, a}, {S}, S, P), sa skupom smena P:

S 0S1 S a.

Prepoznavanje jezika denisanog gramatikom G moe da se izvri maga-


cinskim automatom koji je opisan sa:

Ma = (Q, V, S, P, q0 , Z0 , F),

gde je:

Q = {q0 , q1 }, V = {0, 1, a}, S = {A, B},


Z0 = A, F = q1 ;

a skup smena P ima sledee elemente:

(q0 , #, A) (q0 , A), (q0 , 0, A) (q0 , BA),


(q0 , a, A) (q1, ), (q1 , 1, B) (q1 , ).

Poetno stanje automata je q0 , a kraj preslikavanja denisan je sa (q1 , #, ).


Pokazaemo prepoznavanje dve karakteristine rei jezika denisanog gra-
matikom G.
1. Prepoznavanje rei #000a111:

(q0 , #000a111#, A) (q0 , #000a111#, A)


(q0 , #000a111#, BA)
(q0 , #000a111#, BBA)
(q0 , #000a111#, BBBA)
(q1 , #000a111#, BBB)
(q1 , #000a111#, BB)
(q1 , #000a111#, B)
(q1 , #000a111#, ).

2. Prepoznavanje rei #a#:

(q0 , #a#, A) (q0 , #a#, A) (q1 , #a#, ).

Magacinski automati su pogodni za prepoznavanje beskonteksnih jezika. Doka-


zana su sledea tvrenja:

1N magacinskim automatima prepoznaju se samo beskonteksni jezici tipa


dva.
42 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA

2N magacinskim automatima mogu se prepoznavati svi beskontesni i neki


(ali ne svi) konteksni jezici.

Postoje beskonteksni jezici koji se ne mogu prepoznati 1D magacinskim


automatima.

2D magacinski automati pored beskonteksnih mogu da prepoznaju i neke


konteksne jezike.

Magacinski automati se koriste u sintaksnoj analizi programskih jezika.

3.5 Konani automati


Konani automati su ureaji za prepoznavanje regularnih jezika. Za razliku od
drugih tipova nemaju radnu memoriju ve se predistorija preslikavanja pamti
samo preko promene stanja funkcionalnog organa (slika 3.4).

Kod dvosmernih kona;nih automata, na osnovu stanja operativnog organa i


simbola koji ita ulazna glava, menja se stanje automata i ulazna glava pomera
za jedno mesto ulevo, udesno ili ostaje na svom mestu. Kod jednosmernih,
menja se samo trenutno stanje automata.

ulazna traka
# a1 a2 ai an #

ulazna glava

funkcionalni organ

Slika 3.4: ema konanog automata

Jednosmeran deterministiki konaan automat je opisan torkom Ka = (Q, V, P, q0 , F),


gde je:

Q  skup stanja operativnog organa,

V  skup simbola na ulaznoj traci,

F  skup zavrnih, krajnjih stanja (podskup skupa Q),


q 0  poetno stanje operativnog organa,

P  preslikavanje pravilima oblika: Q {V #} Q.


Za ulazni niz w V kaemo da je prepoznat automatom ako automat prevodi
iz poetnog u neko od njegovih krajnjih stanja, odnosno ako je P(q0 , w) F.
3.5. KONANI AUTOMATI 43

Skup svih rei koje prepoznaje Ka nazivamo regularnim i oznaavaemo ih sa


T(Ka). Vai:
T(Ka) = {x | P(q0 , x) F}.

Primer 3.2 Konani automat


Neka je Ka = (Q, V, P, q0 , F), denisan na sledei nain:

Q = {q0 , q1 , q2 , q3 },
V = {0, 1},
F = {q0 },

a skup P ima sledee elemente:

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 .

Moe se pokazati da ovaj konani automat prepoznaje rei koje se sastoje


od parnog broja jedinica i parnog broja nula.

Za predstavljanje automata se koriste grafovi, pri emu vorovi grafa odgova-


raju stanjima automata, a potezi preslikavanjima. Na Slici 3.4 predstavljen je
graf koji odgovara automatu iz primera. Poetno stanje automata je oznaeno
strelicom, a krajnje stanje sa dva koncentrina kruga.

Kako se preslikavanje P (qi , a) = qj moe tumaiti da se stanje qi automata


za ulazno slovo a preslikava u stanje qj , svako takvo preslikavanje se na grafu
predstavlja odlaznim potegom od stanja qi do stanja qj na kome je oznaka a.
44 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA

Primer 3.3 Graf automata


Graf automata iz primera 3.2 prikazan je na sledeoj slici.

start q0 q1
1

0 0 0 0

q2 q3
1

3.5.1 Odreivanje jezika koji se prepoznaje datim kona-


nim automatom
Jezik koji prepoznaje konani automat Ka moe da se odredi analitiki kao
skup svih rei koje poetno stanje preslikavaju u krajnja stanja (kao dogaaji
krajnjih stanja u funkciji poetnog stanja). Poinje se tako to se za svako od
stanja automata (svaki vor grafa automata) piu jednaine stanja. Za svaki
vor grafa automata, ove jednaine su odreene dolaznim potezima u taj vor.
Ako postoji preslikavanje P (qi , a) qj , znai u grafu automata postoji poteg
iz vora qi ka voru qj za ulazno slovo a. To se predstavlja jednainom stanja

qj = qi a.

Da bi se odredio jezik koji prepoznaje automat potrebno za svako od zavrnih


stanja odrediti skup rei koje poetno stanje prevode u to stanje, odnosno rea-
vanjem jednaina stanja oderediti

qkraj = f (qpo ).
3.5. KONANI AUTOMATI 45

Pri reavanju jednaina stanja za njihovo transformisanje moe se koristiti sle-


dei model:

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

Primer 3.4 Odreivanje jezika


Zadatak je da se za automat predstavljen grafom sa sledee slike odredi
jezik koji prepoznaje.

1
start q0 q1 1

0
1

q2 q3 0

Postavljamo jednaine stanja za svako od stanja automata:

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)

3.5.2 Veza izmeu konanih automata i gramatika tipa tri


Pokazali smo da se jednostavo moe odrediti jezik koji se prepoznaje zada-
tim konanim automatom. Vai i obrnuto, za svaki jezik denisan gramatikom
tipa tri moe se odrediti konani automat koji ga prepoznaje. Pravila koja se
primenjuju za ova preslikavanja data su u tabeli 3.1. Svskom neterminalnom
simbolu gramatike odgovara jedno stanje automata, pri emu startnom simbolu
odgovara poetno stanje. Skupu terminalnih simbola gramatike odgovara skup
ulaznih simbola automata a svakom pravilu gramatike odgovara preslikavanje u
automatu.

Tabela 3.1: Veze izmeu gramatika tipa tri i konanih automata

Automat Gramatika

skup stanja Q skup neterminalnih simbola Vn


ulazna azbuka V skup terminalnih simbola Vt
poetno stanje q0 startni simbol

skup prslikavanja P skup pravila P


a
A B a aB

a
A B a aB i b

B b b bB

B b b bB i B ili
b bB i B b

Sledei primeri ilustruju primenu ovih pravila.


3.5. KONANI AUTOMATI 47

Primer 3.5 Preslikavanje gramatike u konani automat


Denisati konani automat za prepoznavanje oznaenih celih brojeva. Ozna-
eni ceo broj denisan je sledeom gramatikom:

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
-

Primer 3.6 Preslikavanje grafa u gramatiku


Na osnovu grafa automata prikazanog u primeru 3.3 moe se odrediti sle-
dea gramatika koja opisuje jezik koji se prepoznaje ovim automatom.

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

Primer 3.7 Preslikavanje gramatike u graf automata i odreivanje jezika


Odrediti kom tipu pripada i koji jezik prepoznaje gramatika zadata slede-
48 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA

im skupom smena:

A 0B | 1D, B 0C | 1F, C 0C | 1F | ,
D 1E | 0F, E 1E | 0F, F 0G | 1G,
G 0G | 1G | .

Za svaku smenu gramatike vai da je duina rei na levoj strani smene


manja ili jednaka duini rei na desnoj strani  zadovoljen je uslov da
gramatika moe biti tipa 1.

Na levoj strani svih smena je neterminalni simbol  gramatika moe biti


tipa 2.

Sve smene su oblika X a, ili X aY ili X  gramatika je tipa 3.

Kako je data gramatika tipa 3, jezik koji je denisan gramatikom se moe


predstaviti u obliku regularnog izraza. Da bismo odredili regularni izraz
jezika, crtamo najpre graf konanog automata koji taj jezik prepoznaje.
Ovaj graf dat je na slici na kraju primera.

Jednaine stanja automata su:

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)

Treba izraziti sva zavrna stanja u funkciji ulaznog stanja.

Iz jednaina (1) i (2) sledi:

B = A0. (8)

Iz (3) i (8) imamo C = A00 + C0, tj.

C = A000 . (9)

Iz (1) i (4) dobijamo:

D = A1. (10)
3.6. REGULARNI IZRAZI 49

Iz (5) i (10) imamo E = A11 + E1, tj.

E = A111 . (11)

Zamenom (8), (9) i (11) u (6) dobija se:

F = A01 + A000 1 + A111 0


(12)
= A(01 + 000 1 + 111 0).

Iz (7) sledi:
G = F (0 + 1) + G(0 + 1)
(13)
= F (0 + 1)(0 + 1) .

Zamenom (12) u (13) dobijamo:

G = A(01 + 000 1 + 111 0)(0 + 1)(0 + 1) .

Konano, jezik koji je denisan gramatikom je unija jezika koje prepoznaju


stanja C, F i G:

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

3.6 Regularni izrazi


Jezici tipa tri koji se prepoznaju konanim automatima su regularni jezici zato
to se mogu opisati regularnim izrazima . Ovde emo posvetiti malo vie panje
pojmu regularni izrazi. Oni se mogu posmatrati i kao meta jezici za predstavlja-
nje formalnih jezika. Regularni izrazi u sutini deniu skup rei jezika. Sami
regularni izrazi su nizovi formirani od slova neke azbuke V i skupa specijalnih
simbola. Regularni izraz skraeno opisuje skup rei jezika denisanog nad azbu-
50 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA

kom V. Postoje posebna pravila kako se vri tumaenje (denotacija) regularnog


izraza i generisanje skupa rei jezika koji je opisan regularnim izrazom.

Regularni izraz nad azbukom V denie se sledeim skupom pravila:

1. (prazan skup) je regularni izraz.

2. je regularni izraz.

3. Ako je a V, onda je a regularni izraz.

4. Ako su r1 i r2 regularni izrazi, onda su i (r1 | r2 ) i (r1 r2 ) regularni


izrazi.

5. Ako je r regularni izraz onda je i r takoe regularni izraz.

6. Nema drugih regularnih izraza nad azbukom V.


Napomena: U literaturi se esto se umesto operatora | koristi +, a operator
se izostavlja.

Primer 3.8 Regularni izrazi


Neka je V = {a, b, c, . . . , x, y, z}. Sledei nizovi su regularni izrazi:

, a, ((c a) t),

((m e) (o) w), (a | (e | (i | (o | u)))), (a | (e | (i | (o | u)))) .

Kada su regularni izrazi denisani, treba da se zna njihovo tumaenje, odno-


sno preslikavanje (denotacija) u skup rei. Za svaki regularni izraz r, njegova
denotacija, oznaena sa krk, je skup rei denasan sa:

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 .

Primer 3.9 Regularni izrazi i jezici


U sledeoj tabeli dato je tumaenje regularnih izraza iz primera 3.8.
3.6. REGULARNI IZRAZI 51

Regularni izraz Denotacija


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

Regularni izrazi ine algebru, sa svojstvima operacija prikazanim u tabeli 3.2.

Tabela 3.2: Algebarska svojstva regularnih izraza

Aksiom Opis

r|s=s|r operacija | je komutativna

r(s | t) = (r | s) | t operacija | je asocijativna

s(st) = (rs)t nadovezivanje je asocijativna operacija

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.

Regularni izrazi su veoma korisni za formalno i koncizno denisanje jezika. Kada


je jezik konaan mogue je nabrojati sve rei koje sadri, ali u sluaju beskona-
nih jezika to postaje problem. Zbog toga se regularni izrazi i koriste u razliitim
disciplinama kao sredstvo za opis kompleksnih jezika. Na alost, ne mogu se svi
formalni jezici opisati regularnim izrazima. To je mogue samo u sluaju jezika
denisanih gramatikama tipa tri, zbog ega se oni i nazivaju regularnim. Sle-
dei primer ilustruje mo regularnih izraza da deniu beskonane i kompleksne
jezike.
52 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA

Primer 3.10 Jezici denisani regularnim izrazima


Neka je data azbuka V koja sadri sva slova engleske abecede

V = {a, b, c, . . . , x, y, z}.

Regularnim izrazom V denisan je skup svih rei koje se mogu na-


praviti od slova skupa V.
Skup svih rei koje sadre samoglasnike moe se denisati regularnim
izrazom V (a + e + i + o + u) V .
Skup svih rei koje poinju sa non je: (non) V .
Skup svih rei koje se zavravaju na tion ili sion denisan izrazom:
V (t + s) (ion).

Regularni izrazi ne mogu da se koriste za opis izbalansiranih ili umetnutih kon-


strukcija. Na primer, izrazi sa zagradama u kojima se uvek zagrade javljaju u
paru ne mogu da budu opisani regularnim gramatikama, ali se zato jednostavno
opisuju beskontesnim gramatikama; na primer, pravilom E (E).

3.7 Preslikavanje regularnih izraza u konane au-


tomate
Za svaki regularni izraz se moe denisati konani automat koji ga prepoznaje.
Pri tome vae sledea pravila:

Regularni izraz r = se prepoznaje automatom datim na slici 3.5, gde je A


poetno stanje automata a Z zavrno stanje automata.


start A Z

Slika 3.5: Automat za regularni izraz r =

Regularnom izrazu r=a odgovara automat sa slike 3.6.

a
start A Z

Slika 3.6: Automat za regularni izraz r = a

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

Automat za regularni izraz s r, gde su s i r regularni izrazi, realizuje se kao


redna veza automata koji prepoznaje izraz s i automata koji prepoznaje izraz r
(slika 3.8).

Ka(s) Ka(r)

start A Z

Slika 3.8: Automat za regularni izraz r s

Regularni izraz (s) se prepoznaje automatom sa petljom koja spaja zavrno i


poetno stanje stanje podautomata za regularni izraz s, kao to je prikazano na
slici 3.9.


start A Z

Slika 3.9: Automat za regularni izraz (s)

Kako se u prethodnim primerima automata pojavljuje puno potega oznaenih


sa , sledei primer ilustruje njihovo tumaenje i znaaj.
54 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA

Primer 3.11 -grane u automatu


Automat sa sledee slike prepoznaje jezik {do, undo, undone, done}.

q0 u q1 n q2 d q3
start

q6 q5 q4
n n

Uoimo da i u ovom sluaju zamenjuje praznu re. Na primer, kada


automat prepoznaje re undo, iz poetnog stanja dolazi u stanje q4 i prazna
re ga iz stanja q4 prevodi u zavrno stanje q6 .

Primenom navedenih pravila moe se generisati konani automat za bilo koji


regularni izraz.

Primer 3.12 Regularni izrazi u konani automat


Oznaeni realni brojevi u eksponencijalnom zapisu denisani su sledeim
regularnim izrazom:

(+ | ) cifra cifra . cifra (E | e) (+ | ) cifra cifra .

Za prepoznavanje ovih brojeva moe se koristiti automat sa sledee slike.

cifra cifra

+
cifra .
start A B C D

e E

cifra F E
cifra

Primer 3.13 Primeri konanih automata


U sledeoj tabeli su dati grafovi konanih automata koji prepoznaju regu-
larne izraze iz primera 3.8.
3.8. PITANJA 55

Regularni izraz Graf automata

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.

2. Kako je denisana Tjuringova maina?

3. Koje jezike prepoznaju automati tipa Tjuringove maine?

4. ta su to linearno ogranieni automati i koje jezike prepoznaju?

5. Kako je denisam magacinski automat i koje jezike prepoznaje?

6. Dati deniciju konanih automata.

7. Objasniti vezu izmeu konanih automata i jezika tipa tri.

8. Dati deniciju regularnih izraza. Navesti nekoliko primera regularnih iz-


raza.

9. ta je to denotacija regularnih izraza? Dati primere za denotaciju.

10. Pokazati kako se osnovni regularni izrazi preslikavaju u automate.

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.

Odrediti tip gramatike i automat koji prepoznaje rei jezika denisanog


datom gramatikom. Pokazati proces prepoznavanja rei #aaabbcddddd#.
2. Gramatika G zadata je sledeim skupom smena:

A 0C | 1B, B 0B | 1C,
C 0A | 1D, D 1D | .

Denisati mainu za prepoznavanje rei jezika ove gramatike i odrediti


jezik koji je denisan ovom gramatikom.

3. Gramatika G zadata je sledeim skupom smena:

A cifra B | +C | C, B cifra B | .D,


C cifra B, D cifra D | .

(a) Denisati mainu za prepoznavanje rei jezika ove gramatike.

(b) Odrediti jezik ove gramatike.

4. Zadata je gramatika tipa tri sledeim skupom smena:

A 0B | 1D, B 0C | 1F,
C 0C | 1F | , D 1E | 0F,
E 1E | 0F | , F 0G | 1G,
G 0G | 1G | .

Nacrtati graf odgovarajueg konanog automata i odrediti regularni izraz


jezika ove gramatike.

5. Gramatika G zadata je sledeim skupom smena:

A 0D | 1A, B 0A | 1C, C 0A | 1F,


D 0B | 1C, E 0B | 1C | , F 0E | 1A | .

(a) Denisati mainu za prepoznavanje rei jezika odreenog gramatikom


G.
(b) Odrediti jezik koji je denisan gramatikom G.
6. Denisati regularne izraze za jezike denisane nad azbukom

V = {a, b, c, . . . , x, y, z, 0, 1, . . . , 9}

koje ine sledei skupovi rei:

(a) Sve rei koje poinju na m i zavravaju se na ov.


(b) Sve rei koje poinju ciframa.
3.9. ZADACI 57

(c) Sve rei koje poinju slovom i zavravaju se jednom cifrom.

7. Izvriti denotaciju sledeih regularnih izraza denisanih nad azbukom

V = {0, 1} :

(a) (0 + 1)(0) (1)


(b) 0(0 + 1) 1
(c) 0 10 .
8. Nacrtati grafove automata za regularne izraze iz prethodnog zadatka.
58 GLAVA 3. AUTOMATI KAO UREAJI ZA PREPOZNAVANJE JEZIKA
Glava 4

Leksiki analizator

Leksikim analizatorom se realizuje faza leksike analize u procesu prevoenja


jezika. U kodu programa napisanog na programskom jeziku sa kog se vr[i prevo-
enje se identikuju leksike celine (lekseme) koje imaju neki sintaksni smisao,
transformiu se u simbole (tokene) i prosleuju se sintaksnom analizatoru.

4.1 Namena leksikog analizatora


Postoji vie razloga zbog kojih se leksiki analizator izdvaja od sintaksnog ana-
lizatora. Moda najvaniji su:

Jednostavnija realizacija.

Tako se dobija mogunost da se tehnike za sintaksnu analizu razvijaju


nezavisno od jezika. Ulaz u sintaksni analizator je niz simbola denisan
odreenim formalnim jezikom, nije zavisan od programskog jezika koji se
prevodi.

Prenosivost kompilatora. U fazi leksike analize eliminiu se svi mainski


zavisni elementi i generie mainski nezavisna sekvenca simbola koja se
prosleuje sintaksnom analizatoru.

Poveanje ekasnosti kompilatora. Posebnim tehnikama baferisanja, koje


se koriste u realizaciji leksikog analizatora, doprinosi se njegovoj eka-
snosti a time i ekasnosti kompilatora.

Sprega leksikog i sintaksnog analizatora prikazana ja na slici 4.1.

Pored navedene osnovne uloge, leksiki analizator obavlja jo neke zadatke:

Izbacuje iz ulaznog koda delove koji nisu znaajni za sintaksnu analizu:


komentare, praznine (blanko znake), tab i newline simbole.

59
60 GLAVA 4. LEKSIKI ANALIZATOR

izvorni program token


leksiki sintaksni
analizator get next token analizator

tabela
simbola

Slika 4.1: Veza izmeu leksikog i sintaksnog analizatora

Usklauje listing graka sa ulaznim kodom. Na primer, vodi rauna o


broju newline simbola, to se koristi kod referenciranja na grke.

esto se leksiki analizator realizuje tako da su njegove funkcije razdvojene u


dve faze:

ulazna konverzija  odgovorna za transformaciju ulaznog koda, izbacivanje


praznina i sl;

leksika anliza  odgovorna za generisanje tokena.

U okviru ulazne konverzije vri se transformisanje i pojednostavljivanje ulaznog


koda i njegovo prilagoavanje ulaznom formatu leksikog analizatora. Danas se
neke funkcije ulazne konverzije vre ve u fazi pisanja koda, odnosno prenete
su editoru, programu za pripremu koda. Mnogi editori transformiu kod u neki
standardni format pogodan za kasnije pregledanje od strane programera, ali ga
i prilagoavaju leksikom analizatoru. Na primer, transformiu identikatore,
dodaju ili briu neko slovo, mala slova zamenjuju velikim i obrnuto, kako bi
identikatori bili napisani uniformno.

Sam postupak leksike analize objasniemo na sledeem primeru. Leksiki ana-


lizator vidi ulazni kod (napisan na nekom programskom jeziku) kao niz slova.
Na primer, ako u programu imamo:

if (i == j)
z = 0;
else
z = 1;
leksiki analizator e ovo videti kao sledei niz slova:

\tif(i == j)\n\t\tz = 0;\n\telse\n\t\tz = 1;


gde \t oznaava tabulator a \n novu liniju.

Njegov zadatak je da iz ovog niza izdvoji lekseme i predstavi ih simbolima,


tokenima. Sintaksnom analizatoru prosleuje niz tokena. Kao to su u srp-
skom jeziku leksike celine imenica, glagol, pridev, u programskim jezicima su
to identikator, kljuna re, konstanta, i sl.
4.1. NAMENA LEKSIKOG ANALIZATORA 61

4.1.1 Tokeni
Jedan token u sutini predstavlja skup nizova (rei). Na primer:

identikator: niz koji poinje slovom a moe da sadri slova i cifre;

celobrojna konstanta: neprazan niz cifara, sa ili bez znaka;

kljuna re: else, if, begin, itd;


Tokenima se identikuju leksike celine koje su od interesa za sintaksni anali-
zator. Za sintaksnu analizu nisu bitni razmaci, znaci za nove linije, tabulatori
i komentari. U nekim jezicima ak i neke rei same naredbe nisu bitne. Na
primer, u programskom jeziku COBOL naredba moe da se sastoji od rei je-
zika koje su bitne i rei koje nisu bitne za prepoznavanje naredbe, ve se koriste
samo da bi zapis naredbe bio jasniji.

Za analizu, takoe, nije bitno da li se na odreenom mestu nalazi identikator


koji se zove alfa ili beta, ve je jedino to da je na odreenom mestu iden-
tikator, zbog toga se sintaksnom analizatoru preko tokena prenosi samo ta
informacija.

Izbor tokena koji e se koristiti zavisi od programskog jezika na koji se odnosi


kompilator, kao i od toga kako je projektovan sintaksni analizator. Na primer,
u prethodno datom nizu

\tif (i == j)\n\t\tz = 0;\n\telse\n\t\tz = 1;


bie izdvojeni sledei tokeni: kljuna re if, otvorena zagrada, identikator, rela-
cija, identikator, zatvorena zagrada, identikator, dodela, celobrojna konstanta,
graninik, kljuna re else, identikator, dodela, celobrojna konstanta, graninik.
Denisanje tokena moe bitno da utie na kvalitet samog prevoenja a time i
na kvalitet jezika. To se moe ilustrovati nekim karakteristinim primerima iz
istorije programskih jezika.

Na primer, prilikom realizacije kompilatora za programski jezik FORTRAN uz-


imano je da se blanko znaci ignoriu. To znai da se nizovi V AR1 i VA R1
tretiraju kao isti identikator VAR1. Meutim, ovo pravilo je dovelo do uvene
greke koja se potkrala u programu za upravljanje letilicom iz programa Geminy,
gde je umesto naredbe

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:

U programskom jeziku PL-I kljune rei nisu bile zatiene pa su mogle da


se koriate i kao identikatori. Nije teko uoiti kakvu zabunu leksikom
analizatoru unosi sledei deo koda:

IF ELSE THEN THEN = ELSE; ELSE ELSE = THEN


Takoe, u primeru

DECLARE (ARG1, ..., ARGN)


nije lako sve do zatvorene zagrade zakljuiti da li je DECLARE referenca
na viedimenzionalno polje ili naredba za opis. Ovo je zahtevalo da se
prilikom realizacije leksikog analizatora koristi viestruki pogled unapred.

Naalost, slinih primera ima i u savremenim jezicima. Na primer, u C++


se za denisanje templejta koristi sintaksa

Foo<Bar>,
dok je strim sintaksa:

cinn >{}> var.


Meutim, javlja se konikt sa ugnjeenim templejtima:

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.

cifra = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ili cifra = [0 9],


int = cifra cifra ili int = cifra+,
slovo = A | B | C | | Z | a | b | z ili slovo = [A Z a z],
id = slovo(slovo | cifra) ,
oat = (+ | )? cifra + (.cifra+)? (E(+ | )? cifra+)?

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

Regularni izrazi su abloni za prepoznavanje nizova i njihovo preslikavanje u


tokene. To je samo jedan od naina kako se mogu denisati abloni i u praksi
se esto koristi. U principu, ablon tokena moe da bude denisan i na bilo koji
drugi nain. Mi smo na poetku ove lekcije koristili tekstualni opis, pa smo npr.
identikator denisali kao niz koji poinje slovom, a moe da sadri slova i cifre.

Da zakljuimo:

Leksema  ulazni niz koji se prepoznaje na osnovu formalnog opisa po-


mou ablona i za koji se generie odreeni token.

Token  izlazni simbol koji se generie kada je prepoznat odreeni ulazni


niz znakova.

ablon (pattern )  regularni izraz, formalni opis ulaznih nizova za koje


se generie odeeni token.

Primer 4.1 Tokeni, lekseme i abloni


U sledeoj tabeli predstavljeni su primeri nekih tokena, leksema za koje se
generiu i ablona kojima se denisani i prema kojima se generiu.

Leksema ablon Token

const Const const


if If if
<, , =, 6=, >, <||=|6=|>| rel
pi, C, P2 slovo (slovo | cifra) )
id
3.1416, 0, 6.02E23 (+ | )? cifra + (.cifra+)? (E(+ | )? cifra+)? num
 Ovo je podatak  (slovo | blanko | cifra)

 literal

4.1.3 Tabela simbola


Pored toga to sintaksnom analizatoru predaje niz tokena leksiki analizator
treba da sauva neke atribute tih tokena da bi oni bili kasnije iskorieni u toku
generisanja koda. Na primer, u fazi sintaksne analize vana je samo informacija
da je na odreenom mestu u nizu identikator, a nije vano koji je to identi-
kator. Meutim, kasnije u fazi semantike analize i u fazi generisanja koda,
vano je koji je to identikator, ta on imenuje, ako imenuje promenljivu kakvog
je tipa, da li je u pitanju skalar ili vektor i sl. Takoe, kada se generie listing
greaka, bitno je koji je identikator i u kojoj liniji se on nalazi.

Kako leksiki analizator prvi dolazi u kontakt sa ulaznim kodom i kasnije ga


transformie on mora da sauva te informacije za kasniju upotrebu. U te svrhe
64 GLAVA 4. LEKSIKI ANALIZATOR

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.

Primer 4.2 Generisani tokeni


Uzmimo kao primer sledeu naredbu napisanu u programskom jeziku C:

E = M * C ** 2
Tokeni sa pridruenim atributima:

hid, pokaziva na tablicu simbola za E i


hop_dodi
hid, pokaziva na TS za M i
hop_muli
hid, pokaziva na TS za C i
hop_expi
hnum, type integer, val 2 i

Detaljnije o organizaciji i realizaciji tabela simbola bie rei u poglavlju 9.

4.2 Realizacija leksikog analizatora


Kako je osnovni zadatak leksikog analizatora da prepozna nizove slova koji
su denisani preko regularnih izraza, za njegovu realizaciju se obino koriste
konani automati.

Na primeru jednog jednostavnog programskog jezika pokazaemo kako moe da


bude generisan graf automata koji prepoznaje taj jezik. Pretpostavimo da na
jezik sadri:

komentare oblika: /*Ovo je komentar */


relacione operatore: <, <=, <>, =, >, >=,
aritmetike operatore: + , -, /, *,
operator dodeljivanja :=,
separatore ;, (, ),
kljune rei (u tabeli kljunih rei),
4.2. REALIZACIJA LEKSIKOG ANALIZATORA 65

identikatore (simbolika imena),

literale (nizove oblika: 'Ovo je podatak'),


celobrojne konstante bez znaka,

beline (prazna slova).

Leksiki analizator treba da prepoznaje sve navedene lekseme, da ignorie ko-


mentare i beline i da generie tokene za sve preostale sluajeve. Bie realizovan
kao konani automat koji polazi iz poetnog stanja uvek kada zapoinje prepo-
znavanje nove lekseme i prelazi u zavrno stanje kada je prepoznao leksemu. U
zavrnim stanjima automata generiu se odgovarajui tokeni.

/
start q1
/ not *

* *
q2 q3 q4 *

not (* | /)

Slika 4.2: Deo automata kojim se izbacuju komentari

Deo ovog automata kojim se izbacuju komentari prikazan je na slici 4.2. Na


ovom grafu stanje q2 automata je zavrno stanje i u njemu se prepoznaje token
/ kao operator deljenja. Kada doe u stanje q2 , analizator e na osnovu toga
koji je sledei znak po redu odluiti da li je to zavrno stanje ili e prei u novo
stanje. Ako je iza kose crte znak *, analizator prelazi u sledee stanje. U svim
ostalim sluajevima stanje q2 je zavrno i prepoznaje se token /.
Deo automata kojim se prepoznaju relacioni operatori prikazan je na slici 4.3.
Stanje q5 < i u njemu se generie token lt, u stanju q6 se
je zavrno za operator
prepoznaje <= i generie se token le, dok se u stanju q7 prepoznaje <> i generie
se token ne. Stanje q8 prepoznaje > i daje token gt, a stanje q9 operator >= i
token ge, dok je stanje q10 zavrno stanje za operator = i generie token eq.

Ovaj primer pokazuje kako se tretiraju dvoznaci. U ovom sluaju za niz od dva
znaka koja ine jedan operator generie se jedan token.

Na slici 4.4 predstavljen je deo automata kojim se prepoznaju aritmetiki ope-


ratori i operator dodele. Svakom od aritmetikih operatora odgovara po jedno
zavrno stanje. Obino su oni sami za sebe tokeni. U ovom delu treba obratiti
panju na to kako se prepoznaje operator dodele. Znak dvotake (:) prevodi
automat u stanje q16 ali to stanje nije zavrno zato to u ovom jeziku dvotaka
66 GLAVA 4. LEKSIKI ANALIZATOR

start q1

<
q5 = q6

> q7
>

q8 = q9
=

q10

Slika 4.3: Prepoznavanje relacionih operatora

nema leksiki smisao: tek sa pojavom znaka = iza dvotake prelazi se u stanje
q17 koje je zavrno i u kome se generie odgovarajui token.

Deo automata kojim se prepoznaju identikatori , literali i graninik ; prikazan


je na slici 4.5. Svako slovo prevodi automat u stanje q19 . Svako sledee slovo ili
cifra zadravaju ga u tom stanju sve dok se ne pojavi neki drugi znak kada to
stanje postaje zavrno. Nakon toga najpre se proverava da li je prepoznata re
kljuna re jezika. U te svrhe pretrauje se tablica kljunih rei jezika. Ukoliko
se u ovoj tablici ne pronae ta re, generie se token id, to znai da je prepoznat
identikator.

Interesantan je i deo kojim se prepoznaju literali (znakovne konstante). U deo


automata koji prepoznaje ove lekseme ulazi se ako se pojavi znak apostrof (')
koji prevodi automat u stanje 20. Svaki znak koji nije apostrof zadrava automat
u tom stanju. Svaki sledei apostrof prevodi automat u stanje q21 . Ovo stanje
je zavrno stanje ako se string zavrava jednim ili neparnim brojem apostrofa.
Paran broj apostrofa vraa automat u stanje q20 koje nije zavrno. U stanju q21
generie se token str i kao njegov atribut pamti prepoznati literal.
Na slici 4.6 prikazan je deo automata kojim se prepoznaju celi brojevi bez znaka.
Pojava cifre prevodi automat u stanje q22 . Svaka sledea cifra zadrava ga u
tom stanju. Nailaskom znaka koji se razlikuje od cifre stanje q22 postaje zavrno
i generie se token int.
U programskim jezicima se obino denie vie tipova konstanti i one su znatno
sloenije od celobrojnih konstanti bez znaka koje smo imali u naem primeru. Na
4.3. PROGRAMSKA REALIZACIJA LEKSIKOG ANALIZATORA 67

start q1

(
q11

)
q12
+

q13
-

* q14

*
q15

q16 = q17

Slika 4.4: Prepoznavanje aritmetikih operatora

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

num = (+|)? cifra (. cifra+ )? (E(+|)? cifra+ )?.

4.3 Programska realizacija leksikog analizatora

Programska realizacija leksikog analizatora se svodi na pisanje programa koji


realizuje automat koji je denisan. Tu mogu da se primene razliite tehnike.
Jedan pristup je da se napie potprogram za svako od stanja automata pa da se
pozivi potprograma poveu u skladu sa grafom automata. Drugi pristup je da
se napie program koji realizuje automat u celosti.
68 GLAVA 4. LEKSIKI ANALIZATOR

start q1

;
q18

slovo
q19 slovo | cifra
' '
q20 q21

'
not '
Slika 4.5: Prepoznavanje identikatora i literala

start q1

cifra
ostalo
q22 cifra

Slika 4.6: Prepoznavanje celih brojeva bez znaka

4.3.1 Tehnika dvostrukog bafera


Prilikom programske realizacije leksikog nalizatora esto se koriste tehnika kod
koje se kao pomona struktura koristi dvostruki bafer (obino duine 1024 baj-
tova); slika 4.8. Najpre se puni leva polovina bafera. Oba pokazivaa ( pPo 
pokaziva poetka lekseme i pKraj  pokaziva kraja lekseme) se postavljaju na
poetak. ita se znak po znak niza i pKraj-pokaziva kraja lekseme se pomera
udesno sve dok se ne prepozna kraj lekseme. Kada se prepozna jedna leksema
pPo se pomera na poziciju pKraj i kree se sa prepoznavanjem nove lekseme.
Kada pKraj doe do kraja prvog bafera puni se drugi bafer i nastavlja se sa
traenjem kraja lekseme u drugom baferu. Kada se doe do kraja drugog bafera
puni se prvi bafer i nastavlja se sa traenjem lekseme od njegovog poetka. Na
ovaj nain dobija se jedan beskonani bafer. Jasno je da zbirna duina oba ba-
fera treba da bude vea od najdue lekseme koja se moe pojaviti u programu.
4.3. PROGRAMSKA REALIZACIJA LEKSIKOG ANALIZATORA 69

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

Slika 4.8: Dvostruki bafer

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

else if pKraj na kraju druge polovine then begin


reload prve polovine;
pomeriti pKraj na poetak prve polovine
end
else Kraj lekseme
pPo = pKraj
End

4.4 Pitanja
1. Objasniti namenu leksikog analizatora.

2. Objasniti zato je bolje da se leksika analiza izdvoji kao posebna faza u


procesu prevoenja jezika.

3. ta su to tokeni?

4. Objasniti vezu izmeu tokena, leksema i ablona.

5. Objasniti vezu izmeu ablona i regularnih izraza.

6. ta je to tablica simbola?

7. Koje greke moe da otkriva leksiki analizator?

8. Objasniti tehniku dvostrukog bafera.

4.5 Zadaci
1. Identikovati lekseme u sledeem delu koda napisanog na programskom
jeziku C.

float triangle(float width, float height) {


float area;
area = width * height / 2.0;
return (area);
}
2. Celobrojne konstante u programskom jeziku C su denisane sledeim sku-
pom pravila.

decimal-constant nonzero-digit | decimal-constant digit


octal-constant octal-digit | octal-constant octal-digit
hexadecimal-constant 0x hexadecimal-digit
| 0X hexadecimal-digit
| hexadecimal-constant hexadecimal-digit
4.5. ZADACI 71

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.

Nacrtati graf automata koji prepoznaje ovako denisane celobrojne kon-


stante.

3. Nacrtati graf automata koji prepoznaje sve operatore dodeljivanja i rela-


cione operatore u C++. Ukljuiti operatore dodeljivanja

=, *=, /=, %=, +=, -=, <<=, >>=, &=, =, |=,

kao i relacione operatore

==, !=, <, >, <=, >=.


72 GLAVA 4. LEKSIKI ANALIZATOR
Glava 5

Sintaksna analiza

Sintaksni analizator prima niz simbola (tokena) od leksikog analizatora i pro-


verava da li taj niz pripada jeziku koji je opisan zadatom gramatikom. Cilj
sintaksnog analizatora je da generie sintaksno stablo za ulazni niz simbola.

5.1 Redosled primene pravila


Da bi se generisalo sintaksno stablo potrebno je odrediti koja se pravila i u
kom redosledu primenjuju prilikom preslikavanja startnog simbola u analizirani
niz. Generalno gledano, postoje dva osnovna principa po kojima se odreuje
redosled pravila. Kako se za opis jezika obino koriste beskonteksne gramatike,
u svakom koraku izvoenja po jedan neterminalni simbol se preslikava u neku
re, pa redosled primene pravila moe da bude:

1. sleva nadesno (levo izvoenje)  kada se zamenjuje prvi neterminalni sim-


bol sa leve strane i

2. zdesna nalevo (desno izvoenje)  kada se zamenjuje prvi neterminalni


simbil sa desne strane.

Sledei primer ilustruje ova dva principa izvoenja.

Primer 5.1 Levo i desno izvoenje


Neka je data gramatika

G({hidi, hslovoi, hcifrai}, {a, b, c, . . . , z, 0, 1, . . . , 9}, id, P),

73
74 GLAVA 5. SINTAKSNA ANALIZA

gde je P sledei skup pravila:

hidi hslovoi | hidihslovoi | hidihcifrai,


hslovoi a | b | c | | z,
hcifrai 0 | 1 | 2 | | 9.

Razmotriemo generisanje rei a111.


Levo izvoenje rei daje:

hidi hidihcifrai
hidihcifraihcifrai
hidihcifraihcifraihcifrai
hslovoihcifraihcifraihcifrai
ahcifraihcifraihcifrai
a1hcifraihcifrai
a11hcifrai
a111.

Desnim izvoenjem dobija se:

hidi hidihcifrai
hidi1
hidihcifrai1
hidi11
hidihcifrai11
hidi111
hslovoi111
a111.

Na sledeoj slici predstavljeno je sintaksno stablo koje odgovara jednom i


drugom izvoenju.
5.1. REDOSLED PRIMENE PRAVILA 75

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.

Primer 5.2 Nejednoznano denisane gramatike


Data je gramatika

G = ({hizrazi, hidi}, {+, , A, B}, hizrazi, P},

gde je P:

hizrazi hidi | hizrazi + hizrazi | hizrazi hizrazi


hidi A | B.

Posmatrajmo izvoenje rei: A B + A.


Levo izvoenje za ovu re je:

hizrazi hizrazi hizrazi


hidi hizrazi
A hizrazi
A hizrazi + hizrazi
A hidi + hizrazi
76 GLAVA 5. SINTAKSNA ANALIZA

A B + hizrazi
A B + hidi
A B + A.

Sintaksno stablo koje odgovara ovom izvoenju dato je na sledeoj slici. U


ovom sluaju bi najpre bila generisana naredba sabiranja a zatim mnoenja.
(Pri generisanju naredbi se prolazi kroz sintaksno stablo odozdo navie.)

hizrazi

hizrazi * hizrazi

hidi
hizrazi + hizrazi

A
hidi hidi

B A

Desnim izvoenjem za posmatrani niz dobija se:

hizrazi hizrazi + hizrazi


hizrazi + hidi
hizrazi + A
hizrazi hizrazi + A
hizrazi hidi + A
hizrazi B + A
hidi B + A
A B + A.

Ovom izvoenju odgovara sintaksno stablo prikazano na sledeoj slici. U


ovom sluaju prvo bi bila generisana naredba mnoenja, a zatim naredba
sabiranja.
5.1. REDOSLED PRIMENE PRAVILA 77

hizrazi

hizrazi + hizrazi

hidi
hizrazi * hizrazi

A
hidi hidi

A B

Oigledno je da ova gramatika, za posmatranu re, primenom levog i desnog


izvoenja daje razliita sintaksna stabla. To znai da rezultat analize nije
jednoznano denisan i bio bi generisan razliit skup naredbi zavisno od
toga koje se izvoenje primenjuje.

Kako bi se izbegla ova vieznanost potrebno je bolje denisati gramatiku.


Na primer, sledea gramatika je ekvivalentna navedenoj, a pri tome je i
jednoznana.

G = ({hizrazi, hsabiraki, hfaktori, hidi}, {+, , A, B}, hizrazi, P)

Skp smena P je:

hizrazi hsabiraki | hizrazi + hsabiraki,


hsabiraki hfaktori | hsabiraki hfaktori,
hfaktori hidi.

Za posmatranu re A B+A dobija se sledee levo izvoenje:

hizrazi hizrazi + hsabiraki


hsabiraki + hsabiraki
hsabiraki hfaktori + hsabiraki
hfaktori hfaktori + hsabiraki
hidi hfaktori + hsabiraki
A hfaktori + hsabiraki
A hidi + hsabiraki
A B + hsabiraki
A B + hfaktori
A B + hidi
78 GLAVA 5. SINTAKSNA ANALIZA

A B + A.

Desno izvoenje za istu re bi bilo:

hizrazi hizrazi + hsabiraki


hizrazi + hfaktori
hizrazi + hidi
hizrazi + A
hsabiraki + A
hsabiraki hfaktori + A
hsabiraki hidi + A
hsabiraki B + A
hfaktori B + A
hidi B + A
A B + A.

Oba ova izvoenja generiu isto sintaksno stablo prikazano u nastavku.

hizrazi

hizrazi + hsabiraki

hsabiraki hfaktori

hidi
hsabiraki * hfaktori
A
hfaktori hidi

hidi B

U odnosu na to kako obavljaju sintaksnu analizu postoje dva tipa sintaksnih


analizatora:

top-down analizatori koji vre analizu odozgo nanie i

bottom-up analizatori koji vre analizu odozdo navie.


5.2. OSNOVNI ALGORITAM ZA TOP-DOWN SINTAKSNU ANALIZU 79

U sluaju top-down analize polazi se od startnog simbola i nastoji se da se odrede


pravila koja treba primeniti da bi se generisala re ija se analiza vri. To znai
da se pravila otkrivaju u redosledu u kom se i primenjuju prilikom generisanja
rei, odnosno odozgo nanie ako se to posmatra na sintaksnom stablu.

U sluaju bottom-up analize primenjuje se postupak redukcije. Kree se od rei


ija se analiza vri i nastoji se da se ta re redukuje na startni simbol. Pravila se
odreuju u redosledu koji je suprotan redosledu njihove primene kod generisanja
rei i sintaksnog stabla, odnosno odozdo navie ako se to gleda na sintaksnom
stablu.

U principu bottom-up analizatori su ekasniji i na njima se uglavnom zasnivaju


komercijalna reenja kompilatora.

Postoje veoma ekasni algoritmi za sintaksnu analizu i u jednoj i u drugoj klasi


i ovde e biti predstavljeni neki od njih. Kako bi se bolje sagledala razlika u
pristupu analizi najpre e biti objanjeni osnovni algoritmi za analizu iz obe
klase analizatora.

5.2 Osnovni algoritam za top-down sintaksnu ana-


lizu
Kree se od startnog simbola i bira se prvo pravilo kojim se startni simbol
preslikava u neku frazu. Posle toga u svakom koraku se nastoji da se prvi
neterminalni simbol sa leve strane zameni desnom stranom prvog raspoloivog
pravila. Praktino, nastoji se da se generie analizirani niz levim izvoenjem.
Ukoliko na nekom koraku ne postoji odgovarajua smena, vraamo se natrag
do nivoa na kome je mogue primeniti alternativno pravilo. Analiza je uspena
ako se kao rezultat ovog postupka dobije niz koji se analizira. Ako se vraanjem
unazad doe ponovo do startnog simbola gramatike, i nema novih alternativa
za zamenu tog simbola, postupak analize je neuspean.

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:

1. U izvedenu sekvencu upisati niz S#, gde je S startni simbol, a # granini.


Postaviti pokaziva pRadni na prvi znak u izvedenom nizu (na startni
simbol) a pokaziva pUlaz na prvi simbol ulaznog niza.

2. Ukoliko je simbol na koji pokazuje pRadni u izvedenoj sekvenci neter-


minalni simbol, zameniti ga desnom stranom prve smene na ijoj je levoj
80 GLAVA 5. SINTAKSNA ANALIZA

strani taj neterminalni simbol i postaviti pRadni na prvi simbol unete


rei.

3. Ukoliko je simbol na koji pokazuje pRadni u izvedenoj sekvenci terminalni


simbol i pri tome jednak ulaznom simbolu na koji pokazuje pUlaz, to znai
da je taj simbol prepoznat, oba pokazivaa se pomeraju za jedno mesto
udesno i postupak se nastavlja (prelazi se na analizu sledeeg simbola).

4. Ukoliko je simbol na koji pokazuje pRadni u izvedenoj sekvenci terminalni


simbol i razliit od ulaznog simbola na koji pokazuje pUlaz, ponititi
dejstvo poslednje primenjene smene, vratiti se na stanje pre primene te
smene i pokuati na tom nivou sa primenom nove smene. Ukoliko na tom
nivou nema alternativa vratiti se jo jedan korak nazad ponititi poslednju
primenjenu smenu i triti novu alternativu na tom nivou.

5. Ukoliko se vraanjem doe do startnog simbola i pri tome nema novih


alternativa, ulazni niz nije mogue prepoznati, postupak prepoznavanja
niza je neuspean, kd sadri sintaksnu greku.

6. Postupak analize je uspean kada se oba pokazivaa ( pUlaz i pRadni)


nau na graninom simbolu .

Primer 5.3 Osnovni algoritam za top-down analizu


Neka je data gramatika

G = ({S, A, B}, {a, b, c, d}, S, P)

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

ulazni niz izvedeni niz akcija

1 a ccd# S# primenjuje se (1)


2 a ccd# a Ad# prepoznaje se a
3 a c cd# a A d# primenjuje se (3)
4 a c cd# a b d# greka, vraanje unatrag

5 a c cd# a A d# primenjuje se (4)


6 a c cd# a c d# prepoznaje se c
7 ac c d# ac d # greka, vraanje unatrag

8 a c cd# a A d# nema novih pravila, vraanje

9 a ccd# S# primenjuje se (2)

10 a ccd# a B# prepoznaje se a
11 a c cd# aB# primenjuje se (5)

12 a c cd# a c cd# prepoznaje se c


13 ac c d# ac c d# prepoznaje se c
14 acc d # acc d # prepoznaje se d
15 accd # accd # uspean kraj analize

Napomena: Posebno su oznaena slova na koja pokazuju ulazni i radni


pokaziva, koja se posmatraju u odreenom koraku. Uz pravila koja su
ponitena stoji oznaka .
Za generisanje rei accd#, potrebno je primenti smene (2) i (5). Na sledeoj
slici prikazano je sintaksno stablo za analiziranu re.

a B

c c d

5.2.1 Problem leve rekurzije


Top-down sintaksnom analizom se generie skup smena iji redosled primene
odgovara levom izvoenju. Zbog toga ovaj postupak analze ne moe da se
primeni kod tzv. levo rekurzivnih gramatika. Levo rekurzivne gramatike su
82 GLAVA 5. SINTAKSNA ANALIZA

gramtike kod kojih postoje levo rekurzivna pravila , odnosno pravila oblika:

A Ar, gde je A Vn , r V .

Kod ovakvih pravila preslikavanjem neterminala A dobija se re koja opet po-


inje istim neterminalom, i to se iz koraka u korak ponavlja, odnosno ulazi se u
jednu beskonanu petlju, tako da analzu nije mogue zavriti.

Primer 5.4 Levo rekurzivna gramatika


Neka je data gramatika

G = ({S, A}, {a, c}, S, P)

gde je P sledei skup pravila:

S aAc,
S Aa,
S .

Ova gramatika e u postupku sintaksne analize uvek ui u petlju prikazanu


na sledeoj slici.

a A c

A a

A a

A a

Pored ove direktne rekurzije gramatika moe da ima i indirektna rekurzivna


pravila koje je teko otkriti.

Primer 5.5 Levo rekurzivna gramatika sa indirektnim rekurzivnim pravilima


Sledei skup pravila sadri rekurziju po dubini:

S Aa | b,
A Sd | c | .
5.2. OSNOVNI ALGORITAM ZA TOP-DOWN SINTAKSNU ANALIZU 83

Neterminal S generie neterminal A, a ovaj opet neterminal S.

5.2.2 Eliminisanje leve rekurzije


Svaku levu rekurzivnu gramatiku mogue je transformisati u ekvivalentnu ne-
rekurzivnu gramatiku. Naveemo dve mogunosti za to.

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 ,

ovaj skup pravila mogue je zameniti sledeim skupom nerekurzivnih pravila:

A 1 | 2 | | m | 1 A0 | 2 A0 | | m A0 ,
A0 1 | 2 | | n | 1 A0 | 2 A0 | | n A0 .

Mogua je i sledea transformacija:

A 1 A0 | 2 A0 | | m A0 ,
A0 1 A0 | 2 A0 | | n A0 .

Primer 5.6 Eliminisanje leve rekurzije


Neka je data levo rekurzivna gramatika:

E E + T | T,
T T F | F,
F (E) | a.

Ekvivalentna nerekurzivna gramatika bila bi:

E T | T E0,
E 0 +T | +T E 0 ,
T F | F T 0,
T 0 F | F T 0 ,
F (E) | a.

Eliminisanje indirektne rekurzije mogue je sledeom transformacijom:

Sve skupove pravila oblika

X Y ,
84 GLAVA 5. SINTAKSNA ANALIZA

Y X1 | X2 | | Xn

treba zameniti pravilima

x X1 | X2 | | Xn .

Posle ove transformacije treba se osloboditi svih direktnih levo-rekurzivnih smena,


ukoliko postoje.

Primer 5.7 Eliminisanje leve rekurzije


Gramatika iz primera 5.5 moe da se transformie u nerekurzivnu grama-
tiku na sledei nain:

Najpre emo razdvojiti smene da bismo bolje videli indirektnu rekurziju:

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.

U sledeem koraku se eliminiu direktno levo rekurzivno pravila (1), tako


da je gramatika konano denisana skupom smena:

S ca, S a,
S b, S caS 0 ,
S aS 0 , S bS 0 .

Primer 5.8 Top-down analiza


5.2. OSNOVNI ALGORITAM ZA TOP-DOWN SINTAKSNU ANALIZU 85

Blok naredbi u jeziku Pascal denisan je sledeom gramatikom:

G = ({Blok, NizNar, Naredba, Dodela, Izraz},


{begin, end, ID, CONST, ;, +, :=},
Blok, P),

gde je P sledei skup pravila:

Blok begin NizNar end


NizNar NizNar ; Naredba | Naredba
Naredba Dodela | Blok
Dodela ID:= Izraz
Izraz Izraz + CONST CONST
|

Proveriti da li je blok

begin ID := CONST end


sintaksno korektno napisan.

Reenje: Najpre eliminiemo levo rekurzivna pravila: Najpre skup smena

NizNar NizNar ; Naredba | Naredba

zamenjujemo smenama:

NizNar Naredba NizNar 0


NizNar 0 ; Naredba NizNar 0 |

Zatim skup smena

Izraz Izraz + CONST | CONST


zamenjujemo smenama:

Izraz CONST Izraz 0


Izraz 0 + CONST Izraz 0 |
Transformisana gramatika sadri sledei skup pravila:

Blok begin NizNar end (1)

NizNar Naredba NizNar 0 (2)

NizNar 0 ; Naredba NizNar 0 (3)

NizNar 0 (4)
86 GLAVA 5. SINTAKSNA ANALIZA

Naredba Dodela (5)

Naredba Blok (6)

Dodela ID
:= Izraz (7)

Izraz CONST
Izraz 0 (8)

Izraz 0 + CONST
Izraz 0 (9)

Izraz 0 (10)

Postupak sintaksne analize zadate rei je dat u tabeli 5.1.

Za generisanje niza begin ID := CONST end # koristi se skup smena


{(1), (2), (5), (7), (8), (10), (4)}. Na sledeoj slici je prikazano odgovarajue
sintaksno stablo.

Blok

begin NizNar end

Naredba NizNar

Dodela

ID := Izraz

CONST Izraz

5.3 Osnovni algoritam za bottom-up analizu


U sluaju bottom-up analize primenjuje se postupak redukcije rei koja se ana-
lizira. Osnovni algoritam za analizu se sastoji u tome to se ulazni niz analizira
slovo po slovo od poetka prema kraju i nastoji se da se neki njegov podniz
prepozna kao desna stana nekog od raspoloivih pravila gramatike. Kada se
takav podniz pronae, vri se njegova redukcija na simbol koji je na levoj strani
primenjene smene i postupak nastavlja sve dok se niz ne redukuje na startni
simbol. Kao i kod osnovnog algoritma za top-down analizu i ovde ima vraanja
unatrag i ponitavanja primenjenih smena u sluaju kada doe do greke i ne
moe da se ide dalje sa analizom.
Ulazni niz Generisani niz Akcija

begin ID := CONST end # Blok # primenjuje se (1)

begin ID := CONST end # begin NizNar end # prepoznaje se begin

begin ID := CONST end # begin NizNar end # primenjuje se (2)

begin ID := CONST end # begin Naredba NizNar' end # (5)

begin ID := CONST end # begin Dodela NizNar' end # (7)

begin ID := CONST end # begin ID := Izraz NizNar' end# prepoznaje se ID

begin ID := CONST end # begin ID := Izraz NizNar' end# prepoznaje se :=

begin ID := CONST end # begin ID := Izraz NizNar' end# (8)

begin ID := CONST end # begin ID := CONST Izraz'NizNar' end # prepoznaje se CONST

begin ID := CONST end # begin ID := CONST Izraz' NizNar' end # (9)


begin ID := CONST end # begin ID := CONST + CONST Izraz'NizNar' end# greka

begin ID := CONST end # begin ID := CONST Izraz' NizNar' end # (10)

begin ID := CONST end # begin ID := CONST NizNar' end # (3)


greka
5.3. OSNOVNI ALGORITAM ZA BOTTOM-UP ANALIZU

begin ID := CONST end # begin ID := CONST ; N aredba NizNar' end#


begin ID := CONST end # begin ID := CONST NizNar' end # (4)

begin ID := CONST end # begin ID := CONST end # prepoznaje se end

begin ID := CONST end # begin ID := CONST end # uspean kraj


87

Tabela 5.1: Postupak sintaksne analize iz primera 5.7


88 GLAVA 5. SINTAKSNA ANALIZA

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.

Ilustrovaemo ovaj postupak na primeru rei i gramatike iz primera 5.3.

Primer 5.9 Osnovni algoritam za bottom-up analizu


Neka je data gramatika

G = ({S, A, B}, {a, b, c, d}, S, P)

sa skupom smena P:

S aAd (1)

S aB (2)

Ab (3)

Ac (4)

B ccd. (5)

Bottom-up sintaksna analiza rei accd# data je u nastavku.

Ulazni Niz u
niz magacinu Akcija

1 accd#
2 ccd# a Nema smene, ubacuje se novo slovo

3 cd# ac Primenjuje se smena (4)

4 cd# aA Nema smene, gleda se dublje

5 cd# aA Nema smene, ubacuje se novo slovo

6 d# aA c Primenjuje se smena (4)

7 d# aA A Nema smene, gleda se dublje

8 d# a AA Nema smene, gleda se dublje

9 d# aAA Nema smene, ubacuje se novo slovo


5.3. OSNOVNI ALGORITAM ZA BOTTOM-UP ANALIZU 89

10 # aAA d Nema smene, gleda se dublje

11 # aA Ad Nema smene, gleda se dublje

12 # a AAd Nema smene, gleda se dublje

Nema smene, nema slova za ubaciva-

13 # aAAd nje; ponitava se sve do koraka 6 i po-


kuava sa da se nae nova alternativa
na tom nivou

14 d# aA c Nema smene, gleda se dublje

15 d# a Ac Nema smene, gleda se dublje

16 d# aAc Nema smene, ubacuje se novo slovo

17 # aAc d Nema smene, gleda se dublje

18 # aA cd Nema smene, gleda se dublje

19 # a Acd Nema smene, gleda se dublje

Nema smene, nema slova za ubaci-


vanje; ponitava se sve do poslednje
20 # aAcd
primenjene smene (korak 3) i trai se
nova alternativa na tom nivou

21 cd# ac Nema smene, gleda se dublje

22 cd# ac Nema smene, ubacuje se slovo

23 d# ac c Primenjuje se smena (4)

24 d# ac A Nema smene, gleda se dublje

25 d# a cA Nema smene, gleda se dublje

26 d# acA Nema smene, ubacuje se novo slovo

27 # acA d Nema smene, gleda se dublje

28 # ac Ad Nema smene, gleda se dublje

29 # a cAd Nema smene, gleda se dublje

Nema smene, nema slova za ubaciva-

30 # acAd # nje; ponitava se sve do 23 i pokuava


sa da se nae nova alternativa na tom
nivou

31 d# ac c Nema smene, gleda se dublje


90 GLAVA 5. SINTAKSNA ANALIZA

32 d# a cc Nema smene, gleda se dublje

33 d# acc Nema smene, ubacuje se novo slovo

34 # acc d Nema smene, gleda se dublje

35 # ac cd Nema smene, gleda se dublje

36 # a ccd Primenjuje se smena (5)

37 # aB Nema smene, gleda se dublje

38 # aB Primenjuje se smena (2)

39 # S Uspean kraj analize

Koriena je notacija u kojoj je uokviren niz koji se nalazi u vrhu magacina


i trenutno trai kao desna strana smene.

I u ovom postupku dobija se da se analizirani niz generie primenom smena


(5) i (2) samo to su one otkrivene u redosledu koji je suprotan od njihove
primene, to je i sutina samog postupka. Sintaksno stablo koje odgovara
rei je isto kao i u primeru 5.3.

5.4 Pitanja

1. Objasniti ta je zadatak sintaksnog analizatora.

2. Objasniti pojam levog i desnog izvoenja.

3. Objasniti koji se problem javlja kod nejednoznano denisanih gramatika.

4. Koja su to dva osnovna naina sintaksne analize?

5. Opisati osnovni algoritam za top-down analizu.

6. ta je to problem leve rekurzije i kada se javlja?

7. Dati transformacije kojima se eliminie leva rekurzija.

8. ta je to indirektna rekurzija i kako se eliminie?

9. Objasniti osnovni algoritam za bottom-up analizu.


5.5. ZADACI 91

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:

Ulaz READ (NizPromenljivih )


NizPromenljivih NizPromenljivih , | ID ID
2. Primenom osnovnog algoritma za top-down sintaksnu analizu proveriti da
li re #a + a (a + a)# pripada jeziku koji je denisan gramatikom

G = ({S, I, F }, {a, +, }, S, P},

gde je P sledei skup pravila:

S S+I |I I I F |F
F a(S) | a.

3. Neka je gramatika G zadata skupom pravila

S S + I | I, I (S) | f (S) | id.

Primenom osnovnog algoritma za top-down sintaksnu analizu proveriti da


li niz
#id + f (id + f (id)))#
pripada jeziku ove gramatike.

4. Primenom osnovnog algoritma za bottom-up analizu proveriti da li re


#a + a a# pripada jeziku denisanom gramatikom iz zadatka 2.

5. Traenu proveru iz zadatka 3 izvriti primenom osnovnog algoritma za


bottom-up analizu.
92 GLAVA 5. SINTAKSNA ANALIZA
Glava 6

Prediktivna analiza  LL-1


analizatori

Osnovni problem kod polaznih algoritama za sintaksnu analizu predstavljenih


u prethodnom poglavlju je veliki broj povratnih koraka tako da je sam postu-
pak analize dosta dug i neizvestan. U ovom poglavlju bie razmotreni mnogo
ekasniji analizatori za top-down analizu koji u svakom koraku vre neku vrstu
predikcije na osnovu koje odluuju koja e se pravilo primeniti. Ako meu raspo-
loivim pravilima ne postoji odgovarajue pravilo postupak analize se prekida
kao neuspean. Smene se otkrivaju direktno bez povratnih petlji.

Za razliku od osnovnog algoritma za top-down analizu kod kojeg se pravila biraju


na osnovu prvog neterminalnog simbola sa leve strane u izvedenom nizu, kod
ovih analizatora odluka o pravilu koje e da se primeni se donosi i na osnovu
slova u ulaznom nizu koje treba da se prepozna, na kome je trenutno ulazni
pokaziva. Primenjuje se pravilo koje e sigurno da generie bar to slovo. Ovakvi
analizatori su poznati kao LL-1 analizatori (look-left 1 ), gde cifra 1 ukazuje na to
da se predikcija vri na osnovu jednog slova u ulaznom nizu. Generalno gledano,
mogu da se deniu i LL-k analizatori kod kojih se predikcija vri na osnovu
rei duine k, ali su LL-1 mnogo upotrebljiviji.

Da bi mogla da se vri predikcija, gramatika kojom je opisan jezik mora da bude


tako denisana da za jedan ulazni simbol i jedan neterminal postoji najvie jedna
raspoloiva smena, nema vie alternativa. Krenuemo od denicije proste LL-1
gramatike.

93
94 GLAVA 6. PREDIKTIVNA ANALIZA  LL-1 ANALIZATORI

6.1 Proste LL-1 gramatike


Proste LL-1 gramatike su beskonteksne gramatike kod kojih sve smene za isti
neterminalni simbol poinju razliitim terminalnim simbolima:

A 1 1 | 2 2 | | n n , gde je ai Vt , i V , ai 6= aj za i 6= j.

Primer 6.1 Prosta LL-1 gramatika


Gramatika G = ({S, A}, {a, b, c, d}, S, P}, gde je P skup pravila

S aS S bA
Ad A ccA,

je LL-1 gramatika. Za neterminal S postoje dva pravila kojima se S presli-


kava u rei koje poinju razliitim poetnim slovima (a i b). Za neterminal
A postoje dva pravila koja takoe imaju razliita poetna slova rei u koje
se preslikava taj neterminal (d, c).
Re aabccd# pripada jeziku denisanom ovom gramatikom i izvodi se na
sledei nain.

S 0 S# aS# aaS# aabA# aabccA# aabccd#

Napomena: Skup pravila je dopunjen pravilom: S 0 S#, kako bi se


uveo i granini simbol #.

Za sintaksnu analizu jezika denisanih LL-1 gramatikama koristi se magacinski


automat i sintaksnu tabela kao pomona struktura. Ova sintaksna tabela se
sastoji od onoliko kolona koliko ima terminalnih sibola i onoliko vrsta koliko
ima neterminalnih i terminalnih simbola zajedno. Polja sintaksne tabele se po-
punjavaju tako da se u polju koje odgovara neterminalu A i terminalu a, upisuje
smena koji na levoj strani ima neterminal A, a na desnoj strani re koja poinje
terminalom a, ako takva smena postoji. U preseku vrste koja je oznaena nekim
terminalom i kolone koja je oznaena istim tim terminalom upisuje se vrednost
pop, dok se u preseku vrste i kolone koje su oznaene graninim simbolom #
upisuje znak za kraj analize (acc ). Sva ostala polja su polja greke (err ). Sin-
taksna tabela Ts(A, a), gde je A oznaka vrste, a a oznaka kolone se formalno
moe denisati na sledei nain:

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

Primer 6.2 LL-1 sintaksna tabela


Sintaksna tabela koja odgovara gramatici iz primera 6.1 data je u nastavku.

Vrh Ulazni simbol


magacina a b c d #

S (aS, 1) (bA, 2)
A (ccA, 4) (d, 3)
a pop
b pop
c pop
d pop
# acc

Opisani magacinski automat prepoznaje re koju analizira tako to se u ma-


gacin ubacuje startni niz S# i u svakom koraku vri preslikavanje odreeno
sintaksnom tabelom, odnosno:

M : {V {#}} {Vt {#}} 7 {(, r), pop, acc, err}.

Oznaimo konguraciju automata u odreenom trenutku prepoznavanja sa (az, A, p),


gde je:

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.

Preslikavanje koje u toku prepoznavanja vri automat moemo da deniemo


na sledei nain:

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

Poetna konguracija magacina je odreena sa: (w, S#, ), gde je w re ije


prepoznavanje treba izvriti, S startni simbol, a oznaava prazan niz prime-
njenih smena. Niz je uspeno prepoznat ako se u toku analize doe do graninog
96 GLAVA 6. PREDIKTIVNA ANALIZA  LL-1 ANALIZATORI

simbola i u ulaznom i u generisanom nizu, odnosno iz tablice sintaksne analize


proita vrednost za kraj analize (acc ).

Napomenimo da iz same denicije LL-1 gramatike proizilazi da tabela sintaksne


analize mora da bude denisana jednoznano. U svakom koraku prepoznavanja
rei jednoznano je denisano preslikavanje koje treba izvriti: ili je mogue
primeniti neku smenu i napredovati u postupku prepoznavanja, ili je dolo do
greke i prepoznavanje treba prekinuti. U ovom postupku analize nema povrat-
nih koraka, to je posledica same denicije LL-1 gramatika. Postupak analize
pokazaemo na primeru rei aabccd# i gramatike iz primera 6. 1.

Primer 6.3 Postupak LL-1 sintaksne analize


Ako se posmatra gramatika iz primera 6.1, u toku prepoznavanja rei
aabccd#, u automatu se dogaaju sledea preslikavanja:

(aabccd#, S#, ) (aabccd#, aS#, 1)


(abccd#, S#, 1)
(abccd#, aS#, 11)
(bccd#, S#, 11)
(bccd#, ba#, 112)
(ccd#, A#, 112)
(ccd#, ccA#, 1124)
(cd#, cA#, 1124
(d#, A#, 1124)
(d#, d#, 11243)
(#, #, 11243).

Kako se posle primene nekog pravila sigurno prepoznaje jedan terminalni


simbol iz ulaznog niza, gore dati postupak prepoznavanja se moe napisati
i skraeno na sledei nain:

(aabccd#, S#, ) (abccd#, S#, 1)


(bccd#, S#, 11)
(ccd#, A#, 112)
(cd#, cA, 1124)
(d#, A#, 1124)
(#, #, 11243).
6.2. POMONE FUNKICIJE ZA DEFINISANJE OPTIH LL-1 GRAMATIKA97

6.1.1 Leva faktorizacija


Pokazali smo da se u sluaju LL-1 gramatika moe vriti prediktivna sintaksna
analiza koja je mnogo ekasnija od osnovnog algoritma za sintaksnu analizu.
Veoma znaajno u svemu tome je da se gramatike koje ne zadovoljavaju uslov
LL-1 gramatika mogu jednostavno transvormisati u ovaj tip gramatika. Naime,
ukoliko u gramatici postoji vei broj pravila kojima se isti neterminalni simbol
preslikava u rei sa istim poetnim slovom, odnosno smene oblika

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

Ova transformacija gramatika poznata je pod imenom leva faktorizacija .

Primer 6.4 Leva faktorizacija


Neka je gramtika zadata sledeim skupom pravila:

Nar if Izraz then Nar else Nar | if Izraz then Nar


Izraz b

Kako u datoj gramatici za neterminal Nar postoje dva pravila koja na


desnoj imaju rei sa istim preksom: if Izraz then Nar, ova gramatika nije
LL-1. Njoj ekvivalentna LL-1 gramarika je:

Nar if Izraz then Nar else Nar Nar'


Nar' else Nar |
Izraz b

6.2 Pomone funkicije za denisanje optih LL-1


gramatika
Datom denicijom LL-1 gramatika obuhvaen je samo najednostavniji sluaj
ovih gramatika kada re na desnoj strani smene poinje terminalnim simbolom.
Meutim, taj uslov moe i da se proiri da obuhvati i sloenije sluajeve LL-1
98 GLAVA 6. PREDIKTIVNA ANALIZA  LL-1 ANALIZATORI

gramatika. Na primer, razmotrimo sledeu gramatiku u kojoj imamo i pravila


koja neterminale preslikavaju u rei koje zapoinju neterminalima:

S 0 S# (1)

Ac (2)

S Abe (3)

B AS (4)

A dB (5)

Bb (6)

A aS (7)

Oigledno je da se prilikom odluivanja kada se mogu primeniti takva pravila


moraju uzeti u obzir svi terminalni simboli koji se nalaze na poetku fraza koje
se generiu od poetnih neterminala. U naem primeru pravilo (4) e moi da
se primeni u svim sluajevima kada se u radnom magacinu nalazi neterminal B,
a prepoznaje se neki od terminalnih simbola kojim zapoinju fraze neterminala
A, koji je poetni simbol desne strane pravila (4).

Jo komplikovanije je odluivanje kada koje pravilo treba primeniti ako u gra-


matici postoje tzv. -pravila, odnosno kada se neki neterminalni simbol ukida,
kao u sluaju gramatike denisane sledeim skupom pravila:

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.

6.2.1 Funkcija First


Za svaku smenu oblika X a, moe da se denie funkcija First(a) koja kao
rezultat daje sve terminalne simbole koji mogu da se nau na poetku rei
izvedenih iz rei a, tj.


V+ First() = {s |
s, gde je s Vt , V }.
6.2. POMONE FUNKICIJE ZA DEFINISANJE OPTIH LL-1 GRAMATIKA99

Primer 6.5 Funkcija First


Neka je gramatika zadata sledeim skupom pravila.

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

6.2.2 Funkcija Follow


Funkcija Follow se denie za neterminalne simbole, kao skup terminalnih sim-
bola koji mogu u toku izvoenja da se nau iza tog neterminalnog simbola,
ili:

Follow(A) = {s Vt | S 0
As, A, S 0 Vn , V },
gde je S0 startni simbol gramatike.

Po deniciji, Follow funkcija startnog simbola gramatike sadri granini sim-


bol #.
Za odreivanje Follow funkcije neterminalnog simbola X posmatraju se desne
strane pravila u kojima se pojavljuje posmatrani simbol. Pri tome simbol X na
desnoj strani smene moe da se nae u jednom od sledeih konteksta:

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).

Primer 6.6 Funkcija Follow


Naka je data gramtika

G({A, B, C, D}, {i, , e, [, ], }, A, P)

denisana sledeim skupom pravila.

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} = {]}.

6.3 LL-1 gramatike bez -pravila

Iskoristiemo najpre funkciju First da deniemo optije LL-1 gramatike ali


emo pri tome iskljiti postojanje -pravila.

Beskonteksna gramatika bez -pravila je LL-1 gramatika ako su za sva pravila


za isti neterminalni simbol oblika A 1 | 2 | | n skupovi

First(1 ), First(2 ), . . . , First(n )

disjunktni po parovima, odnsno

First(i ) First(j ) = , i 6= j.

Primer 6.7 LL-1 gramatika bez -pravila


Za gramatiku datu u primeru 6.4 vai:

First(dB) First(aS) = {d} {a} = ,


First(dB) First(c) = {d} {c} = ,
First(aS) First(c) = {a} {c} = ,
First(AS) First(b) = {a, c, d} {b} = .

Ova gramatika ispunjava potrebne uslove za LL-1 gramatiku.


6.3. LL-1 GRAMATIKE BEZ -PRAVILA 101

Sintaksna tabela za ovako denisane LL-1 gramatike denisana je sa:

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.

Tabela se popunjava tako to se odreena smena upisuje u polje na preseku vrste


koja odgovara neterminalu sa leve strane smene i u sve koleone koje odgovaraju
terminalnim simbolima koji ulaze u skup odreen funkcijom First za re koja je
na desnoj stani smene.

Primer 6.8 Sintaksna tabela za LL-1 gramatiku bez -pravila


Za gramatiku datu u primeru 6.6 sintaksna tabela je data u nastavku.

Vrh Ulazni simbol


magacina a b c d e #

S (ABe, 3) (ABe, 3) (ABe, 3)


A (aS, 7) (c, 2) (dB, 5)
B (AS, 4) (b, 6) (AS, 4) (AS, 4)
a pop
b pop
c pop
d pop
e pop
# acc

Uoimo da su smene (3) i (4) upisane u kolonama a, b i d zato to je

First(ABe) = First(A) = {a, c, d} i First(AS) = First(A) = {a, c, d}.

Sam postupak sintaksne analize je potpuno isti kao i kod prostih LL-1 gramatika.

Primer 6.9 Postupak sintaksne analize za LL-1 gramatiku bez -pravila


Za gramatiku iz primera 6.6, postupak sintaksne analize rei dccbebe# je
102 GLAVA 6. PREDIKTIVNA ANALIZA  LL-1 ANALIZATORI

sledei.

(dccbebe#, S#, ) (dccbebe#, ABe#, 3)


(dccbebe#, dBBe#, 35)
(ccbebe#, BBe#, 35)
(ccbebe#, ASBe#, 354)
(ccbebe#, cSBe#, 3542)
(cbebe#, SBe#, 3542)
(cbebe#aBeBe#, 35423)
(cbebe#, cBeBe#, 354232)
(bebe#BeBe#, 354232)
(bebe#beBe#, 3542326)
(ebe#, eBe#, 35423226)
(be#, Be#, 35423226)
(be#, be#, 354232266)
(e#, e#, 3542266)
(#, #, 35423266).

Sintaksna analiza je uspeno zavrena i kao rezultat je dobijeno da se zadata


re generie nizom smena

(3), (5), (4), (2), (3), (2), (6) i (6)

odnosno zadatoj re odgovara sledee izvoenje:

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

6.4 LL-1 gramatike sa -pravilima


Beskonteksna gramatika koja sadri i -pravila je LL-1 gramatika ako i samo
ako za sva pravila oblika A 1 | 2 | | n i A vai

First(i Follow(A)) First(j Follow(A)) = , za svako i 6= j,

gde je simbolom oznaena operacija nadovezivanja (konkatenacije).

Ovaj uslov moe da se iskae i na sledei nain:

1. Za sva pravila A 1 | 2 | | n treba da vai

First(i ) First(j ) = , za svako i 6= j;


2. Ako je i
, tada mora da vai i

First(j ) Follow(A) = , za svako j 6= i.

Primer 6.10 Primer LL-1 gramatike sa -pravilima


Neka je data gramatika

G({A, B, C, D}, {i, , e, [, ], }, A, P)

denisana sledeim skupom smena:

A0 A# A iB e B SB B
S [eC] S i C eC C .

Ispitaemo da li ova gramatika ispunjava potrebne uslove za LL-1 gra-


matiku. Dati uslovi treba da budu ispitani za svaki par pravila za isti
neterminalni simbol.

Za pravila kojima se denie preslikavanje neterminala S vai:

First([eC] Follow(S)) First(i Follow(S)) = {[} {} = .

Kako je presek ova dva skupa prazan skup, uslov je ispunjen za ovaj ne-
terminal.

Za pravila kojima se preslikava neterminal B se dobija:

First(SB Follow(B)) First( Follow(B)) =


{[, } Follow(B) =
{[, } {} = .
104 GLAVA 6. PREDIKTIVNA ANALIZA  LL-1 ANALIZATORI

Za neterminal C vai:

First(eC Follow(C)) First( Follow(C)) =


{e} First(Follow(C)) =
{e} Follow(C) =
{e} {]} = .

Za sve razmatrane parove dobijamo da je presek First funkcija pazan skup


to znai da zadata gramatika pripada skupu LL-1. gramatka.

Sintaksna tabela kod LL-1 gramatika sa -pravilima je neto modikovana u


odnosu na prethodne denicije. Naime, sada je problem gde u tablici treba
smestiti -pravila. Zbog toga je sintaksna tabela denisana na sledei nain:

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.

Primer 6.11 Sintaksna tabela za gramatiku iz primera 6.10


Za gramatiku iz primera 6.10 dobija se sintaksna tabela prikazana u na-
stavku.
6.4. LL-1 GRAMATIKE SA -PRAVILIMA 105

Vrh Ulazni simbol


magacina i e [ ] #

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

Pravilo (3) B nalazi se u koloni zato to ovaj simbol pripada skupu


Follow(B), to se vidi iz pravila (1). Slino, pravilo (7) C , nalazi se u
koloni ] zato to taj simbol pripada skupu Follow(C), prema pravilu (4).

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).

Primer 6.12 Sintaksna analiza za gramatiku iz primera 6.10


Za gramatiku iz primera 6.10 i re i[e] e# postupak sintaksne analize
je:

(i[e] e#, A#, e) (i[e] e#, iB #, 1)


([e] e#, B e#, 1)
([e] e#, SB e#, 12)
([e] e#, [eC]B e#, 124)
(e] e#, eC]B e#, 124)
(] e#, C]B e#, 124)
(] e#, ]B e#, 1247)
( e#, B e#, 1247)
( e#, e#, 12473)
(e#, e#, 12473)
(#, #, 12473).
106 GLAVA 6. PREDIKTIVNA ANALIZA  LL-1 ANALIZATORI

Re je prepoznata i za njeno izvoenje koristi se niz smena (1), (2), (4),


(7) i (3).

Da zakljuimo  ukoliko gramatika kojom je opisan jezik ima svojstva LL-1


gramatike, mogue je vriti top-down analizu bez povratnih koraka, odnosno
mnogo ekasnije u odnosu na osnovni top-down algoritam.

6.5 Reeni zadaci


Zadatak 1 Ispitati da li gramatika

G = ({Blok, NizNar, Naredba, Dodela, Izraz},


{begin, end, ID, CONST, ;, +, :=},
Blok, P),

iz primera 5.8, koja je posle eliminisanja leve rekurzije zadata sledeim


skupom smena,

Blok begin NizNar end (1)

NizNar Naredba NizNar' (2)

NizNar' ; Naredba NizNar' (3)

NizNar' (4)

Naredba Dodela (5)

Naredba Blok (6)

Dodela id := Izraz (7)

Izraz const Izraz' (8)

Izraz' +const Izraz' (9)

Izraz' (10)

zadovoljava uslove LL-1 gramatike.

Reenje. Vrimo analizu skupova smena koje na levoj strani imaju isti neter-
minalni simbol.

Prvi par smena koje treba ispitati je par (3) i (4).

First(; Naredba NizNar') = {;}


First() = {}
First(; Naredba NizNar') First() =

Samo jedna od navedenih smena se preslikava u prazan skup.

Follow(NizNar') = Follow(NizNar) = {end}


6.6. PITANJA 107

First(; Naredba NizNar') Follow(NizNar) =

Drugi par smena je par (5) i (6).

First(Dodela) = {id}
First(Blok) = {begin}
First(Dodela) First(Blok) =

Nijedna od navedenih smena se ne preslikava u prazan skup.

Trei par smena je par (9) i (10).

First(+const Izraz') = {+}


First() = {}
First(+const Izraz') First() =

Samo jedna od navedenih smena se preslikava u prazan skup.

Follow(Izraz') = {;, end}


First(+const Izraz') Follow(Izraz') =

Gramatika G ispunjava uslove LL-1 gramatike.

Zadatak 2 Odrediti tablicu sintaksne analize za LL-1 gramatiku zadatu


sledeim skupom pravila:

S aT T SA | A
A bB | c Bd|

Reenje. Sintaksna tabela za zadatu gramatiku data je u tabeli 6.1.

6.6 Pitanja
1. Dati deniciju proste LL-1 gramatike.

2. Kako je denisana sintaksna tabela proste LL-1 gramatike?

3. Objasniti algoritam za sintaksnu analizu proste LL-1 gramatike.

4. Objasniti pojam leve faktorizacije.

5. Dati deniciju funkcije First.


6. Dati deniciju funkcije Follow.
7. Dati deniciju LL-1 gramatika bez pravila.

8. Kako se popunjava sintaksna tabela kod LL-1 gramatika bez pravila?


108 GLAVA 6. PREDIKTIVNA ANALIZA  LL-1 ANALIZATORI

Tabela 6.1

Vrh Ulazni simbol


magacina a b c d #

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

9. Dati deniciju LL-1 gramatika sa pravilima.

10. Kako se popunjava sintaksna tabela kod LL-1 gramatika sa pravilima?

6.7 Zadaci
1. Za LL-1 gramatiku zadatu skupom smena

E (E) T | i T T +E | E |

generisati tablicu sintaksne analize.

2. Gramatika G zadata je skupom smena

S aaSd | aAd A bAc | b.

Transformisati gramatiku G u LL-1 gramatiku, odrediti tablicu sintak-


sne analize i korienjem formirane tabele proveriti da li niz #aaababcd#
pripada jeziku koji je odreen ovom gramatikom.

3. Utvrditi da li je gramatika zadata skupom smena

A aBC | bB B CbA | c | C aBa | cBaC |

LL-1 gramatika. Ako jeste, formirati odgovarajuu tablicu sintaksne ana-


lize.
6.7. ZADACI 109

4. Generisati LL-1 sintaksnu tabelu gramatike koja je denisana skupom


smena

E (E) T | const T T +E | E | .
Korienjem generisane tabele proveriti da li izraz

# const (const + const)#


pripada jeziku date gramatike.

5. Transformisati gramatiku G zadatu skupom smena

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.

6. Proveriti da li gramatika zadata sledeim skupom smena P zadovoljava


uslove LL-1 gramatika i, ako zadovoljava, kreirati njenu sintaksnu tabelu.

S aT T SA | A
A bB | c Bd|

7. Proveriti da li je gramatika zadata skupom smena

S aT T SA | A
A bB | c Bd|
tipa LL-1. Ako jeste, kreirati njenu sintaksnu tabelu.

8. LL-2 gramatiku koja je zadata skupom smena

S aaSd | abAd S baAc | bc


transformisati u LL-1 gramatiku, odrediti sintaksnu tabelu i korienjem
formirane tabele proveriti da li niz

#aaabbcdd#
pripada jeziku koji je odreen ovom gramatikom.

9. Formirati LL-1 sintaksnu tabelu gramatike zadate skupom smena

S if b then S E | a
E else S | .
Korienjem formirane tabele proveriti da li niz

# if b then a else if b then a#


pripada jeziku koji je denisan ovom gramatikom.
110 GLAVA 6. PREDIKTIVNA ANALIZA  LL-1 ANALIZATORI
Glava 7

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.

7.1 Relacije prvenstva


Denicija: Operatorske gramatike su beskonteksne gramatike kod kojih ne
postoje pravila u kojima se u rei na desnoj strani javljaju dva neterminalna
simbola jedan do drugog, odnosno ne postoje pravila oblika

C AB gde je A, B, C Vn i , V .

Da bi mogao uspeno da se sprovede postupak sintaksne analize, izmeu termi-


nalnih simbola operatorske gramatike deniu se relacije prvenstva (prioriteta).


Postoje tri osnovne relacije prvenstva: < , >
i =.

7.1.1 Relacija istog prioriteta



Terminalni simboli aib su u relaciji istog prioriteta, u oznaci a = b, ako i samo
ako postoji smena oblika

C ab ili C aAb, gde je C, A Vn , a, b Vt , , V .

111
112 GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA

C C

a b a A b

Slika 7.1: Relacija istog prioriteta (a = b)

C C


a A
A b

b a

Slika 7.2: Relacija nieg (a < b) i vieg (a >


b) prioriteta

Ako se to predstavi na sintaksnom stablu, onda znai da se terminalni simboli


aib pojavljuju na istom nivou sintaksnog stabla (slika 7.1).

7.1.2 Relacija nieg prioriteta


Terminalni simbol a je nieg prioriteta u odnosu na terminalni simbol b, u oznaci
a < b, ako i samo ako postoji smena oblika:


C aA i A
b ili A
Db

gde je C, A, D Vn , a, b Vt , , , V . Predstavljeno na sintaksnom


stablu to znai da se terminalni simbol a pojavljuje levo i na viem nivou u
odnosu na terminalni simbol b (slika 7.2, levo).

7.1.3 Relacija vieg prioriteta


Terminalni simbol a je vieg prioriteta u odnosu na terminalni simbol b, u oznaci
b,
a> ako i samo ako postoji smena oblika:


C Ab i A
a ili A
aD,

gde je C, A, D Vn , a, b Vt , , , V . Posmatrano na sintaksnom stablu


to znai da se terminalni simbol a pojavljuje levo od terminalnog simbola b ali
na nekom niem nivou (slika 7.2, desno).
7.2. OPERATORSKA GRAMATIKA PRVENSTVA 113

7.2 Operatorska gramatika prvenstva

Operatorska gramatika u kojoj za svaka dva terminalna simbola vai najvie


jedna relacija prvenstva naziva se operatorska gramatika prvenstva. Kod ovih
gramatika mogue je primeniti algoritam za bottom-up analizu u kome nee biti
povratnih petlji.

U postupaku sintaksne analize operatorskih gramatika prvenstva koristi se po-


mona sintaksna tabela (operatorska tabela prvenstva). To je tabela sa onoliko
vrsta i kolona koliko je terminalnih simbola azbuke (ukljuujui i granini sim-
bol). Elementi operatorske tabele prvenstva su relacije prvenstva, pri emu se
simbol sa leve strane relacije uzima kao oznaka vrste, a simbol sa desne strane
relacije kao oznaka kolone.

Primer 7.1 Relacije prvenstva


Za operatorsku gramatiku prvenstva denisanu skupom smena

E E+T |T
T T F |F
F id

odrediti tablicu prvenstva.

Odreivanje relacija prvenstva. Da bi se odredile relacije prvenstva


izmeu graninih simbola i ostalih simbola gramatike uvodi se pomona
smena oblika
S 0 #S#
gde je S startni simbol gramatike.

Kako je E startni simbol gramatike iz naeg primera, uvodi se smena

E 0 #E#.

Kako bismo uoili relacije prvenstva, polazimo od startnog simbola gra-


matike i generiemo fraze tog simbola, odnosno rei koje koje se izvode
od tog simbola. Pri tome uoavamo relacije izmeu terminalnih simbola.
Taj postupak se nastavlja daljim uvoenjem smena sve dok se ne uoe sve
relacije izmeu terminalnih simbola (tabela 7.1). Napomenimo da su u toj
tabeli prikazane smene koje su primenjene, niz koji se generie, deo sintak-
snog stabla i relacija koja se izvodi. U ovom postupku se primenjuje levo
izvoenje.

Odgovarajua operatorska tabela prvenstva je data u tabeli 7.2.


Tabela 7.1: Otkrivanje relacije prvenstva uz primer 7.1
GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA

Primenjena smena Izvedeni niz Stablo Uoene relacije


# = #a

E 0 #E# #E# slika 7.3 (a)
E E+T #E + T # slika 7.3 (b) # < +, + >
#
E E+T #E + T + T # slika 7.3 (c) +
+>
E Tb #T + T + T # slika 7.3 (d) nema
T T F #T F + T + T # slika 7.3 (e) # < , >
+
T T F #T F F + T + T # slika 7.3 (f) >

T F #F F F + T + T # slika 7.4 (g) nema
F id #id F F + T + T # slika 7.4 (h) # < id, id >

F id #id id F + T + T # slika 7.4 (i) < id, id >

F id #id id id + T + T # slika 7.4 (j) +
i>
T T F #id id id + T F + T # slika 7.5 (k) + < , < +
T F #id id id + F F + T # slika 7.5 (l) nema
F id #id id id + id F + T # slika 7.5 (m) + < id
F id #id id id + id id + T # slika 7.6 (n) id >
+
T T F #id id id + id id + T F # slika 7.6 (o) >
#
T F , F id, F id #id id id + id id + id id# slika 7.6 (p) #
i>
a ova relacija ne utie na postupak analize
114

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

(a) (b) (c)


E0 E0 E0

# E # # E # # E #

E + T E + T

E + T

(d) (e) (f)


E0 E0 E0

# E # # E # # E #

E + T E + T E + T

E + T E + T E + T

T T T

T F T F

T F

Slika 7.3: Sintaksna stabla uz tabelu 7.2 (prvi deo)


GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA

(g) (h) (i) (j)


E0 E0 E0 E0
# E # # E # # E # # E #
E + T E + T E + T E + T
E + T E + T E + T E + T
T T T T
T F T F T F T F
T F T F T F T F id
F F F id F id
id id id
Slika 7.4: Sintaksna stabla uz tabelu 7.2 (drugi deo)
116
(k) (l) (m)
E0 E0 E0

# 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

Slika 7.5: Sintaksna stabla uz tabelu 7.2 (trei deo)


117
GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA

(n) (o) (p)


E0 E0 E0
# E # # E # # E #
E + T
E + T E + T
id id id + T T * F T * F
id id id + id id id id id + id id
T F F id
F id id
id
Slika 7.6: Sintaksna stabla uz tabelu 7.2 (etvrti deo)
118
7.2. OPERATORSKA GRAMATIKA PRVENSTVA 119

Tabela 7.2: Operatorska tabela iz primera 7.1

id + #
id
>
>
>
+ <
> <
>
<
>
>
>

# < < < =

7.2.1 Postupak sintaksne analize


Kada je jezik denisan operatorskom gramatikom prvenstva mogue je deni-
sati bottom-up postupak sintaksne analize bez povratnih koraka. U postupku
sintaksne analize, prati se stanje ulaznog niza (t) i pomonog magacina () i
izvravaju se sledei koraci:

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.

2. Ako vai relacija


> treba ii dublje u stek i traiti prvi terminal u steku
koji je < od svog sledbenika u steku i proveriti da li fraza sa vrha steka (od
uoenog simbola do vrha, fraza izmeu simbola < i )
> predstavlja desnu
stranu neke smene. Ako takva smena postoji, treba izvriti redukciju,
tj. umesto uoene fraze u stek ubaciti uniformnu oznaku neterminalnog
simbola (P ). U suprotnom, ako takva fraza ne postoji kao desna strana
smene, u zapisu postoji greka i dalju analizu treba prekinuti. Kada se
redukcija uspeno izvede treba ispitati da li je sledei ulazni simbol #, a
sadraj steka #P . U tom sluaju ceo ulazni niz redukovan, tj. prepoznat.

3. Ako ne postoji ni jedna od navedenih relacija znai da u zapisu postoji


greka i dalju analizu treba prekinuti.

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.

Kompletan sintaksni analizator dat je u vidu pseudokoda (algoritam 1).


120 GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA

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

Primer 7.2 Postupak sintaksne analize


Za operatorsku gramatiku prvenstva razmatranu u primeru 7.1, postupak
sintaksne analize izraza #id + id id# prikazan je u sledeoj tabeli.

Radni magacin Ulazni niz Relacija prvenstva

# 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

7.2.2 Funkcije prvenstva


Memorija potrebna za pamenje tabela prvenstva je (n + 1) (n + 1) (gde je
n broj terminalnih simbola gramatike). Kod gramatika sa mnogo terminalnih
simbola ova tabela moe da bude veoma velika i da zahteva mnogo memorijskog
prostora. Zato se umesto tabele prvenstva esto relacije pamte preko funkcija
prvenstva. Za svaki terminalni simbol gramatike deniu se po dve celobrojne
funkcije f i g koje zadovoljavaju sledee uslove:

a < b f (a) < g(b),



a = b f (a) = g(b),
b f (a) > g(b).
a>

Uoimo da je memorijski prostor potreban za pamenje funkcija prvenstva 2


(n + 1).
Za odreivanje funkcije prvenstva formira se orijentisani graf koji ima 2n vo-
rova. Potezi u grafu se odreuju na sledei nain:

Ako vai relacija b,


a> postoji poteg od vora f (a) prema voru g(b).
122 GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA

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.

Primer 7.3 Funkcije prvenstva


Graf za odreivanje vrdnosti funkcija prvenstva za gramatiku razmatranu
u primeru 7.1 predstavljen je na slici 7.7.

Na primer, najdui put koji polazi iz vora g(i) je put

g(i) f () g() f (+) g(+) f (#),

pa je vrednost funkcije g(i) = 6.

i + #
F 5 3 5 0
G 6 2 4 0

7.3 Opta pravila prioriteta


Kako su operatorske gramatike prvenstva pogodne za opis izraza u programskim
jezicima, gramatike prvenstva treba da budu tako denisane da zadravaju pri-
oritete operatora koji vae u samom programskom jeziku. Neka opta pravila
prikazana su u tabeli 7.3, pri emu vae sledee relacije:

1. Ako je operator Q1 veeg prioriteta u odnosu na operator Q2 , tada relacije


prioriteta treba da budu postavljene tako da je

Q2
Q1 > i Q2 < Q1 .

Na primer, za operatore i+ treba da vai >


+ i + < .
Time se postie da se u reeninim formama E +E E +E prvo redukuje
fraza E E.
2. Ako su Q1 i Q2 operatori istog prioriteta (to vai i u sluaju kada su u
pitanju isti operatori), tada relacija prioriteta treba da bude postavljena
tako da je

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(#)

Slika 7.7: Graf za odreivanje funkcija prvenstva uz primer 7.3

Q1 < Q2 i Q2 < Q1 , ako su operatori desno asocijativni.

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>

4. Otvorena zagrada je nieg prioriteta od ostalih simbola, dok je zatvorena


zagrada vieg prioriteta od svih simbola. Takodje, svi ostali operatori
su nieg prioriteta od otvorene zagrade, a vieg prioriteta od zatvorene.
Ovim se postie da se izraz u zagradi redukuje pre konteksta u kome se
nalazi, to je i namena zagrada.

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

da postoji, zato to u programskim jezicima izmeu zatvorene zagrade i


sledee otvorene zagrade mora da stoji operator.

5. Identikator je uvek vieg prioriteta u odnosu na susedne simbole, dok su


svu svi ostali simboli nieg prioriteta od identikatora.

Q < id id >
Q # < id id >
# ( < id id >
)

Tabela 7.3: Opte relacije prioriteta

+ / id ( ) #
+
>
> < < < < <
>
>

>
> < < < < <
>
>

>
>
>
> < < <
>
>
/
>
>
>
> < < <
>
>

>
>
>
> < < <
>
>
id
>
>
>
>
>
>
>

( < < < < < < < =
)
>
>
>
>
>
>
>

# < < < < < < < =

7.4 Gramatike prvenstva


Relacije prvenstva mogue je denisati tako da se odnose i na neterminalne
simbole. Pri tome e vaiti:

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.

Za svaku gramatiku prvenstva moe se generisati jednoznano popunjena tablica


prvenstva u koju se upisuju relacije prvenstva. Ova tablica ima onoliko vrsta
7.4. GRAMATIKE PRVENSTVA 125

i kolona koliko gramatika ima ukupno simbola i terminalnih i neterminalnih.


Tablica prvenstva koristi se u postupku sintaksne analize na isti nain kao i kod
operatorskih gramatika prvenstva.

Primer 7.4 Gramatika prvenstva


Gramatiku zadatu sledeim skupom smena

Program start NizNaredbi end


NizNaredbi NizNaredbi ; Naredba | Naredba
Naredba ulaz | izlaz | dodela

transformisaemo u gramatiku prvenstva i kreirati njenu tablicu prvenstva.

Da bi gramatika bila gramatika prvenstva izmeu svaka dva simbola moe


da vai najvie jedna relacija prvenstva. Najpre proveravamo ovaj uslov.

Na osnovu prve smene gramatike moe se zakljuiti da postoji relacija:

start = NizNaredbi.

Ukoliko se NizNaredbi preslika po prvoj smeni za taj neterminalni simbol,


dobija se niz oblika:

start NizNaredbi ; Naredba end,


odakle se moe zakljuiti da vai relacija:

start < NizNaredbi.

To znai da relacija prvenstva izmeu simbola start i NizNaredbi nije jed-


noznano denisana. Ovakva situacija e se javiti uvek kada postoji smena
oblika X A i uz nju postoji levo rekurzivna smenaA A, gde
nije prazan niz; ili postoji smena X A , gde nije prazan niz i uz
nju desno rekurzivna smena A A. U tom sluaju potrebno je izvriti
sledee transformacije. Skup smena

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

Transformisana gramatika iz naeg primera bie:

Program start NizNaredbi end


NizNaredbi NizNaredbi'
NizNaredbi NizNaredbi' ; NizNaredbi | NizNaredbi
Naredba ulaz | izlaz | dodela

Nastavljamo sa odreivanjem relacija prvenstva.

Zbog kraeg pisanja uveemo sledee oznake neterminalnih simbola:

Program P
NizNaredbi N
NizNaredbi' NN'
Naredba N

Da bi se odredile relacije prvenstva izmeu graninih simbola i ostalih


simbola gramatike uvodimo i pomonu smenu oblika

P 0 # P #.

U tabeli 7.4 je predstavljen postupak otkrivanja relacija prvenstva izmeu


svih simbola.

Kao rezultat ove analize dobija se tabela prvenstva data u tabeli 7.5.

7.4.1 Postupak sintaksne analize


Bottom-up postupak sintaksne analize gramatika prvenstva je veoma slian sin-
taksnoj analizi operatorskih gramatika prvenstva. I u ovom sluaju prati se
stanje ulaznog niza (t) i pomonog steka (). Ulazni niz (t) dopuni se grani-
nim simbolom (#) sa desne strane. Isti granini simbol smeta se i u pomoni
stek (). Zatim se, na osnovu relacije prvenstva koja vai izmeu poslednjeg
simbola u steku i sledeeg simbola u ulaznom nizu, odreuje akcija koja e se
Primenjena smena Izvedeni niz Stablo Relacije prvenstva

P 0 #P # #P # slika 7.8 # = P, P =#

P start NN end #start NN end # # < start, start = NN, NN = eq, #
end >
NN NN' #start NN' end # start < NN', NN' >
end

NN' NN' ; N #start NN' ; N end # NN' = ;, ; = N, N>
end
7.4. GRAMATIKE PRVENSTVA

NN' N #start N ; N end # start < N , N>


;
N ulaz #start ulaz ; N end # slika 7.9 start < ulaz, ulaz >
;
ili: N dodela #start dodela ; N end # start < dodela, dodela >
;
ili: N izlaz #start izlaz ; N end # start < izlaz, ulaz >
;
N ulaz #start izlaz ; ulaz # ; < ulaz, ulaz >
end
ili: N dodela #start izlaz ; dodela # ; < dodela, dodela >
end
ili: N izlaz #start izlaz ; izlaz # ; < izlaz, izlaz >
end

Tabela 7.4: Otkrivanje relacija prvenstva za gramatiku prvenstva iz primera 7.4


127
128 GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA

P0 P0 P0

# P # # P # # P #

start NN end start NN end

NN'

P0 P0

# P # # P #

start NN end start NN end

NN' NN'

NN' ; N NN' ; N

Slika 7.8: Sintaksna stabla uz tabelu 7.4 (prvi deo)


7.4. GRAMATIKE PRVENSTVA 129

P0 P0 P0

# P # # P # # P #

start NN end start NN end start NN end

NN' NN' NN'

NN' ; N NN' ; N NN' ; N

N N N

ulaz dodela izlaz

P0 P0 P0

# P # # P # # P #

start NN end start NN end start NN end

NN' NN' NN'

NN' ; N NN' ; N NN' ; N

N ulaz N dodela N izlaz

izlaz izlaz izlaz


Slika 7.9: Sintaksna stabla uz tabelu 7.4 (drugi deo)
130 GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA

Tabela 7.5: Tabela prvenstva razmatrane gramatike prvenstva iz primera 7.4

P NN NN' N start end ulaz izlaz dodela ; #



P =

NN =

NN'
> =

N = < < < < <
start
>
ulaz
>
>
izlaz
>
>
dodela
>
>
; =

< < <

# = <

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.

3. Ako ne postoji ni jedna od navedenih relacija znai da u zapisu postoji


greka i dalju analizu treba prekinuti.

Kompletan bottom-up sintaksni analizator gramatika prvenstva dat je u vidu


pseudokoda kao algoritam 2

Primer 7.5 Postupak sintaksne analize gramatike prvenstva


Za gramatiku prvenstva razmatranu u Primeru 7.4 izvriemo sintaksnu
analizu niza
start ulaz ; dodela ; izlaz end.
7.4. GRAMATIKE PRVENSTVA 131

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

U postupku analize datog niza koristie se tablica prvenstva predstavljena


u tabeli 7.6. U poslednjoj koloni ove tabele upisana je relacija prvenstva
izmeu simbola u vrhu magacina i simbola na ulazu. X u poslednjem redu
iznaava da je analiza uspeno zavrena.

Tabela 7.6: Analiza izraza za gramatiku iz primera 7.5.

Radni magacin () next Relacija 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

Isto kao kod operatorskih gramatika prvenstva, i u sluaju gramatika prvenstva


umesto tablice prioriteta mogu se denisati funkcije prvenstva. Ovde to ima jo
vie smisla zato to ima mnogo vie simbola izmeu kojih se posmatraju relacije
tako da su tablice veih dimenzija ali retko popunjene.

7.5 Pitanja

1. Dati deniciju operatorskih gramatika.


7.6. ZADACI 133

2. Denisati osnovne relacije prvenstva kod operatorskih gramatika prven-


stva.

3. Dati deniciju operatorske gramatike prvenstva.

4. ta je to operatorska tablica prvenstva? Dati primer.

5. ta su to funkcije prvenstva i kako se odreuju?

6. Opisati algoritam za sintaksnu analizu operatorskih gramatika prvenstva.

7. Dati deniciju relacija prvenstva kod gramatika prvenstva.

8. Dati deniciju gramatika prvenstva.

9. ta je to tablica prvenstva i kako se popunjava.

10. Opisati algoritam za sintaksnu analizu gramatika prvenstva.

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.

2. Kreirati operatorsku tablicu prvenstva gramatike koja je zadata sledeim


skupom smena

SS+I|I
I ( S ) | f ( S ) | id

Korienjem kreirane tabele proveriti da li niz

# id + f ( id + f ( id ) ) ) #

pripada jeziku koji je denisan ovom gramatikom.

3. Formirati operatorsku tablicu prvenstva za gramatiku G zadatu sledeim


skupom smena:

SP
P R or Q | Q
QT
T T and R | R
R V | not V
V ( S ) | true | false.

4. Formirati tablicu prvenstva za gramatiku G iz prethodnog zadatka.


134 GLAVA 7. ANALIZA ZASNOVANA NA RELACIJAMA PRVENSTVA

5. Kreirati operatorsku tablicu prvenstva za gramatiku zadatu skupom smena:

Ulaz READ ( NizPromenljivih )


NizPromenljivih NizPromenljivih , id | id.

Korienjem kreirane tablice proveriti da li izraz

# READ ( id , id , ) #

pripada jeziku date gramatike.

6. Gramatika G za denisanje tipa enum u programskom jeziku C zadata je


sledeim skupom smena:

EnumType enum id { ConstantList } ;


ConstantList ConstantList , ConstantDenition
ConstantList ConstantDenition
ConstantDenition id
ConstantDenition id = const

Transformisati datu gramatiku u gramatiku prvenstva, kreirati tablicu


prvenstava i proveriti da li zapis

enum id { id , id = const } ;
pripada jeziku ove gramatike.

7. Operatorska gramatika prvenstva zadata je sledeim skupom smena.

S S+I |I
I (S) | a(S) | a

(a) Formirati operatorsku tablicu prvenstva zadate gramatike.

(b) Proveriti da li niz # a(a + a) # pripada jeziku date gramatike.


Glava 8

LR analizatori

U ovom poglavlju bie rei o karaktiristikama i projektovanju LR analizatora


koji se najee sreu u komercijalnim reenjima kompilatora. Radi se o e-
kasnim bottom-up analizatorima. U optem sluaju to mogu da budu LR(k)
analizatori gde ova skraenica ukazuje na njihove opte karakteristike:

L  (left ) ulazni niz se analizira sleva udesno;

R  (right ) dobijaju se paravila koja odgovaraju desnom izvoenju;

k  broj slova na osnovu kojih se vri predikcija (ako k nije navedeno,


podrazumeva se jedno slovo).

LR analizatorima mogu da se prepoznaju sve programske konstrukcije koje se


mogu opisati beskonteksnim gramatikama. To je najoptiji metod za bottom-up
analizu bez povratnih petlji koji se lako implementira. Klasa gramatika koje se
prepoznaju LR analizatorima je nadskup klase gramatika kod kojih je mogua
LL analiza. Takoe, omoguavaju najbre mogue otkrivanje greaka, onoliko
brzo koliko je to uopte mogue kod analizatora koji prolaze kroz ulazni niz
sleva udesno.

8.1 Opis analizatora


ema LR analizatora prikazana je na slici 8.1. U sutini to je automat koji kao
radnu memoriju koristi magacin.

Simbol na vrhu radnog magacina je trenutno stanje LR sintaksnog analizatora


i on sumira informacije smetene u stek pre njega.

Postupak sintaksne analize je upravljan LR sintaksnom tabelom. Ona se sastoji


od: akcija i prelaza. Ova sintaksna tabela ima onoliko vrsta koliko je moguih
stanja sintaksnog analizatora. U delu za akcije postoji onoliko kolona koliko

135
136 GLAVA 8. LR ANALIZATORI

ulazni niz
# a1 a2 ai an #

LR sintaksni

magacin
Sn
analizator
Xn

Sn1

Xn1 prelazi akcije

LR sintaksna tabela
.
.
.

S0

Slika 8.1: LR sintaksni analizator

je terminalnih simbola gramatike (ukljuujui i granini simbol), a u delu za


prelaze broj kolona jednak je broju neterminalnih simbola gramatike. U delu
za akcije denisani su prelazi koji e se izvriti zavisno od stanja koje se nalazi
na vrhu radnog magacina i tekueg simbola u ulaznom nizu.

Akcija moe biti:

sp  (shift p)  znai da u magacin treba smestiti tekui simbol iz ulaznog


niza i naredno stanje (p) i prei na analizu sledeeg simbola iz ulaznog
niza;

rk  (reduce k)  znai da treba izvriti redukciju primenom smene (k ).


Ako je, na primer, smena (k ) A , iz magacina treba izbaciti 2length()
elemenata, u magacin smestiti neterminalni simbol A (simbol sa leve
strane smene (k )), a novo stanje proitati iz dela prelazi u sintaksnoj ta-
beli, kao prelaz iz prethodnog stanja u magacinu pod dejstvom ubaenog
neterminalnog simbola (A).

acc (accept )  znai da je niz prepoznat i dalju analizu treba prekinuti;

err (error )  znai da u ulaznom nizu postoji greka i teba prekinuti dalju
analizu.
8.1. OPIS ANALIZATORA 137

8.1.1 Shift-reduce algoritam analize


LR analizatori su poznati i kao Shift-reduce analizatori, to znai da se kroz
ulazni niz prolazi sleva udesno i nastoji se da se izvri redukcija (reduce ), ako
redukcija nije mogua prelazi se na sledei znak u nizu (shift ). Za razliku od
osnovnog algoritma za bottom-up analizu koji je praktino brute-force algori-
tam, kod ovih analizatora se analizom smena gramatike generie LR sintaksna
tabela koja odreuje promenu stanja u automatu u zavisnosti od tekueg ula-
znog simbola i nema povratnih koraka.

Postaviti ulazni pokaziva ip na poetak niza w# koji se analizira;


while true do
Neka je q znak u vrhu magacina;
Neka je a znak na koji pokazuje ulazni pokaziva ip;
if action(q, a) = shift then
Ubaciti u magacin a, a zatim i p;
Pomeriti ulazni pokaziva ip za jedno mesto udesno;
end
else if action(s, a) = reduce k, pri emu je k-ta smena gramatike A
then
Izbaciti 2 || simbola iz steka;
Ubaciti A u stek;
Ubaciti u stek oznaku stanja koja se dobija na osnovu goto(s0 , A), gde
0
je s oznaka stanja u koje smo se vratili posle redukcije;
end
else if action(s, #) = accept then return;
else error;
end
Algorithm 3: LR Sintaksni analizator
Ako konguraciju automata oznaimo sa

(s0 , X1 , s1 , X2 , s2 , . . . , Xm , sm , ai , ai+1 , . . . , an , #),


gde je s0 , X1 , s1 , X2 , s2 , . . . , Xm , sm niz u magacinu, pri emu je sm oznaka
stanja koje je u vrhu magacina, ai , ai+1 , . . . , an , #  ulazni niz i ai  slovo koje
se u datom trenutku prepoznaje, preslikavanja u automatu se mogu predstaviti
i na sledei nain.

Ako je action(sm , ai ) = reduce k i k -ta smena A ,


onda (s0 , X1 , s1 , X2 , s2 , . . . , Xmr , smr , A, s, ai , ai+1 , . . . , an , #)
s = goto(smr , A), r = ||

Ako je action(sm , ai ) = shift p,


onda (s0 , X1 , s1 , X2 , s2 , . . . , Xm , sm , ai , p, ai+1 , . . . , an , #)
138 GLAVA 8. LR ANALIZATORI

Primer 8.1 LR alanizator


Gramatika G je denisana sledeim skupom pravila.

E E+T (1)

ET (2)

E EF (3)

T F (4)

F (F ) (5)

F id (6)

LR sintaksni analizator je odreen sledeom LR sintaksnom tabelom.

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

Postupak LR analize za re # id id + id # prikazan je u sledeoj tabeli.


8.2. REALIZACIJA LR ANALIZATORA 139

Niz u magacinu Ulazni niz Akcija automata

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

Analiza rei je uspeno zavrena.

8.2 Realizacija LR analizatora


LR analizator se realizuje kao automat koji prepoznaje sve prekse koji mogu
da nastanu u procesu generisanja rei jezka koji je opisan gramatikom za koju
se vri analiza.

8.2.1 Vidljivi preksi


U reeninoj formi t, gde je fraza koja se generie, vidljivi preksi niza
su svi preksi niza , ukljuujui i sam niz .
Za = u1 u2 . . . ur , preksi su oblika u1 u2 . . . ui (1 i r).

Primer 8.2 Vidljivi preksi


140 GLAVA 8. LR ANALIZATORI

Za gramatiku G iz primera 8.1, jedno od moguih izvoenja je

E E+T
E+F
E + id
E + T + id
E + F + id.

Na osnovu ovog izvoenja, moemo da odredimo vidljive prekse za frazu F:

E, E+ i E + F.

Izvoenje iz prethodnog primera predstavljeno je sledeim sintaksnim stablom.

E + T

E + T F

F id

Ako se stanje prikazano na sintaksnom stablu posmatra kao jedan trenutak u


postupku bottom-up analize, moe se uoiti da se svi vidljivi preksi posmatrane
fraze u sintaksnom stablu nalaze levo od nje, dok se desno od nje nalazi niz
terminalnih simbola koje tek treba otkriti.

8.2.2 LR(k) gramatike


Posmatrajmo jedan korak u desnom izvoenju nekog niza: At t, gde je
A prvi neterminal sa desne strane koji se preslikava u niz primenom pravila
A . Oigledno je niz t sastavljen od terminalnih simbola.

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.

8.2.3 Tipovi LR analizatora


LR analizatori se realizuju kao automati koji prepoznaju vidljive prekse u
postupku generisanja rei jezika koji je opisan gramatikom. U zavisnosti od
8.3. REALIZACIJA SLR ANALIZATORA 141

toga koliko je kompleksan i kompletan postupak identikacije vidljivih preksa


razlikuje se vie vrsta LR analizatora:

SLR (Simple LR )  jednostavan za konstrukciju ali moe da se dogodi da


se za neke gramatike ne moe sastaviti tablica sintaksne analize;

kanoniki LR  najmoniji ali i najskuplji i najsloeniji postupak projek-


tovanja;

LALR (Look-Ahead Left Right )  izmeu prva dva i po ceni i po perfor-


mansama.

8.3 Realizacija SLR analizatora

Realizacija SLR analizatora se zasniva na deniciji tzv. LR(0) lanova i primeni


funkcije closure za zatvaranje LR(0) lanova i funkcijegoto za inicijalizaciju
novog skupa LR(0) lanova.

8.3.1 LR(0) lanovi


LR(0) lanovi se generiu na osnovu pravila gramatike i svako pravilo gramatike
daje nekoliko LR(0) lanova u zavisnosti od duine rei na desnoj strani pravi

Izvoenje (na osnovu nekog pravila) sa takom u bilo kojoj poziciji u nizu se
naziva LR(0) lan.

Primer 8.3 LR(0) lanovi


Za gramatiku iz primera 8.1 na osnovu pravila mogu se generisati sledei
LR(0) lanovi.

E E + T
E E +T
E E + T
EE + T

LR(0) lanovi e se u postupku sinteze LR analizatora koristiti da se prate


vidljivi preksi koji su uzeti u obzir. Naime, taka praktino razdvaja vidljeive
prekse od neprepoznatog dela rei.
142 GLAVA 8. LR ANALIZATORI

8.3.2 Funkcija zatvaranja (closure)


Ako je I skup LR(0) lanova gramatike G, tada je closure(I) skup LR(0) lanova
koji se dobijaju primenom sledeih pravila

1. Inicijalno svaki LR(0) lan skupa I ukljuuje se u skup closure(I).


2. Ako A B pripada skupu closure(I) i postoji pravilo gramatike
oblika B , tada se skupu closure(I) pridodaje i lan B , ako ve
ne postoji u tom skupu. Ovo pravilo se primenjuje sve dok je to mogue.

8.3.3 Funkcija iniciranja novih skupova LR(0) lanova (goto)


Funkcija pomou koje se inicira stvaranje novog skupa LR(0) lanova denie
se kao goto(I, X) gde je I skup LR(0) lanova, a X slovo azbuke.

Na osnovu svakog LR(0) lana oblika A X iz skupa I denie se novi


skup LR(0) lanova goto(I, X) kao zatvaranje svih lanova A X .
Ako je I skup lanova koji su znaajni za preks , tada je goto(I, X) skup svih
LR(0) lanova koji su znaajni za preks X .

8.3.4 Postupak sinteze LR analizatorata


Sinteza LR analizatora se svodi na generisanje LR sintaksne tabele, pri emu se
razlikuju sledee tri faze.

1. Odreivanje kanonikog skupa LR lanova koji obuhvata sve vidljive pre-


kse rei jezika koji je opisan gramatikom. Odreivanje kanonikog skupa
kree od LR(0) lana S 0 S koji se formira na osnovu ktivne smene
0
S S, gde je S startni simbol gramatike. Nakon formiranja ovog po-
etnog LR(0) lana primenjuju se funkcije closure i goto sve dok je to
mogue. Rezultat ovog koraka je kanoniki skup zatvaranja LR(0) la-
nova K = {I0 , I1 , . . . , Ik }.
2. Crtanje grafa prelaza konanog automata za prepoznavanje vidljivih pre-
ksa pri emu vae sledea pravila:

(a) Svakom zatvaranju iz kanonikog skupa pravila K = {I0 , I1 , . . . , Ik }


dodeljuje se jedno stanje u grafu automata .

(b) Potezi u grafu odreeni su goto funkcijama iz kanonikog skupa LR(0)


pri emu, ako je goto(Ii , X) = Ij , onda postoji odlazni poteg iz stanja
Ii do stanja Ij za slovo X , gde je X V.
(c) Sva stanja automata koja odgovaraju zatvaranjima LR(0) lanova
kojima pripadaju lanovi oblika A su zavrna stanja (stanja
redukcije za pravila A ).
8.3. REALIZACIJA SLR ANALIZATORA 143

(d) Stanje kome pripada LR(0) lan S 0 S , nastao na osnovu ktivne


smene je poetno stanje automata.

3. Popunjavanje LR sintaksne tabele koje se vri primenom sledeih pravila:

(a) Ako [A a ] Ii i goto(Ii , a) = Ij , tada je action(i, a) = shift j ,


a Vt .
(b) Ako [A ] Ii , tada je action(i, a) = reduce(A ) za a
Follow(A), A 6= S 0 .
(c) Ako [S 0 S] Ii , tada je action(i, #) = accept.

Primer 8.4 Sinteza LR analizatora


Izvriemo sintezu LR analizatora za gramatiku G, denisanu sledeim
pravilima.

E E+T (1)

ET (2)

T T F (3)

T F (4)

F (E) (5)

F id (6)

Startni simbol ove gramatike je E zbog ega skupu smena dodajemo i


ktivnu smenu E0 E.
Na osnovu ove ktivne smene formiramo inicijalni LR(0) lan E 0 E od
kojeg poinjemo formiranje kanonike kolekcije LR(0) lanova.

Ukljuujemo inicijalni lan E 0 E u skup I0 i vrimo zatvaranje ovog


skupa primenom funkcije closure. Kako se taka nalazi ispred neterminal-
nog simbola E , skupu se pridruuju svi inicijalni LR(0) lanovi koji nastaju
od pravila za neterminal E, a to su E E + T i E T .
Zatvaranje nastavljamo dalje. Kako skupu I0 sada pripada lan kod kojeg
se taka nalazi ispred neterminala T, skupu treba pridruiti inicijalne la-
nove koji nastaju na osnovu pravila za neterminal T, odnosno T T F
i T F .
Sada skupu pripada lan T F , kod kojeg je taka ispred neterminala
F, tako da skupu treba prikljuiti i lanove koji nastaju na osnovu pravila
za F, odnosno F (E) i F id.
144 GLAVA 8. LR ANALIZATORI

Zatvaranje skupa I0 je zavreno i kao rezultat se dobija:

E0 E
E E + T
E T
T T F
T F
F (E)
F id

Na osnovu LR(0) lanova iz skupa I0 , primenom funkcije goto formiraju


se novi skupovi. Tako na osnovu toga to skupu I0 pripadaju lanovi
E0 E i E E + T, E,
kod kojih se taka nalazi ispred neterminala
mogue je primeniti funkciju goto(I0 , E), koja kao rezultat daje skup I1
0
kome inicijalno prikljuujemo lanove E E i E E + T . Dalje bi
trebalo izvriti zatvaranje skupa I1 . Meutim, on je zatvoren sa ova dva
lana zato to se u jednom lanu taka nalazi na kraju, a u drugom je taka
ispred terminalnog simbola, a ne ispred neterminalnog.

Znai, dobili smo:

I1 = goto(I0 , T )
E0 E
E E +T

Na slian nain, primenom goto funkcije nad skupom I0 , nastaju i sledei


skupovi:

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

Nakon to smo iscrpili mogunosti primene funkcije goto nad skupom I0 ,


nastavljamo sa primenom ove funkcije nad novonastalim skupovima. Uz
to paralelno vrimo i zatvaranje svakog novonastalog skupa.

Kao rezultat primene funkcije goto nad skupom I1 nastaje:

I6 = goto(I1 , +)
E E + T
T F
T F
F (E)
F id

Funkcijom goto nad skupom I2 dobija se

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.

Primenom goto funkcije nad skupom I4 , dobija se jedan 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.

Od skupa I6 se generie jedan novi lan

I9 = goto(I6 , T )
E E + T
T T F

i nekoliko koji ve postoje:

goto(I6 , F ) = I3
goto(I6 , () = I4
goto(I6 , id) = I5

Ovaj postupak se nastavlja sve dok je mogue. Skup I7 daje

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

Dalja primena funkcije goto nije mogua. Ovim postupkom je odreena


kanonika kolekcija LR(0) lanova

C = {I0 , I1 , I2 , I3 , I4 , I5 , I6 , I7 , I8 , I9 , I10 , I11 },

na osnovu koje se generie LR sintaksna tabela i graf automata koji pre-


poznaje sve vidljive prekse gramatike.

Kao rezultat se dobija LR sintaksna tabela predstavljena uz primer 8.1,


dok je graf automata dat na slici 8.2.

8.4 Reeni zadaci


U ovom odeljku bie data reenja jo nekih zadataka ovog tipa.

Zadatak 3 Za gramatiku zadatu skupom smena

Program start NizNaredbi end


NizNaredbi NizNaredbi ; Naredba | Naredba
Naredba ulaz | izlaz | dodela

kreirati LR sintaksnu tabelu i, korienjem kreirane tabele, proveriti da li


je program
start ulaz ; dodela ; izlaz end
ispravno napisan.

Reenje. Kreiranje kanonikog skupa LR(0) lanova. Uvodimo smenu


P 0 P i deniemo prvo zatvaranje skupa LR pavila:
I0 : P 0 P.
Taka koja razdvaja vidljivi preks od neprepoznatog dela pravila se nalazi
ispred neterminalnog simbola to znai da u nastavku analize treba prepoznati
neterminalni simbol. Neterminalni simboli se ne pojavljuju u ulaznom kodu
pa prepoznavanje neterminalnog simbola podrazumeva, u stvari, prepoznavanje
desne strane neke od smena na ijoj se levoj strani nalazi taj simbol. Zbog toga
se ovom zatvaranju dodaje skup pravila izvedenih iz smena za preslikavanje tog
neterminalnog simbola sa takom na poetku. U ovom sluaju dodajemo lan

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

Slika 8.2: Graf automata LR analizaora iz primera 8.4


8.4. REENI ZADACI 149

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 )

Prepoznat je simbol P, vidljivi preks oznaen u pravilu (0, 1) se poveava 


taka se pomera iza prepoznatog simbola pa ovom zatvaranju pripada pravilo

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 :

Prepoznat je simbol start, vidljivi preks se poveava  taka se pomera iza


prepoznatog simbola pa zatvaranju I2 pripada pravilo

P start NN end.

Taka se nalazi ispred neterminalnog simbola NN, pa ovom zatvaranju pripadaju


i pravila

NN NN ; N
NN N

Poto ovom zatvaranju pripada i lan u kojem je taka sispred neterminalnog


simbola N, ovom zatvaranju treba dodati i lanove nastale na osnovu smena
koje na levoj strani imaju neterminal N.

N ulaz
N izlaz
N dodela

I3 = goto(I2 , NN :

Skupu I2 pripadaju dva lana u kojima je taka ispred simbola NN pa e zatva-


ranju I3 pripadati lanovi

I3 = goto(I2 , NN) P start NN end


NN NN ; N
150 GLAVA 8. LR ANALIZATORI

I4 = goto(I3 , end) P start NN end

Zatvaranju I4 pripada lan sa takom na kraju. Taj lan je izveden iz prve


smene gramatike. To znai da e stanje koje odgovara ovom zatvaranju biti
redukciono stanje za smenu (1).

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

Crtanje grafa prelaza konanog automata za prepoznavanje vidljivih


preksa. Za svako zatvaranje skupa LR lanova crtamo po jedan vor u grafu.
Potezi u grafu su odreeni prelazima koje smo denisali prilikom kreiranja ovog
skupa LR lanova. Na primer, zatvaranje I1 smo denisali kao prelaz iz stanja I0
kad se pojavi simbol P, pa u grafu postoji grana izmeu stanja I0 i I1 oznaena
simbolom P. Redukciona stanja se obeleavaju kao zavrna stanja u automatu.
Graf generisanog automata predstavljen je na slici 8.3.

Popunjavanje LR sintaksne tabele. Upis shift akcija. Svakom potegu koji


je oznaen terminalnim simbolom odgovara po jedna shift akcija. Na primer,
stanja I0 i I2 su povezana potegom koji je obeleen terminalnim simbolom start.
To znai da e akcija(0, start) biti s2. Stanja I3 i I4 su povezana potegom koji
je obeleen terminalnim simbolom end, pa je akcija(3, end) = s4, itd.

Popunjavanje prelaza u LR tabeli. Svakom potegu koji je oznaen neterminalnim


simbolom odgovara po jedan prelaz u LR sintaksnoj tabeli. Na primer, stanja
I0 i I1 su povezana potegom koji je obeleen neterminalnim simbolom P. To
znai da je prelaz(0, P ) = 1, itd.

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

Slika 8.3: Graf automata LR analizatora iz zadatka 3


152 GLAVA 8. LR ANALIZATORI

P start NN end izvedeno iz smene (1).


1
To znai da se u stanju I4 vri
redukcija po smeni (1) kada se na ulazu pojavi bilo koji simbol koji pripada
Follow funkciji za neterminalni simbol koji se nalazi na levoj strani smene, tj.
za simbol P. Kako je Follow(P ) = {#}, dobija se akcija(4, #) = r1.
Slino se deniu i ostale reduce akcije. Follow funkcije za ostale neterminalne
simbole su

Follow(N N ) = {end, ;}
Follow(N ) = Follow(NN) = {end, ;}.

Jedino zavrno stanje u kojem se ne vri redukcija je stanje I1 . Reeno je ve


da se redukcija po novouvedenoj pomonoj smeni ne vri, ve ako je cela ulazna
datoteka proitana (tj. sledei simbol je #), kod je kompletno ispravan pa je
akcija(1, #) = acc.
Generisana LR sintaksna tabela data je u tabeli 8.1.

Tabela 8.1: LR sintaksna tabela dobijena u zadatku 3

start end ; ulaz izlaz dodela # P NN N


0 s2 1

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

Analiza ulaznog niza. Postupak analize ulaznog niza

# start ulaz ; dodela ; izlaz end #


prikazan je u tabeli 8.2. Radi utede prostora u tabeli je prikazan samo simbol
ulaznog niza koji je na redu za prepoznavanje, a ne i ostatak niza.

1 Redukciono pravilo je pravilo koje odgovara lanu sa takom na kraju.


Niz u magacinu next Akcija automata

0 start s2

0 start 2 ulaz s8

0 start 2 ulaz 8 ; r4 (smena 4: N ulaz, prelaz(2, N ) = 7)


8.4. REENI ZADACI

0 start 2 N 7 ; r3 (smena 3: NN N , prelaz(2, NN) = 3)


0 start 2 NN 3 ; s5

0 start 2 NN ; 5 dodela s10

0 start 2 NN 3 ; 5 dodela 10 ; r6 (smena 6: N dodela, prelaz(5, N ) = 6)


0 start 2 NN 3 ; 5 N 6 ; r2 (smena 2: NN NN ; N, prelaz(2, NN) = 3)
0 start 2 NN 3 ; s5

0 start 2 NN 3 ; 5 izlaz s9

0 start 2 NN 3 ; 5 izlaz 9 end r5 (smena 5: N izlaz, prelaz(5, N ) = 6)


0 start 2 NN 3 ; 5 N 6 end r2 (smena 2: NN NN ; N, prelaz(2, NN) = 3)
0 start 2 NN 3 end s4

0 start 2 NN 3 end 4 # r1 (smena 1: P start NN end, prelaz(0, P ) = 1)


0P 1 # acc  niz je prepoznat

Tabela 8.2: Postupak analize zadatog niza iz zadatka 3.


153
154 GLAVA 8. LR ANALIZATORI

Zadatak 4 Formirati LR sintaksnu tabelu gramatike koja je zadata skupom


smena

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

Tabela 8.3: LR sintaksna tabela dobijena u zadatku 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.

2. Objasniti strukturu LR tablice sintaksne analize.

3. Objasniti postupak LR analize.


156 GLAVA 8. LR ANALIZATORI

4. Kako se deniu vidljivi preksi?

5. Kako se deniu LR(0) lanovi?

6. Denisati kanoniku kolekciju LR(0) lanova?

7. Kako se kanonika kolekcija LR(0) lanova preslikava u graf automata?

8. Kako se odreuju zavrna stanja automata?

9. Kako je odreeno poetno stanje automata?

10. Kako je preslikava kanonika kolekcija LR(0) lanova u LR sintaksnu ta-


belu?

11. Kako su odreena shift polja u LR sintaksnoj tabeli.

12. Kako su odreena reduce polja u LR sintaksnoj tabeli.

13. Kako je odreen deo sa prelazima u LR sintaksnoj tabeli.

8.6 Zadaci
1. Kreirati LR sintaksnu tabelu za gramatiku zadatu skupom smena

CaseList CaseListCaseItem | CaseItem


CaseItem case CONST : Assignment break ;
Assignment ID = Expression ;
Expression ID | CONST.

Korienjem kreirane tabele proveriti da li jeziku koji je denisan ovom


gramatikom pripada niz

case 1 : ID = CONST ;
case 2 : ID = ID ; break ;

2. Kreirati LR sintaksnu tabelu gramatike koja je denisana skupom smena

E ( E ) T | const T
T +E|E|

Korienjem kreirane tabele proveriti da li izraz

# const (const + const) #

pripada jeziku date gramatike.


8.6. ZADACI 157

3. Za gramatiku G zadatu skupom smena

Ulaz read ( NizPromenljivih )


NizPromenljivih NizPromenljivih , id | id

kreirati odgovarajuu LR sintaksnu tabelu. Korienjem kreirane tabele


proveriti da li niz
read ( id , id , )
pripada jeziku date gramatike.

4. Kreirati LR sintaksnu tabelu gramatike koja je zadata sledeim skupom


smena:

S S+I |I
I ( S ) | f ( S ) | id

Korienjem kreirane tabele proveriti da li niz

# id + f ( id + *f ( id ) ) ) #

pripada jeziku koji je denisan ovom gramatikom.

5. Kreirati LR sintaksnu tabelu za gramatiku denisanu skupom smena

E E + E | E E | E + + | E | id.

6. Kreirati LR sintaksu tabelu za gramatiku zadatu sledeim skupom smena:

SSAT |T
T T M F |F
A + | | or
M | / | mod | div | and
F id

7. Kreirati LR sintaksnu tabelu gramatike koja je zadata skupom smena

S S+I |I
I ( S ) | F ( S ) | id
F sin | cos | abs | sqr

8. Kreirati LR sintaksnu tabelu za gramatiku zadatu skupom smena

hblocki ::= begin hdecsi ; hstmtsi end


hdecsi ::= d | hdecsi ; d
hstmtsi ::= s | hstmtsi ; s
158 GLAVA 8. LR ANALIZATORI

Korienjem kreirane sintaksne tabele proveriti da li niz

begin d ; d ; s ; s end
pripada jeziku koji je denisan datom gramatikom.

9. Za gramatiku zadatu skupom smena

E E O E | ( E ) | num
O+|||/

kreirati LR sintaksnu tabelu.


Glava 9

Tabele simbola

Tabele simbola su strukture podataka koje u programskim prevodiocima uvaju


informacije o simbolikim imenima koja se koriste u programu. Kako se simbo-
lika imena mogu koristiti za imenovanje razliitih tipove entiteta u programu
(promenljivih, konstanti, funkcija, korisnikih tipova podataka i sl), jasno je da
su informacije koje se pamte o simbolikim imenima veoma raznorodne.

Na primer,

za promenljive je potrebno zapamtiti

 ime,

 tip (zbog provere slaganja tipova u izrazima u kojima uestvuje),

 taku u kodu u kojoj je denisana (zbog prijave greke ukoliko se


koristi van oblasti njenog vaenja),

 taku u kodu u kojoj je prvi put inicijalizovana (zbog prijave greke


ukoliko se vrednost promenljive koristi pre njene inicijalizacije),

 taku u kodu u kojoj je poslednji put koriena (zbog prijave upozore-


nja ukoliko u programu postoje promenljive koje se nigde ne koriste),
itd;

za funkcije je potrebno znati

 ime (pri pozivu funkcije treba proveriti da li takva funkcija uopte


postoji),

 tip (zbog provere slaganja tipova u izrazima u kojima se koristi),

 broj i tipove atrumenata (zbog provere da li se lista stvarnih argu-


menata slae sa listom ktivnih argumenata), itd.

159
160 GLAVA 9. TABELE SIMBOLA

Ve iz ovog kratkog primera moe se zakljuiti da se tabele simbola koriste u


semantikoj analizi u dve svrhe:

za proveru tipova podataka koji uestvuju u izrazima (type checking ) i

za proveru opsega vaenja imena (scope checking ).

9.1 Predstavljanje simbola u tabeli simbola


Za sve navedene tipove entiteta koji se imenuju, zajednika karakteristike su
ime i tip kojem pripadaju. Kako i informacije o tipu mogu biti vrlo sloene
(postoje elementarni tipovi podataka, polja, strukture, klase, itd) simboli se
predstavljaju sloenim tipovima podataka koje imaju strukturu grafa. U tim
grafovima koriste se dva osnovna tipa vorova :

vorovi kojima se predstavljaju tipovi (type nodes ili structure nodes ) i

vorovi kojima se predstavljaju imenovani entiteti u programu (object no-


des ).
S obzirom na raznorodnost podataka koji se o entitetima i tipovima pamte u
tabeli simbola, postoje dva osnovna pristupa za implementaciju ova dva tipa
vorova:

at pristup kod koga jedinstvena struktura podataka sadri sve podatke
koji se mogu pamtiti o svim moguim vrstama entiteta (odnosno tipova) i

objektno-orijentisani pristup kod koga se u apstraktnoj klasi pamti ono to


je zajedniko za sve vrste entiteta (tipova), a u konkretizovanim izvedenim
klasama ono to je karakteristino za konkretne vrste entiteta/tipova.

9.2 Predstavljanje simbola korienjeme at pri-


stupa
Strukture podataka koje se mogu koristiti za predstavljanje tipova i imenovanih
entiteta u hipotetikom programskom jeziku korienjem at pristupa imple-
mentacije simbola prikazane su u listingu 1. Pretpostavljeno je da jezik sadri
etiri osnovna tipa podataka: int, char, oat i double, kao i sloene tipove: polja
i strukture i da entiteti koji imaju svoje simboliko ime mogu biti: promenljve,
konstante, korisniki denisani tipovi podataka, lanovi struktura i metode.

Primer 9.1 Predstavljanje simbola at metodom


Na slici 9.1 data je struktura podataka (graf ) kojom je u tabeli simbola
9.2. PREDSTAVLJANJE SIMBOLA KORIENJEME FLAT PRISTUPA161

struct TypeNode {
static const Int = 0, Char = 1, Float = 2,
Double = 3, Struct = 4, Arr = 5;

int kind; // Int, Char, Float, Double, Class ili Arr

// atribut koji se koristi ako je kind = Arr


TypeNode* elementType; // tip elemenata

// atributi koji se koriste ako je kind = Struct


int fieldsNo; // broj lanova
ObjectNode* fields; // lanovi strukture
}

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;

// adresa promenljive, metode ili lana strukture


int adr;

// atributi koji se koristi za metode


int parametersNo; // broj parametara
ObjectNode* parameters; // parametri funkcije

// atribut koji se koristi za konstante


void* value; // vrednost konstante
};
Listing 1: Predstavljanje simbola korienjem at pristupa
162 GLAVA 9. TABELE SIMBOLA

predstaviljena struktura Polinom denisana na sledei nain:

struct Polinom {
int power;
float* coefficients;
};

Zbog jasnoe prikaza, vorovi kojima su predstavljeni objekti (imenovani en-


titeti) prikazani su pravougaonicima sa otrim uglovima, a vorovi kojima su
predstavljeni tipovi pravougaonicima sa zaobljenim uglovima.

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

kind: Int kind: Arr


elementsType: / eldsNo: /
eldsNo: / elds: /
elds: /

elementsType

kind: Float
elementsType: /
eldsNo: /
elds: /

Slika 9.1: Graf kojim je u tabeli simbola predstavljena struktura Polinom


9.3. PREDSTAVLJANJE SIMBOLA KORIENJEM OBJEKTNO-ORIJENTISANOG PRISTUPA163

9.3 Predstavljanje simbola korienjem objektno-


orijentisanog pristupa
Sa slike 9.1 se moe uoiti da, ukoliko se koristi at pristup za predstavljanje
simbola, mnoga polja u strukturama ostaju neiskoriena, tj. troi se mnogo
vie memorijskog prostora nego to je zaista potrebno za memorisanje poda-
taka o simbolu. Zbog toga se danas ee koristi objektno-orijentisani pri-
stup. Kod ovog pristupa bi osnovna klasa za predstavljanje imenovanih entiteta
(ObjectNode) sadrala samo ono to je zajedniko za sve tipove imenovanih en-
titeta: ime (name), vrstu entiteta (kind) i pokaziva na sledei (next). Ono
to je karakteristino za pojedine tipove entiteta bilo bi denisano u izvedenim
klasama. Analogno tome i za predstavljanje tipova bi bila denisana osnovna
klasa (TypeNode) koja bi sadrala samo vrstu tipa, dok bi se u izvedenim kla-
sama pamtili dodatni podaci vezani za konkretne tipove. Kompletan dijagram
klasa za predstavljanje simbola u navedenom hipotetikom programskom jeziku
dat je na slici 9.2.

Kada se koristi objektno-orijentisani pristup za predstavljanje simbola, pri kre-


iranju novog simbola potrebno je znati vrstu enititeta koji on imenuje. Zbog
toga mora da se malo promeni struktura kompilatora u odnosu na onu koja je
prikazana na slici 4.1. U ovom sluaju leksiki analizator, kada prvi put prpozna
neko simboliko ime, ne moe da kreira objekat koji e ga predstavljati u tabeli
simbola jer ne zna kontekst u kojem je ime upotrebljeno. Zbog toga se struktura
kompilatora neznatno menja i u novijim kompilatorima tabela simbola poinje
da se koristi tek od faze sintaksne analize. Izmenjena struktura kompolatora
prikazana na slici 9.3.

9.4 Predstavljanje tabele simbola


Sadraj tabela simbola se stalno menja: dodaju se novi simboli kada se naie
na novu deniciju, a izbacuju se simboli kada se napusti opseg njihovog vae-
nja. Zato se za predstavljanje tabele simbola mora koristiti neka od dinamikih
struktura podataka. Najee koriene su lanane liste, ureena binarna stabla
i rasute (hash ) tabele. Prednosti i nedostatke svake od ovih struktura emo
analizirati tako to emo posmatrati deo tabele simbola koji se kreira na osnovu
sledeeg dela koda:

void m() { /* ... */ }


class T { /* ... */ };
int a, b, c;
const int n = 10;
Tabela simbola realizovana kao lanana lista prikazana je na slici 9.4. Osobine
tabele simbola realizovane na ovaj nain su u stvari osobine same lanane liste
kao strukture podataka:
Array Struct
1
GLAVA 9. TABELE SIMBOLA

- 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

Slika 9.2: Dijagram klasa za predstavljanje simbola


9.4. PREDSTAVLJANJE TABELE SIMBOLA 165

sintaksni i semantiki
analizator

leksiki analizator generator koda

izvorni kod mainski kod

tabela simbola

Slika 9.3: Izmenjena struktura kompilatora

symbols

name: n name: c name: b name: a name: T name: m


kind: Const kind: var kind: Var kind: Var kind: Type kind: Meth

Slika 9.4: Tabela simbola realizovana kao lanana lista

traenje simbola u ovakvoj strukturi je sporo (vri se linearno traenje pa


je proseno vreme traenja n/2),
dodavanje novih simbola je jako brzo (dodavanje se uvek vri na poetak
liste),

brisanje simbola je, takoe, brzo (uvek se briu najpre simboli sa poetka
liste to e biti objanjeno u sledeem poglavlju).

Zbog navedenih osobina, tabele simbola realizovane na ovaj nain se koriste u


situacijama kada oekivani broj simbola u jednoj tabeli nije veliki.

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),

dodavanje simbola je sporije (jer se prvo vri traenje mesta pa je i kom-


pleksnost dodavanja simbola takoe log2 n)
brisanje simbola jako sporo (vri se najpre traenje simbola koji treba da
budu obrisani po celom stablu, a onda i samo brisanje)
166 GLAVA 9. TABELE SIMBOLA

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

Slika 9.5: Tabela simbola realizovana kao ureeno binarno stablo

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: n name: a name: t


1 kind: Var kind: Var kind: Type

name: c name: m
3 kind: Var kind: Meth

Slika 9.6: Tabela simbola realizovana kao rasuta tablica

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:

traenje simbola je izuzetno brzo ( 1),


dodavanje simbola takoe brzo ( 1),
brisanje simbola, takoe, sporo (vri se najpre traenje simbola koji treba
da budu obrisani u celoj tabeli, dok je samo uklanjanje simbola brzo) i

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

koliko e elemenata sadrati hash tabela, preporuljivo je da njena isko-


rienost bude 80%, a u sluaju tabele simbola broj elemenata koji se
upisuju u nju je kranje nepredvidiv).

9.5 Tabele simbola i oblast vaenja simbolikih


imena
Vidljivost simbolikih imena u programu zavisi od mesta u kojem su dinisna.
Deo programa u kojem denisani simbol moe da se koristi se naziva oblast vae-
nja ili oblast vidljivosti simbolikog imena (scope ). Veina savremenih program-
skih jezika je organizovano blokovski, tj. oblast vaenja imena odgovara bloku u
kojem su denisani. Kako se blokovi mogu ugnjedavati jedan u drugi, ime de-
nisano u jednom bloku je vidljivo u tom bloku i u svim blokovim ugnjedenim
u njega. Ako je isto ime denisano u vie ugnjedenih blokova, u posmatranoj
taki vai poslednja denicija, tj. denicija najblia posmatranoj taki.

Na primer, u programskom jeziku C++ moemo uoiti sledee opege vaenja:

opseg jezika  sadri imena denisana u samom jeziku

globalni oseg  sadri imena denisana na globalnom nivou,

opseg klase  sadri lanove klase,

opseg funkcije  sadri parametre funkcije i lokalne promenljive denisane


u funkcijskom bloku i

opseg bloka  sadri promenljive denisane samo u tom bloku.

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:

1. svi simboli se smetaju u jedinstvenu tabelu simbola pri emu se uz svaki


simbol pamti i nivo opsega na kojem je denisan i po zatvaranju bloka iz
tabele se briu svi simboli denisani u njemu, ili

2. za svaki opseg vaenja imena se pravi posebna tabela simbola i one se


smetaju u stek i po zatvaranju bloka za koji je opseg vezan, iz steka se
izbacuje tabela koja odgovara tom opsegu.
168 GLAVA 9. TABELE SIMBOLA

1 public class Foo {


2 private int value = 39;
3 public int test() {
4 int b = 3; opseg imena b
5 return value + b;
6 }
7 public void setValue(int c) {
opseg imena value,
8 value = c;
test i setValue
9 {
10 int d = c; opseg imena c
11 c = c + d; opseg imena d
12 value = c;
13 }
14 }
15 }
16
17 public class Bar {
18 private int value = 42;
19 public void setValue(int c) { opseg imena value
20 value = c; opseg imena c i setValue
21 }
22 }

Listing 2: Jedan deo Java koda sa obeleenim oblastima vaenja imena

Svaki od navedenih pristupa ima svoje prednosti i svoje nedostatke. Problemi


koji se javljaju kada se koristi posebna tabela simbola za svaki opseg su sledei.

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

lananim listama i ureenim binarnim stablima.

Primer 9.2

Prikazati sadraj tabele simbola u obeleenim takama datog C++ koda.


Posmatrati sluaj jedinstvene tabele i posebne tabele simbola za svaki op-
seg vaenja.

// 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.

Taka 1: U tabeli simbola su upisani samo simboli ugraeni u programski


jezik. Na primer, videti sledeu sliku.

symbols

name: int name: cin


kind: Type kind: Var
level: 0 level: 0

Taka 2: Do ovog trenutka u kodu su denisana dva globalna objekta


(konstanta Pi i klasa Polinom) i lanovi klase Polinom (stepen i koef).
170 GLAVA 9. TABELE SIMBOLA

symbols

name: koef name: stepen name: Polinom name: pi


kind: Fld kind: Fld kind: Type kind: Con
level: 2 level: 2 level: 1 level: 1

name: int name: cin


kind: Type kind: Var
level: 0 level: 0

Taka 3: Tabeli simbola je dodata metoda vrednost, njen parameter x i


lokalna promenljiva s.
symbols

name: s name: x name: vrednost


kind: Var kind: Var kind: Meth
level: 3 level: 3 level: 2

name: koef name: stepen name: Polinom name: pi


kind: Fld kind: Fld kind: Type kind: Con
level: 2 level: 2 level: 1 level: 1

name: int name: cin


kind: Type kind: Var
level: 0 level: 0

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

name: p name: main name: Polinom name: pi


kind: Var kind: Meth kind: Type kind: Const
level: 2 level: 1 level: 1 level: 1

name: int name: cin


kind: Type kind: Var
level: 0 level: 0

Drugi sluaj. Kreira se posebna tabela simbola za svaki opseg. Sadraj


tih tabela u navedenim takama 1, 2, 3 i 4, respektivno, je prikazan na
slikama 9.7, 9.8, 9.9 i 9.10.
9.5. TABELE SIMBOLA I OBLAST VAENJA SIMBOLIKIH IMENA 171

top
scope

symbols
name: int name: cin language

kind: Type kind: Var scope
next

Slika 9.7: Taka 1 za drugi sluaj uz primer 9.2

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

Slika 9.8: Taka 2 za drugi sluaj uz primer 9.2


172 GLAVA 9. TABELE SIMBOLA

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

Slika 9.9: Taka 3 za drugi sluaj uz primer 9.2

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

Slika 9.10: Taka 4 za drugi sluaj uz primer 9.2


9.6. PITANJA 173

9.6 Pitanja
1. ta je tabela simbola?

2. Navesti metode za predstavljanje podataka o tipovima i imenovanim en-


titetima u tabeli simbola.

3. Objasniti kako se tipovi i imenovani entiteti predstavljaju u tabeli simbola


kada se koristi at metoda implementacije.

4. Objasniti kako se tipovi i imenovani entiteti predstavljaju u tabeli simbola


kada se koristi objektno-orijentisani pristup implementacije.

5. Navesti strukture podataka koje se koriste za predstavljanje tabele simbola

6. Navesti prednosti i nedostatke tabele simbola realizovane pomou lanane


liste.

7. Navesti prednosti i nedostatke tabele simbola realizovane pomou uree-


nog binarnog stabla.

8. Navesti prednosti i nedostatke tabele simbola realizovane pomou rasute


tablice.

9. Kako se imformacija o oblasti vaenja simbola predstavlja u tabeli simbola.

10. Koja se struktura podataka najee koristi za predstavljanje tabele sim-


bola ukoliko se organizuje jedinstvena tabela simbola za sve oblasti vae-
nja? Zato?

11. Koja se struktura podataka najee koristi za predstavljanje posebnih


tabela simbola za svaku oblast vaenja? Zato?

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:

(a) jedinstvena tabela smbola za sve opsege vaenja;

(b) posebna tabela simbola za svaki opseg.

public class Krug


{
private int r;
/* tacka 1 */
void postaviR(int r)
{
this.r = r;
/* tacka 2 */
}
/* ... */
};
Glava 10

Generatori leksikih i
sintaksnih analizatora

U ovom poglavlju bie predstavljeni generatori leksikih analizatora Lex i JFlex


i generatori sintaksnih analizacora Yacc i Cup .

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.

10.1 Lex  generator leksikih analizatora


Lex generie kod koji prepoznaje instance zadatih regularnih izraza u ulaznom
tekstu, prepoznaje u ulaznom tekstu podnizove koji odgovaraju zadatim regu-
larnim izrazima. Osnovna namena Lex-a jeste generisanje leksikih analizatora,
ali se Lex moe koristiti i u programima za bilo kakvo procesiranje teksta.

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.

10.1.1 Pravila u Lex specikaciji


Centralni deo Lex specikacije su pravila i to je jedini obavezni deo specikacije.
Minimalni sadraj Lex specikacije je:

%%
<pravila>
Jedno pravilo Lex specikacije sadri dva dela:

uzorak  regularni izraz koji denie sekvencu simbola koja se trai u


ulaznom tekstu;

akciju  kod na odredinom jeziku (na programskom jeziku na kojem alat


generie izlazni kod) koji e se izvriti kada se navedeni uzorak prepozna.
Akcija se od uzorka odvaja bar jednim belim simbolom (blanko znakom,
tabulatorom, ili prelazom na novi red).

Kada se Lex koristi za generisanje leksikog analizatora, uzorcima se deniu


regularni izrazi rei (leksema) programskog jezika za koji se analizator pravi,
a akcija se obino zavrava return naredbom koja vraa token koji odgovara
prepoznatoj rei.

U regularnim izrazima za deninisanje uzorka mogu da se koriste simboli (koji


se ba takvi kakvi jesu porede sa znacima iz ulaznog teksta) i metasimboli koji
imaju svoje specijalno znaenje. U tabeli 10.1 prikazan je skup metasimbola i
njihovih znaenja u regularnim izrazima Lex specikacije.

Primer 10.1 Regularni izrazi za prepoznavanje numerikih konstanti


Krenimo od najjednostavnijeg oblika numerikih konstanti. U veini pro-
gramskih jezika denisan je neoznaeni ceo broj kao niz dekadnih cifara
koji ne sme da pone nulom. Regularni izraz koji odgovara ovoj deniciji
neoznaenog celog broja je

[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.

Sledee proirenje denicije numerikih konstanti dobija se uvoenjem pred-


10.1. LEX  GENERATOR LEKSIKIH ANALIZATORA 177

Tabela 10.1: Metasimboli za denisanje regularnih izraza u Lex specikaciji

znak znaenje

+ prethodni znak ili grupa se ponavlja jednom ili vie puta

* prethodni znak ili grupa se ponavlja nijednom ili vie puta

? prethodni znak moe ali i ne mora da se pojavi

{n} prethodni znak ili grupa se ponavlja tano n puta

{n,m} prethodni znak ili grupa se ponavlja minimalno n, a maksimalno


m puta

{name} poziv makroa (ime lex promenljive)

[ ] alternativa  izbor jednog od navedenih simbola unutar zagrade

- sa prethodnim i narednim znakom denie opseg simbola  moe


se koristiti samo unutar alternative

 Koristi se na poetku alternative ili na poetku regularniog iz-


raza. Ukoliko se nalazi na poetku alternative, oznaava nega-
ciju skupa znakova koji sledi  vri se izbor jednog od simbola
koji nisu navedeni u alternativi. Ukoliko se nalazi na poetku
regularnog izraza, oznaava da se taj regularni izraz primenjuje
samo za izdvajanje podstringova (particija) sa poetka linije.

$ koristi se na kraju regularnog izraza i oznaava da se taj regu-


larni izraz primenjuje samo za prepoznavanje podnizova koji se
nalaze na kraju linije

/ oznaava da se podnizovi denisani regularnim izrazom koji


prethodi izdvajaju samo ukoliko ukoliko se iza njih nae podniz
denisan regularnim izrazom koji sledi

( ) grupisanje simbola

\ ponitava specijalno znaenje metakaraktera koji sledi

ponitavaju specijalna dejstva svih metasimbola izmeu

| izbor alternative (bira se izmeu simbola (ili grupe) koji pret-


hodi i simbola (ili grupe) koji sledi

! negira znak koji sledi  na toj poziciji se moe pojaviti svaki


znak osim navedenog

~ prihvata sve simbole do pojave znaka ili grupe koja sledi, uklju-
ujui i taj znak/grupu

. zamenjuje bilo koji znak

<name> koristi se na poetku regularnog izraraza i oznaava da se prime-


njuje samo ukoliko prepoznavanje podniza poinje od navedenog
stanja
178GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

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.

Primer 10.2 Regularni izraz za prepoznavanje kljunih rei i simbolikih imena


U nastavku je dat regularni izraz za prepoznavanje kljunih rei i simbo-
likih imena.

_*[a-z A-Z][a-z A-Z 0-9_]*

Primer 10.3 Regularni izrazi za prepoznavanje operatora u ijem zapisu gu-


riu metasimboli
Operator ++, u kojem se dva puta pojavljuje znak + koji se koristi i kao
metasimbol, moe da se denie bilo kojim od sledeih regularnih izraza:

"++", \+\+ ili \+{2}.

Primer 10.4 Navoenje alternativa


Regularni izrazi za prepoznavanje logikih konstanti mogu da se predstave
na jedan od sledea dva naina, pri emu se znak | koristi za razdvajanje
alternativa.

"true"|"false" ili (true)|(false).

Primer 10.5 Korienje simbola 


10.1. LEX  GENERATOR LEKSIKIH ANALIZATORA 179

Programska linija koja na prvoj poziciji ima slovo C predstavlja komentar u


programskom jeziku FORTRAN. To znai da poetak komentara moemo
denisati regularnim izrazom

C.

Primer 10.6 Korienje simbola $


Regularni izraz za prepoznavanje simbola koji u programskom jeziku BA-
SIC oznaava da se tekua naredba nastavlja u sledeem redu.

-$

10.1.2 Denicije u Lex specikaciji


Denicije u Lex specikaciji mogu da sadre dva dela.

Deo koji se prepisuje na poetak generisanog fajla. Ovaj deo poinje


linijom koja sadri samo %{ i zavrava se linijom koja sadri %}. Navedeni
delimiteri se zapisuju obavezno poev od prve pozicije. U okviru ovog dela
navode se:

 denicije globalnih tipova i podataka;

 include direktive i slino.

Lex denicije koje obuhvataju:

 denicije specijalnih poetnih stanja i

 denicije makroa.

10.1.3 Specijalna poetna stanja


Prilikom prepoznavanja svake nove rei, polazi se od unapred denisanog poet-
nog stanja konanog automata. Po podrazuemvanim podeavanjima, poetno
stanje generisanog konanog automata je stanje koje ima redni broj 0. Nekada
se javlja situacija da iste rei imaju razliita znaenja zavisno od konteksta u
kojem su upotrebljene. Da bi se ta specijalna znaenja pojedinih rei prepoznala
uvode se nova poetna stanja konanog automata koji prepoznaje rei jezika.

Specijalna poetna stanja mogu da budu:

Potpuno denisana specijalna poetna stanja  za njih treba denisati


prelaze za svaki simbol ulazne azbuke. U engleskoj literaturi se ovakva
stanja nazivaju exclusive states. Simbolika imena takvih stanja se u Lex
specikaciji navode u liniji koja poinje sa %x.
180GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

Parcijalno denisana specijalna poetna stanja  za njih se mogu denisati


samo prelazi za one simbole koje se nalaze na poetku rei koje imaju
drugaije znaenje od onog koje imaju kada analiza poinje od poetnog
stanja 0. Za prepoznavanje onih rei koje imaju isto znaenje i u jednom i
u drugom sluaju koristie se uzorci navedeni za podrazumevano poetno
stanje. Za ovakva stanja se u engleskoj literaturi koristi termin inclusive
states. Simbolika imena takvih stanja se u Lex specikaciji navode u liniji
koja poinje sa %s.
Prelaz na korienje novog poetnog stanja prilikom izdvajanja sledee rei (pod-
niza) koristi se funkcija begin.
Komentari u programskom jeziku C poinju simbolom // i zavravaju se prela-
zom na novi red ili se navode izmeu simbola /* i */. Rei navedene u komen-
taru imaju drugaije znaenje nego kad su van komentara (tj. nemaju nikakvo
znaenje). Zato deniemo dva specijalna poetna stanja  za prepoznavanje tj.
ignorisanje sadraja komentara, kao to je prikazano u sledeem primeru.

Primer 10.7 Deo Lex specikacije za ignorisanje komentara u programskom


jeziku C

%x COMMENT1 COMMENT2
%%
\/\/ begin(COMMENT1);
<COMMENT1> \n begin(0);
<COMMENT2> . ;
\/\* begin(COMMENT2);
<COMMENT2> \*\/ begin(0);
<COMMENT2> . ;

10.1.4 Denicije makroa


Ukoliko postoje regularni izrazi koji se koriste u veem broju uzoraka, ili su neki
uzorci vrlo komplikovani, mogue je denisati makro ija je vrednost jednaka
nekom regularnom izrazu, a onda se u uzorcima koji sadre takve regularne
izraze vri poziv makroa .

Format za denisanje makroa:

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

Primer 10.8 Regularni izraz za izdvajanje numerikih konstanti sa korienjem


makroa

cifra [0-9]
%%
[+-]?{cifra}+(\.{cifra}+)?((Ee)[+-]?{cifra}+)?

10.1.5 Korisniki potprogrami


Da bi Lex specikacija bila preglednija, treba se truditi da kod naveden u akci-
jama bude to krai. Ukoliko akcija treba da bude komplikovanija, uobiajeno
je da se u delu za korisnike potprograme implementira funkcija, koja se samo
poziva u okviru akcije. Deo sa korisnikim potprogramima sadri C funkcije
koje se kompletno prepisuju u generisani kod.

10.1.6 Upotreba Lex generatora


Lex kompilator se poziva sa

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.

Najbitnije promenljive i funkcije koje lex generie su:

char* yytext  izdvojena re;

int yylength  duina izdvojene rei;

void yyless(int n)  duinu izdvojene rei menja na n karaktera (prvih


n karaktera iz rei yytext zadrava, preostale vraa u ulazni tok);

void yybegin(int state)  menja poetno stanje konanog automata;


182GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

FILE* yyin  datoteka iz koje se ita ulazni tekst; ukoliko korisnik ne


otvori ovu datoteku pre prvog poziva funkcije yylex(), uitavanje poda-
taka e se vriti sa standardnog ulaza.

10.1.7 Primer kompletne Lex specikacije


U okviru ovog poglavlja generisaemo prevodilac za programski jezik denisan
sledeom gramatikom.

Program NizNaredbi \n end


NizNaredbi NizNaredbi \n Naredba | Naredba
Naredba Ulaz | Izlaz | Dodela
Dodela id = Izraz
Izraz Izraz + Proizvod
Proizvod Proizvod Faktor
Faktor (Izraz) | id | cons
Ulaz read(id)
Izlaz write(Izraz)

Neka u jeziku postoje samo numerike konstante i neka konstante i identikatori


imaju isti zapis kao i u programskom jeziku C.

Uoimo najpre tipove rei u ovom jeziku:

1. kljune rei end, read, write;


2. operatori +, ;
3. separatori =, (, ), \n;
4. simbolika imena id;
5. konstante const.
Za svaki tip rei treba denisati neki ceo broj koji ga identikuje. Kako izvesni
specijalni znaci sami predstavljaju posebnu vrstu rei (za konkretan jezik to su
znaci +, , =, ( i )), za nih se ne moraju denisati posebni identikatori 
mogu se identikovati svojim ASCII kodom. Za ostale tipove rei treba ekspli-
citno denisati konstante koje ih identikuju. Treba voditi rauna o tome da
identikatori tih rei ne smeju da se poklapaju sa bilo kojim ASCII kodom.

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

se pamte u tabeli simbola i leksiki analizator, kako je ranije reeno, proverava


da li je prepoznato ime ve upisano u tabelu simbola. Ako nije, upisuje ga
i daljem stepenima analize treba da dostavi neki ukazatelj na podatke o tom
simbolu. U ovom jednostavnom primeru, tabela simbola e biti organizovana
kao jedan obian niz, pa e leksiki analizator kada prepozna simboliko ime,
vraati i pozciju u tabeli simbola gde je taj simbol zapisan.

Ovakve dodatne informacije o izdvojenoj rei se obino nazivaju atributima i


kako je pokazano tipovi podataka kojim se predstavlaju ti dodatni atributi su
razliiti za razliite vrste rei. Kako je pokazano, u ovom sluaju za konstante
je dodatni atribut realan broj (vrednost konstante), a za simbolika imena ceo
broj (redni broj u tabeli simbola gde su zapisani). Zbog toga se tip podataka
kojima se predstavljaju dodatni atributi simbola, uglavnom, deniu kao unije.

Identikatore rei (tokene) i tipove dodatnih atributa denisaemo u posebnom


fajlu. Neka je to fajl Tokens.h.

Primer 10.9 Denicije tokena i tipa podataka za predstavljanje dodatnih atri-


buta tokena

// 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;
};

O strukturama podataka za predstavljanje podataka o simbolikom imenu je


bilo rei u poglavlju 9. Poto u naem primeru simbolika imena identikuju
samo promenljive, ta struktura e biti neto jednostavnija. Jedino to leksiki
analizator zna o simbolu je njegovo ime. Ostali elementi stukture su vezane
za naredne nivoe prvoenja. Zbog toga emo u ovom trenutku tu strukturu
ostaviti nepopunjenu. Nju emo denisati u fajlu Symbol.h.

Primer 10.10 Nepotpuna denicija tipa podataka za predstavljanje simbola u


tabeli simbola
184GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

// Symbol.h
struct Symbol
{
char name[32];
// ...
};

Kreiraemo i samu lex specikaciju koja e sadrati i main funkciju. U main


funkciji e se pozivati funkcija za izdvajanje sledee tei iz ulaznog teksta dok se
ne doe do kraja ulazne datoteke. Za svaku izdvojenu re, na standardni izlaz
prikazae se kako izgleda, njen token i atribut ukoliko je denisan.

Primer 10.11 Kompletna Lex specikacija za prepoznavanje rei datog jezika

// MyLang.l  LEX specifikacija


%{
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "Tokens.h"
#include "Symbol.h"

struct Symbol symbolTable[200];


unsigned symbolNo;
union AttributeType attribute;
unsigned lineNo;
int getSymbol();
%}

/* 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);
}

/* ignorisanje belih simbola */


[\t ];

/* prelaz na novi red oznacava kraj naredbe */


\n { lineNo++; return yytext[0]; }

/* operatori i separatori */
[+*=();] return( yytext[0] );

/* bilo koji drugi simbol tretira se kao greska */


. return ( ERRSYMBOL );

%%
/* korisnicki potprogrami */

// funkcija koja trazi izdvojenu rec u tabli simbola


// ako je ne nae, upisuje je
int getSymbol()
{
int i;
for (i = 0; i < symbolNo &&
strcmp(symbolTable[i].name, yytext) != 0;
i++);
if (i == symbolNo)
{
strcpy(symbolTable[i].name, yytext);
symbolNo++;
}
return i;
}
186GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

void main(int argv, char** args)


{
int token;
yyin=fopen(args[1], "r");

symbolNo=0;
lineNo=1;

/* funkcija za izdvajanje nove rei se poziva


dok se ne doe do karaja ulaznog fajla,
kada yylex vraa nulu */
while ((token = yylex()) !=0)
{
if (token == ERRSIMBOL)
{
printf("nepoznat simbol %s u liniji %d\n", yytext,
lineNo);
}
else
{
printf("rec: %s, token: %d", yytext, token);
switch (token)
{
case CONST:
printf(" vrednost: %f\n", attribute.value);
break;
case ID:
printf(" r. br. u tabeli: %d\n", attribute.index);
break;
default:
printf("\n");
}
}
}
fclose(yyin);
}

10.2 Yacc  generator sintaksnih analizatora


Yacc je alat za generisanje sintaksnih analizatora. Razvijen je u isto vreme kad i
Lex i osnovna je ideja da ova dva alata rade u sprezi. Yacc generie LR sintaksni
analizator na osnovu ulazne Yacc specikacije.

Yacc specikacija , po strukturi potpuno odgovara Lex specikaciji i sastoji se


10.2. YACC  GENERATOR SINTAKSNIH ANALIZATORA 187

od sledeih delova:

definicije
%%
pravila
%%
korisniki potprogrami
Obavezni deo, kao i u Lex specikaciji, su pravila, dok su denicije i korisniki
potprogrami opcioni .

10.2.1 Denicije u Yacc specikaciji


Deo za denicije sadri zaglavlje koje se direktno umee u generisani analizator
i posebne Yacc denicije.

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.

10.2.2 Denicija startnog simbola gramatike


Stratni simbol gramatike denie se na sledei nain:

%start <ime_startnog_simbola >

10.2.3 Denicije terminalnih simbola gramatike


Terminalni simboli gramatike deniu se na sledei nain:

%token <ime_term_simbola_1> [<ime_term_simbola_2>]...


Kao to je ve reeno, ukoliko nekom tokenu odgovara samo jedna re duine
jedan znak, mogue je da se za takav token ne koristi poseban identikator
(tj. da se on ne navede u ovoj listi tokena), ve da se odgovarajua leksema u
smenama navodi pod literalima.

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

10.2.4 Denicije prioriteta i asocijativnosti operatora


Operatori mogu biti levo-asocijativni, desno-asocijativni i neasocijativni. Za
svaki tip asocijativnosti postoji posebna Yacc denicja (%left, %right, %nonassoc).
Prioritet operatora je denisan redosledom navoenja njihovih asocijativnosti i
to tako to se uvek navode najpre asocijativnosti operatori najnieg prioritera.
Na primer, asocijativnost i prioriteti osnovnih aritmetikih operatora u Yacc
specikaciji mogu biti denisani na sledei nain:

%left '+', '-'


%left '*', '/'
%right STEPEN
Operatori, koji su navedeni u denicjama asocijativnosti i prioriteta, ne moraju
biti navedeni u listi tokena.

10.2.5 Denicije tipova atributa terminalnih i neterminal-


nih simbola
Ukoliko se eksplicitno de denie, tip dodatnih atributa svih simbola gramatike
(terminalnih i neterminalnih) je int. Ukoliko tip int nije dovoljan za pred-
stavljanje dodatnih atributa svih simbola, u Yacc specikaciji moe ekspilicitno
da bude denisan tip dodatnih atributa simbola. S obzirom da se za razliite
simbole kao dodatni atributi pamte podaci razliitog tipa, tip dodatnih atributa
se denie kao unijana sledei nain:

%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:

%token<active_value > <token_list >.


Format denicije %type je:
10.2. YACC  GENERATOR SINTAKSNIH ANALIZATORA 189

%type<active_value > <nonterminal_list >.

Primer 10.12 Denicije tipova dodatnih atributa terminalnih i neterminalnih


simbola u Yacc specikaciji

%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
/* ... */

10.2.6 Pravila u Yacc specikaciji


Deo za pravila poinje linijom sa simbolom %%. Ako u specikaciji postoje i
korisnii potprogrami, isti simbol se koristi i za razdvajanje pravila od korisnih
potprograma.

Za svaku smenu gramatike kreira se po jedno pravilo u Yacc specikaciji. Pravilo


sadri smenu i akciju koja e se izvriti kada se u postupku LR sintaksne analize
izvri redukcija po navedenoj smeni.

Pravilo u Yacc specikaciji ima sledei format:

A : TELO [ AKCIJA ];,


gde je:

A  neterminalni simbol sa leve strane smene;

TELO  desna strana smene;


190GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

AKCIJA  blok naredbi koji se izvrava u trenutku redukcije po navedenoj


smeni.

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:

$$  atribut simbola koji se nalazi na levoj strani smene,

$k  atrribut k -tog simbola na desnoj strani smene.

Ukoliko je za denisanje tipa dodatnih atributa simbola koriena denicija


%union, a nije eksplicitno specciran tip simbola (denicijom %token ili %type),
pri korienju ovih simbola potrebno je pisati:

<ime_simbola >.<ime_aktivnog_clana >.


Ako je tip simbola speciciran, dovoljno je pisati samo ime simbola. Ukoliko u
pravilu nije navedena akcija, podrazumevana akcija je:

{ $$ = $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:

{ ; }

10.2.7 Korisniki potprogrami


Osim za implementaciju funkcija koje se pozivaju iz akcija, u ovom delu u Yacc
specikaciji moe da bude implementiran i leksiki analizator. Ukoliko se u
ovom delu implementira leksiki analizator on mora da ima istu deklaracju kao
i leksiki analizator koji generie Lex (funkcija yylex() tipa int).
10.2. YACC  GENERATOR SINTAKSNIH ANALIZATORA 191

10.2.8 Upotreba Yacc generatora


Yacc kompilator se poziva komandom

yacc [opcije] ime.y.


Generisani kod bie u fajlu y.tab.c. Prilikom prevoenja ovog fajla UNIX-ovim
cc kompilatorom, treba navesti opciju -ly.
Ukoliko leksiki analizator nije implementiran u okviru Yacc specikacije, tabela
tokena, kao i tip podataka za predstavljanje dodatnih atributa simbola treba da
bude vidljiva i onom fajlu u kojem se nalazi implementacija leksikog anailiza-
tora. Da bi tablica tokena i denicija tipa atributa bili izdvojeni u poseban fajl,
u pozivu yacc kompilatora treba navesti opciju -d. U tom sluaju Yacc generie
i fajl pod imenom y.tab.h.
Kao to je ve reeno, Yacc generie LR sintaksni analizator. Ako korisnik eli
da vidi kako izgleda LR sintaksna tabela koju Yacc generie, pri pozivu Yacc
kompilatora treba navesti opciju -v i generisana sintaksna tabela bie zapisana
u datoteci sa imenom y.out.
Funkcija za sintaksnu analizu, generiana na osnovu Yacc specikacije je funkcija:

int yyparse();
Rezultat ove funkcije je 0 ukoliko je analiza uspeno izvrena do kraja ulaznog
fajla.

Tip dodatnih atributa simbola je YYSTYPE. Globalna promenljiva koja se koristi


za privremeno pamenje dodatnih atributa terminalnih simbola je YYSTYPE yylval.
Funkcija koja se poziva ukoliko se u procesu analize pronae greska koja nije
predviena, ili doe do bilo kakve druge greke u radu analizatora je funkcija

void yyerror(char* s);


gde je s string koji signalizira do kakve je greke dolo.

Primer 10.13 Yacc specikacija za generisanje sintaksnog analizatora aritme-


tikih izraza
Neka su aritmetiki izrazi denisani gramatikom

E E + E | E E | E E | E/E | (E) | num.

gde token num predstavlja jednocifrene celobrojne konstante. Potreban


leksiki analizator je implementiran u okviru Yacc specikacije.

%{
#include <ctype.h>
%}
192GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

//definicija tokena
%token NUM

//definicja prioriteta i asocijativnosti operatora


%left '+' '-'
%left '*' '/'

%%

//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();
}

10.2.9 Oporavak od greaka


Sintaksni analizator generisan na osnvu specikacije iz primera 10.13 e samo
utvrditi da li je izraz korektno zapisan ili ne. U trenutku kada se u kodu pojavi
prva greka , analiza e se prekinuti, bie pozvana funkcija yyerror koja e
prikazati poruku Syntax error. Nedostatak ovog analizatora je to nee loka-
lizovati greku, tj. nee nam dati informacije gde se ona nalazi, ni o kakvoj se
greci radi; a nee ni otkriti sve greke u kodu. Cilj analizatora je da prijavi sve
greke i da korisniku ukae gde se nalaze i kako da ih ispravi. Postupak koji nam
omoguava da i kada se greka otkrije, analizator nastavi svoj rad se popularno
10.2. YACC  GENERATOR SINTAKSNIH ANALIZATORA 193

naziva  oporavak od greke .

Pretpostavimo da je u nekom izrazu (koji se prepoznaje gramatikom koja je


denisana u primeru 10.11) izostavljena zatvorena zagrada. Prilikom prepozna-
vanja izraza sa zagradama koristilo bi se pravilo:

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:

E : '('E error /* prijava greske */ ;


Pri denisanju ovih ktivnih smena treba voditi rauna da se to je mogue
vie sprei viestruko prijavljivanje iste greke (to je nemogue potpuno izbei)
i da se ne desi da se u istom stanju pri pojavi istog simbola na ulazu moe
vriti redukcija po veem broju smena. U takvim sluajevima yacc e prijaviti
takozvane reduce/reduce konikte (koje on ne moe da prevazie) i kod nee ge-
nerisati. Ako se prilikom kreiranja sintaksne tabele pojave shift/reduce konikti
(njihov uzrok je objanjen u poglavlju o LR sintaknim analizatorima), prijavie
se semo upozorenje, a u sintaksnoj tabeli bie upisana shift akcija.

Primer 10.14 Yacc specikacija za generisanje sintaksnog analizatora koji


podrava oporavak od greaka
Kreiraemo Yacc specikaciju za generisanje sintaksnog analizatora jezika
koji je denisan gramatikom navedenom u primeru 10.11. Uz sintaksne
greke, analizator e prijavljivati i jednostavnije semantike, npr. korienje
simbola kojem nije dodeljena vrednost i sl.

Struktru za pamenje podataka o simbolikim imenima proiriemo kom-


ponenatama potrebnim za semantiku analizu.

// 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;
}

%token END READ WRITE


%token<index> ID
%token<value> CONST

%%
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 { ; }
;

Ulaz : READ '(' ID ')'


{ symbolTable[$3].posDef = lineNo; }
| READ '(' ID error
10.2. YACC  GENERATOR SINTAKSNIH ANALIZATORA 195

{
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); }
;

Izlaz : WRITE '(' Izraz ')' { ; }


| WRITE '(' Izraz error
{ printf("linija %d: nedostaje )\n", lineNo); }
| WRITE '(' error
{ printf("linija %d: nekorektan izraz\n", lineNo); }
| WRITE error
{ printf("linija %d: nedostaje (\n", lineNo); }
;

Dodela : ID '=' Izraz { symbolTable[$1].lastDef = lineNo; }


| ID '=' error
{
printf("linija %d: nekorektan je izraz\n", lineNo);
symbolTable[$1].lastDef = lineNo;
}
| ID error
{
printf("linija %d: ocekuje se =\n", lineNo);
symbolTable[$1].lastDef = lineNo;
}
;

Izraz : Izraz '+' Proizvod { ; }


| Izraz '+' error
{ printf("linija %d: nekorektan izraz\n", lineNo); }
| Proizvod { ; }
;

Proizvod : Proizvod '*' Faktor { ; }


| Proizvod '*' error
{ printf("linija %d: nekorektan izraz\n", lineNo); }
| Faktor
;

Faktor : '(' Izraz ')' { ; }


196GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

| '(' Izraz error


{ printf("linija %d: nedostaje )\n", lineNo); }
| '(' error
{ printf("linija %d: nekorektan izraz\n", lineNo); }
| ID
{
if ( symbolTable[$1].lastDef == 0 )
printf("linija %d: %s se koristi pre inicijalizacije\n",
lineNo, yytext );
tabelaSimbola[$1].posKor = brLinije;
}
| CONST {;}
;

%%
#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.

Umesto fajla Tokens.h treba ukljuiti fajl y.tab.h.


Promenljivu attribute zameniti promenljivom yylval tipa YYSTYPE.

10.2.10 Generisanje interpretatora pomou Yacc-a


Izvrenje programa vri se po njegovom sintaksnom stablu i to tako to se najpre
izvravaju operacije blie listovima, da bi se tek na kraju izvrila operacija koja
se nalazi u korenu stabla. S obzirom da Yacc generie sintaksni analizator
koji sintaksno stablo generie u tom istom redosledu (od listova ka korenu),
10.2. YACC  GENERATOR SINTAKSNIH ANALIZATORA 197

paralelno sa procesom generisanja sintaksnog stabla programa, on moe i da


se izvrava. Ako smenama gramatike pridruimo akciju koja izvrava naredbu
koja se smenom denie, Yacc e generisati interpretator jezika koji je denisan
odgovarajuom gramatikom.

Primer 10.15 Yacc specikacija za generisanje interpretatora aritmetiikih iz-


raza
Neka su aritmetiki izrazi denisani gramatikom koja je data u primeru 10.13.

%{
#include <ctype.h>
%}

//definicija tokena
%token NUM

//definicja prioriteta i asocijativnosti operatora


%left '+' '-'
%left '*' '/'

%%

//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();
}

Primer 10.16 Yacc specikacija za generisanje interpretatora jezika koji je


denisan u primeru 10.11
Strukturi Symbol emo dodati i lan koji uva vrednost simbola.

// 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 END READ WRITE


%token<rbr> ID
10.2. YACC  GENERATOR SINTAKSNIH ANALIZATORA 199

%token<vrednost> CONST
%type<vrednost> Izraz Proizvod Faktor

%%

Program : NizNar END { printf("analiza je zavrena\n"); };

NizNar : NizNar ';' Naredba { ; }


| Naredba { ; }
;

Naredba : Ulaz { ; }
| Izlaz { ; }
| Dodela { ; }
;

Ulaz : READ '(' ID ')'


{
scanf("%f", &(symbolTable[$3].value));
symbolTable[$3].lastDef = lineNo;
}
;

Izlaz : WRITE '(' Izraz ')'


{
printf("%f\n", $3);
}
;

Dodela : ID '=' Izraz


{
symbolTable[$1].lastDef = lineNo;
symboltable[$1].value = $3;
}
;

Izraz : Izraz '+' Proizvod { $$ = $1 + $3; }


| Proizvod { $$ = $1; }
;

Proizvod : Proizvod '*' Faktor { $$ = $1*$3; }


| Faktor { $$ = $1; }
;

Faktor : '(' Izraz ')' { $$ = $2; }


200GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

| 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:

opcije za podeavanje generisanog leksera:


10.3. JFLEX 201

 JFlex direktive i

 Java kod koji se ukljuuje u razliite delove leksikog analizatora


(Java klase koja se generie);

deklaracije posebnih poetnih stanja

denicije makroa.

10.3.1 Opcije kojima se podeavaju parametri generisanog


leksikog analizatora
JFlex direktive koje se najee koriste su sledee.

Direktive kojima se podeavaju parametri generisane klase  leksikog ana-


lizatora:

 %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.

 %extends <ImeKlase >  ukoliko je ova direktiva navedena, generi-


sana klasa nasleuje navedenu klasu.

Direktive kojima se podeavaju parametri funkcije koja vri izdvajanje


sledee rei iz ulaznog teksta:

 %function <ImeFunkcije > denie ime generisane funkcije. Uko-


liko ova direktiva nije navedena, ime generisane funkcije je yylex().
 %int ili %integer postavlja povratni tip funkcije koja vri leksiku
analizu na tip int.
 %type <ImeTipa > postavlja povratni tip funkcije koja vri leksiku
analizu na navedeni tip.

Ukoliko ni jedna od prethodne dve direktive nije navedena, podrazu-


menvani povratni tip leksikog analizatora je Yytoken.
Direktive kojima se ukljuuju brojai linija i karaktera:

 %line ukljuuje broja linija u izvornom fajlu. Generie se promen-


ljivayyline (tipa int) koja pamti redni broj tekue linije (brojanje
poinje od 0).

 %char ukljuuje broja karaktera u izvornom fajlu. Generie se pro-


menljiva yychar (tipa int) koja pamti redni broj prvog karaktera
izdvojene rei (brojanje poinje od 0).
202GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

 %column ukljuuje broja karaktera u tekuoj liniji. Generie se pro-


menljiva yycolumn (tipa int) koja pamti redni broj prvog karaktera
izdvojene rei u tekuoj liniji (brojanje poinje od 0).

Direktive kojima se nalae generisanje samostalne aplikacije (tj. generisa-


nje main metoda):

 %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.

 %standalone generie se main metod koji poziva leksiki analizator


sve dok se ne doe do kraja ulaznog fajla. Ispravno prepoznati to-
keni se ignoriu, a na standardni izlaz se ispisuju neprepoznati delovi
ulaznog fajla.

Delovi Java koda koji se ugrauju u razliite delove generisane klase se deniu
na sledei nain.

Sledei deo koda se ugrauje u generisanu klasu. Tu se deniu dodatni


atributi i metodi klase.

%{
<code>
%}

Sledei deo koda se ugrauje u konstruktor generisane klase.

%init{
<code>
%init}

Sledei deo koda se ugrauje u generisanu funkciju koja iz funkcije za


leksiku analizu poziva u prenutku kada se prepozna EOF. Ovaj deo koda
treba da vrati vrednost koja signalizira da se dolo do kraja koda koji
se anaizira. Ukoliko ovaj deo nije naveden, a povratni tip funkcije koja
vri leksiku analizu je int, vraa se vrednost konstante YYEOF (javna sta-
tika konstanta generisane klase). Ukoliko je povratni tip neki korisniki
denisani tip, funkcija e vratiti konstantu null.

%eofval{
<code>
%eofval}
10.3. JFLEX 203

10.3.2 Deklaracije posebnih poetnih stanja


Deklaracije posebnih poetnih stanja u JFlex specikaciji imaju istu sintaksu
kao i u Lex specikaciji. Jedino se kao identikator podrazumevanog poetnog
stanja koristi konstanta YYINITIAL.

10.3.3 Denicije makroa


U JFlex specikaciji se makroi deniu na sledei nain:

<ImeMakroa > = <RegularniIzraz >


Za razliku od lex specikacije, ovde se nakon imena makroa navodi znak =.

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).

10.3.5 Korienje JFlex-a


JFlex specikacija se zapisuje sa ekstenzijom .flex. JFlex kompilator se moe
pozvati iz komandne linije na sledei nain:

jflex <ime_specifikacije >


JFlex generie samo jednu Java klasu i, ukoliko direktivama nije drugaije na-
loeno, ona je denisana na sledei nain:

ime klase: Yylex,


konstruktor: public Yylex(System.io.Reader r),
funkcija za leksiku analizu: public Yytype yylex(),
funkcija koja menja poetno stanje analize: void yybegin(int state),
funkcija koja menja poetno stanje na podrayumevano: void yybegin(),
funkcija koja vraa trenutno poetno stanje: int yystate(),
funkcija koja vraa izdvojenu re: String yytext(),
redni broj tekue linije: int yyline,
redni broj tekueg karaktera u ulaznom tekstu: int yychar,
redni broj tekueg karaktera u liniji: int yycolumn.
204GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

10.3.6 Primer JFlex specikacije


Kreiraemo JFlex specikaciju za generisanje leksikog analizatora za isti jezik
za koji je kreirana Lex specikacija u primeru 10.11.

Prvi korak. Kreiramo klasu koja sadri denicije tokena.

Primer 10.17 Java klasa koja sadri denicje tokena

// 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,

njeno znaenje (celobrojni identikator znaenja),

liniju koda iz koje je re izdvojena,

poetnu pozicija u liniji od koje je re izdvojena,

poziciju u liniji na kojoj se izdvojena re zavrava,

dodatni atribut (ukoliko je potrebno).

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;

Yytoken (int token, String text, int line,


int charBegin, int charEnd, Object value) {
_token = token;
_text = text;
_line = line;
_charBegin = charBegin;
_charEnd = charEnd;
_value = value;
}

public String toString() {


return "Re: " + _text +
"\ntoken: " + _token +
"\nlinija: " + _line +
"\npocetak: " + _charBegin +
"\nkraj: " + _charEnd +
"\natribut: " + _value;
}
}

Trei korak. Kreiramo JFlex specikaciju.

Primer 10.19 JFlex specikacija

// import section
package compiler;

%%
// declaration section
%class MyScanner
%function scan
%line
%column

%debug
206GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

// novi lan generisane klase:


// kreira objekat koji funkcija scan vraa
%{
private Yytoken createTtoken( int tokenCode, Object value )
{
return new Yytoken(tokenCode, yytext(), yyline, yycolumn,
yycolumn+yylength(), value);
}
%}

%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()));
}

// ignorisanje belih simbola


[\t ] { ; }

// 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) };

// ukoliko se pojavi bilo koji drugi simbol, prijaviti greku


. { System.out.println("Unknown symbol: " + yytext()); }

10.4 Cup  generator sintaksnih analizatora


Cup (Construct Useful Parser ) je alat koji genee LR sintaksne analizatore u
Javi i sam je pisan u Javi. I ovo je besplatan alat otvorenog koda . Uglavnom
radi u sprezi sa JFlex-om.

Sintaksni analizator koji se generie pomou Cup-a ima dva dela:

ksni deo koji je denisan u paketu java_cup.runtime koji je nezavistan


od gramatike jezika za koji se prevodilac pie i

promenljivi deo koji je zavistan od gramatike jezika koji se generie na


osnovu Cup specikacije.

Paket java_cup.runtime sadri sledee.

Klasu Symbol koja slui za predstavljanje podataka o svim simbolima


gramatike. Atributi ove klase koji se koriste u specikaciji su:

 public int sym;  celobrojni identikator simbola,


 public int left, right;  poetna i zavrna pozicija u ulaznom
tekstu,

 public Object value;  dodatni atribut simbola.


Postoje i atributi klase Symbol koje postavlja i koristi funkcija za parsira-
nje i oni se ne smeju u kodu menjati. Takvi atributi su:

 public int parse_state;  stanje LR analizatora, ovaj atribut je


postavljen samo ukoliko se simbol nalazi u radnom magacinu LR
analizatora. Ovaj atribut je uveden jer se radnom magacinu ne pamte
naizmenino simboli i stanja, ve samo simboli pa se njima pridruuju
stanja analize.

 public boolean used_by_parser;  indikator koji kae da je sim-


bol generisao analizator usled neke greke u ulaznom kodu.

Interfejs Scanner  klasa koja slui za leksiku analizu mora da impelmen-


tira ovaj interfejs. U interfejsu je denisana funkcija za leksiku analizu
(next_token()) koja vraa rezultat tipa Symbol.
208GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

Klasu lr_parser ije su najbitnije funkcije:

 public Symbol parse()  funkcija za LR sintaksnu analizu koja se


bazira na korienju sintaksnih tabela koje su zavisne od jezika pa se
genriu i izvedenoj klasi. Rezultat funkcije parse() je tipa Symbol
i ako je analiza uspeno zarena, on e predstavljati startni simbol
gramatike.

 public Symbol debug_parse()  radi isto to i parse funkcija i uz


to u tok System.err upsije poruke u vezi s debagiranjem.

Generisani deo aplikacije (zavistan od jezika) sadri:

klasu sym koja sadri denicije tipova terminalnih simbola (celobrojne


identikatore tokena);

klasuparser (ije ime moe biti i promenjeno) koja je izvedena iz klase


lr_parser i koja sadri funkcije za inicjalizaciju potrebnih tabela:
 production_tab  tabela koja za svaku smenu gramatike pamti iden-
tikacioni broj simbola sa leve strane smene i duinu desne strane,

 action_tab  sadri deo za akcije LR sintaksne tabele i


 reduce_tab  sadri deo za prelaze nakon redukcija u LR sintaksnoj
tabeli.

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:

implementira interfejs Scanner,


funkcija za leksiku analizu je next_token() i

rezultat leksike analize je objekat klase Symbol,


Kada se doe do kraja ulaznog teksata, analizator treba da vrati simbol sa
identikatorom <CUPSYM>.EOF.
To znai da, ukoliko potreban leksiki analizator generiemo pomou JFlexa, u
JFlex specikaciji treba da stoje sledee direktive:

%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.

10.4.1 Cup specikacija


Cup specikacija po svojoj strukturi malo odstupa od strukture koju imaju Lex,
Yacc i JFlex specikacija. Delovi cup specikacije se meusobno ne odvajaju
simbolom %%, i kljune rei ne poinju simbolom %. Delovi Cup specikacije su:

import sekcija,

korisniki kod,

liste terminalnih i neterminalnih simbola,

prioriteti i asocijativnosti operatora i

opis gramatike.

Ovi delovi u specikaciji mora da budu napisani u redosledu kojim su ovde


navedeni.

Import sekcija

Import sekcija sadri import i package naredbe koje se prepisuju na poetak


fajla sa kodom analizatora i njihova sintaksan ispravnost se ne proverava.

Korisniki kod sadri delove java koda koji se ugrauju u razliite take generi-
sanih klasa.

Novi lanovi (atributi i metode) generisane klase CUP$action se navode u kon-


strukciji:

action code {: /* java code */ :}


Metode denisane u ovom delu se mogu pozivati iz akcija koje se pridruuju
smenama u delu za denisnje gramatike.

Novi lanovi (atributi i metode) generisane klase parser se navode u konstruk-


ciji:

parser code {: /* java code */ :}


Deo koda koji se izvrava pre izdvajanja prve rei iz ulaznog fajla (tj. pre prvog
poziva scanner-a) navodi se u konstrukciji:

init with {: /* java code */ :}


Deo koda koji denie kako parser poziva leksiki analizator, tj. kako trai
izdvajanje sledee rei, navodi se u konstrukciji:

scan with {: /* java code */ :}


210GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

Liste terminalnih i netermianlnih simbola

Liste terminalnih i netermianlnih simbola sadre denicije svih simbola koje


gramatika sadri. Terminalni simboli se uvode deklaracijom:

terminal [<ImeKlase >] <ImeSimbola1 >, <ImeSimbola2 >, ... ;


<ImeKlase > je tip lana value u objektu klase Symbol koji odgovara datom
terminalnom simbolu. Ukoliko se ovaj tip navede, atribut simbola se koristi bez
eksplicitnog kastovanja u svoj tip.

Neterminalni simboli gramtike se deniu deklaracijom:

non terminal [<ImeKlase >] <ImeSimbola1 >, <ImeSimbola2 >, ... ;

Asocijativnost operatora

Asocijativnosti operatora se deniu deklaracijama

precedence left <ImeSimbola1 >, <ImeSimbola2 >, ... ;


precedence right <ImeSimbola1 >, <ImeSimbola2 >, ... ;
precedence nonassoc <ImeSimbola1 >, <ImeSimbola2 >, ... ;

Prioritet operatora

Prioritet operatora je, kao i u Yacc specikaciji, odreen redosledom navoenja


njihovih asocijativnosti.

Primer 10.20 Denicje prioriteta aritmetikih operatora u Cup specikaciji


Neka su aritmetiki izrazi denisani gramatikom

Izraz Izraz + Izraz


| Izraz Izraz
| Izraz Izraz
| Izraz/Izraz
| Izraz
| CONST

Poto je ova gramatika nejednoznana, navoenje asocijativnosti i priori-


teta operatora u cup specikaciji je u ovom sluaju obavezno.

Denicije prioriteta i asocijativnosti operatora sadrale bi sledee Cup


opise:

precedence left PLUS, MINUS;


10.4. CUP  GENERATOR SINTAKSNIH ANALIZATORA 211

precedence left PUTA, PODELJENO;


precedence right UMINUS;

Kao to se vidi, za isti simbol () denisana su dva razliita prioriteta


(MINUS i UMINUS). Koji e se prioritet primeniti zavisie od konteksta u
kojem je simbol naveden.

Opis gramatike

Opis gramatike sadri (opciono) deniciju startnog simbola gramatike i (oba-


vezno) denicje njenih smena. Format denicija startnog simbola gramatike
je:

start with <ImeSimbola >;


Ukoliko je denicija srtartnog simbola gramatike izostavljena, kao i u Yacc spe-
cikaciji, podrazumeva se da je startni simbol gramatike simbol koji se nalazi
na levoj strani prve navedene smene.

Smene gramatike se u Cup specikaciji deniu parvilima koja se navode u


formatu:

<LevaStrana > ::= <DesnaStrana > [ {: <Akcija > :} ];


Akcija je Java kod koji se izvrava u trenutku kada se vri redukcija po navedenoj
smeni.

Vie smena koje na levoj strani imaju isti neterminalni simbol se mogu skraeno
navoditi na isti nain kao u Yacc specikaciji.

Za oporavak od greaka se takoe koristi ista notacija kao u Yacc specikaciji


(uvode se pomoene smene sa error simbolom).

10.4.2 Uvoenje referenci na atribute simbola u smenama


Ukoliko u akcijama treba koristiti dodatne atribute simbola koji se nalaze na
desnoj strani smene, uvode se reference na te atribute na sledei nain:

<ImeSimbola > : <Ime >


<Ime > je u ovom sluaju referenca na lan value objekta klase Symbol.
value atributu simbola koji se nalazi na levoj strani smene pristupa se korie-
njem reference RESULT.

Primer 10.21 Pravila Cup specikacije za generisanje interpretatora aritme-


212GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

tikih izraza
Pretpostavimo da su aritmetiki izrarzi denisani gramatikom navednom
u primeru 10.20.

Izraz ::= Izraz:i1 PLUS Izraz:i2


{:
RESULT = new Integer(i1.intValue() + i2.intValue());
:}
| Izraz:i1 MINUS Izraz:i2
{:
RESULT = new Integer(i1.intValue() - i2.intValue());
:}
| Izraz:i1 PUTA Izraz:i2
{:
RESULT = new Integer(i1.intValue() * i2.intValue());
:}
| Izraz:i1 PODELJENO Izraz:i2
{:
RESULT = new Integer(i1.intValue() / i2.intValue());
:}
| UMINUS Izraz:i
{:
RESULT = new Integer(- i.intValue());
:}
%prec UMINUS // smena Izraz --> - Izraz
| CONST:c
{:
RESULT = c;
:}
;
Naglaeni deo pravila koje odgovara smeni Izraz Izraz oznaava da se
u tom pravilu operator MINUS koristi sa prioritetom UMINUS. Dakle, leksiki
analizator e i u jednom i u drugom sluaju da vrati simbol MINUS, ali e
se pri redukciji po ovoj smeni za njega koristiti drugi prioritet (takozvani
kontekstni prioritet).

10.4.3 Prevoenje Cup specikacije


Poto je Cup implementiran u Javi, prevoenje cup specikacije se vri pomou
java interpretatora na sledei nain:

java java_cup.Main options ime_specifikacije


Ime specikacije mora da ima ektenziju .cup.
10.4. CUP  GENERATOR SINTAKSNIH ANALIZATORA 213

Opcijama se moe prilagoditi izgled generisanog koda. Opcije koje se najee


koriste su:

-package ime_paketa denie ime paketa kojima e pripadati generisane


klase.

-parser ime_klase denie ime klase koja e sadrati parse() metod.


Ukoliko se ova opcija ne navede, ime generisane klase je parser.
-symbols denie ime klase u kojoj su kao statike konstante denisani
identikatori tokena. Ukoliko se ova opcija ne navede, ime generisane klase
je sym.
-nonterminals zahteva da u klasi sa identikatorima tokena budu generi-
sani i identikatori neterminalnih simbola. Poznavanje ovih identikatora
olakava praenje rada analizatoira prilikom debagiranja.

10.4.4 Korienje generisanog analizatora


Da bi se izvrila analiza pomou generisanog analizatora, treba kreirati objekat
klase parser i pozvati funkciju parse(). Konstruktor klase parser ima argument
tipa Scanner, to znai da to treba da bude objekat klase koja implementira
ovaj interfejs, tj. koja sadri funkciju next_token().

Primer 10.22 Korienje analizatora koji je generisan pomou Cup-a

public static void main(String[] args) {


try {
FileReader file = new FileReader(args[0]);
java_cup.runtime.Scanner myScanner = MyScanner(file);
parser myParser = parser(myScanner);
myParser.parse();
}
catch(Exception e) {
System.out.println(e);
}
}

Ukoliko je analizirani kod korektno zapisan, funkcija parse() e izvriti re-


dukciju tog koda na startni simbol gramatike i vratiti taj simbol kao rezultat.
Ukoliko se u kodu pojavi bilo kakva sintaksna greska, poziva se funkcija

void syntax_error(Symbol currentToken),


a zatim se pokuava da se izvri oporavak od grke. Ukoliko oporavak ne uspe,
poziva se funkcija:
214GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

void unrecovered_syntax_error(Symbol currentToken).


Funkcijesyntax_error i unrecovered_syntax_error su denaisane u klasi
lr_parser i one samo pozivaju odgovarajue metode za prikaz poruke o greci.
Metode za prikaz poruka o grekama su sledee.

public void report_error(String message, Object info)  Ova funk-


cija slui za prikaz poruke o sintaksnoj greci. U postojeoj implementaciji
ona samo prikazuje datu poruku, dok se drugi argument prosto ignotie.
Drugi argument slui ako u predenisanoj funkciji elimo da poruku o
greci  obogatimo dodatnim informacijama.

public void report_fatal_error(String message, Object info) 


Ovu metodu treba pozvati za prikaz poruke o greci kada oporavak nije
mogu. U postojeoj implementaciji ona poziva metodu report_error(),
poziva funkciju za prekid parsiranja done_parsing() i na kraju prijavljuje
izuzetak.

Kao to se vidi, implementacije svih ovih funkcija su jako  siromane pa je


generalna preporuka da se sve one predeniu u izvedenoj klasi  klasi koja se
generie. To znai da nove implementacije ovih funkcija treba pisati u delu

parser code {: ... :}.

10.5 Pitanja
1. ta je Lex/JFlex?

2. Objasniti strukturu Lex/Jex specikacije.

3. ta znae specijalna poetna stanja u Lex/Jex specikaciji. Kako se ona


deniu? Kako se koriste?

4. ta su makroi u u Lex/Jex specikaciji. Kako se deniu? Kako se


koriste?

5. Objasniti kako se koriste dodatni atributi simbola u Lex/Jex specikaciji.

6. ta je Yacc/Cup?

7. Objasniti strukturu Yacc/Cup specikacije.

8. Objasniti kako se koriste dodatni atributi simbola u Yacc/Cup specika-


ciji.

9. Objasniti mehanizam za oporavak od greaka u Yacc/Cup specikaciji.

10. Objasniti statiki deo koda sintaksnog analizatora generisanog pomou


Cupa.
10.6. ZADACI 215

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.

2. Kreirati Lex/Jex specikaciju za generisanje leksikog analizatora jezika


mPascal, koji je predstavljen grafom na slici 10.1.
216GLAVA 10. GENERATORI LEKSIKIH I SINTAKSNIH ANALIZATORA

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

Slika 10.1: Graf automata leksikog analizatora jezika Pascal


Glava 11

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:

sintaksno upravljane denicije (Syntax Directed Denitions )


translacione eme (Translation Shemes )
Sintaksno upravljane denicije su jednostavno denicije rutina pridruene pra-
vilima. Daju se na dosta visokom nivou i ne sadre informaciju o tome kako
se realizuju i kojim redosledom se primenjuju. Translacione eme pokazuju re-
dosled u kome se primenjuju semantika pravila to na neki nain utie i na
njihovu implementaciju. To znai da su neto nieg nivoa od denicija.

11.1 Sintaksno upravljane denicije


Sintaksno upravljane denicije su modikovane beskonteksne gramatike kod ko-
jih su simbolima gramatike pridodati atributi. Ako simbol gramatike zamislimo
kao vor u sintaksnom stablu, pri emu se taj vor implementira kao slog sa vie
polja, atributi odgovaraju imenima tih polja. Atributi mogu da predstavljaju
bilo ta: string, broj, memorijsku lokaciju ili bilo ta drugo to moe da zatreba
u toku analize. Vrednost atributa odreena je semantikom rutinom koja je
pridruena pravilu koje se koristi u odgovarajuem voru sintaksnog stabla.

Atributi mogu da budu generisani i nasleeni. Vrednosti generisanih atributa se


izraunavaju kao funkcije atributa potomaka odgovarajueg vora dok se vred-

217
218 GLAVA 11. ATRIBUTNE GRAMATIKE

nosti nasleenih atributa izraunaveju kao funkcije atributa roditeljskih vorova


i atributa ostalih vorova na istom nivou.

Na osnovu semantikih rutina mogu da se generiu grafovi zavisnosti (Depen-


dency Graphs ) koji pokazuju zavisnost izmeu atributa i odreuju kojim redo-
sledom se izraunavaju vrednosti atributa.

Sintaksno stablo koje sadri vrednosti atributa pridruenih vorovima se naziva


oznaemp sintaksno stablo (Annotated Syntax Tree ).

11.2 Generisani atributi


U sintaksno upravljanoj deniciji gramatike svakom pravilu gramatike pridru-
uje se skup semantikih rutina koje odreuje kako se izraunava vrednost atri-
buta koji je pridruen neterminalnom simbolu na levoj strani pravila. Vrednosti
atributa se izraunavaju u funkciji vrednosti atributa pridruenih simbolima na
desnoj strani pravila (slika 11.1).

Za pravila oblika
X Y1 Y2 . . . Yn
semantike rutine su oblika

X.a = f (Y1 .a, Y2 .a, . . . , Yk .a, . . . , Yn .a).

X X.a = f (Y1 .a, . . . , Yn .a)

Y1 Y2 Yn Y1 .a Y2 .a Yn .a

Slika 11.1: Generisan atribut

Generisani atributi se prosleuju navie kroz sintaksno stablo. Leksiki analiza-


tor obino obezbeuje atribute terminalnih simbola od kojih se dalje generiu
atributi neterminala i prosleuju navie kroz sintaksno stablo.

U tabeli 11.1 dat je skup pravila gramatike kojom se denie jednostavan kal-
kulator koji izvrava sabiranje i mnoenje cifara.

Semantikim rutinama koje su pridruene pravilima u tabeli 11.1 denie se


kako se izraunavaju vrednosti atributa pridruenih neterminalnim simbolima
gramatike. Preko atributa val izraunavaju se vrednost izraza i tampa preko
funkcijeprint, koja predstavlja semantiku rutinu pridruenu startnom simbolu.
Funkcija top. get(digit.lexval) preuzima iz tablice simbola vrednost cifre pred-
stavljene preko tokena digit.
11.3. NASLEENI ATRIBUTI 219

Tabela 11.1: Sintaksno upravljana denicija jednostavnog kalkulatora

Pravilo gramatike Semantike rutine

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)

Primer 11.1 Izraunavanje izraza 5 (3 + 4)


Na slici 11.2 prikazano je obeleeno sintaksno stablo prema kome se izrau-
nava vrednost izraza 5 (3 + 4), pri emu se koriste semantika pravila data
u tabeli 11.1. Vrednost izraza se izraunava preko generisanih atributa
obilaskom stabla odozdo navie.

U tabeli 11.2 prikazan je redosled izraunavanja i vrenosti atributa za raz-


matrani primer.

11.3 Nasleeni atributi


Nasleeni atributi se prosleuju nanie kroz sintaksno stablo, odnosno vrednosti
atributa na desnoj strani pravila se nasleuju od atributa sa leve strane pravila
(atributa roditeljskih vorova) i od atributa drugih simbola na desnoj strani
pravila (atributa vorova na istom nivou); slika 11.3. U ovom sluaju za pravila
oblika
X Y1 , Y2 , . . . , Yn ,
a semantike rutine su oblika

Yk .a = f (X.a, Y1 .a, Y2 .a, . . . , Yk1 .a, Yk+1 .a, . . . , Yn .a).

Ukoliko se za generisanje sintaksnog stabla koritsi neki bottom-up algoritam,


u ovom sluaju prvo se generie sintaksno stablo pa se prolaskom kroz stablo
izraunavaju vrednosti atributa.

Ovi atributi se koriste da se proslede informacije o vorovima stabla nanie kroz


stablo.
220 GLAVA 11. ATRIBUTNE GRAMATIKE

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

Slika 11.2: Oznaeno sintaksno stablo za izraz 5 (3 + 4) uz primer 11.1


11.3. NASLEENI ATRIBUTI 221

Tabela 11.2: Redosled izraunavanje i vrednosti atributa za izraz 5 (3 + 4) uz primer 11.1

vor Atribut Vrednost

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

Slika 11.3: Nasleeni atributi

U tabeli 11.3 date su semantike rutine za primenu nasleenih atributa u delu


gramtike kojom se deniu opisi tipova promenljivih. Uoimo da se semantikim
pravilom L.in := T.type, atribut L.in simbola L izraunava preko vrednosti
atributa T.type simbola T koji je na istom nivou sa simbolom L. Takoe,
semantikim pravilom L1 .in := L.in atribut L1 .in se izraunava preko atributa
L.in iz roditeljskog vora.

Primer 11.2 Nasleeni atributi  upis atributa tipa u tablicu simbola


Na slici 11.4 prikazano je oznaeno sintaksno stablo koje se dobija za izraz
real id1, id2, id3.
Prolaskom kroz sintaksno stablo odreuje se najpre vrednost atributa type
222 GLAVA 11. ATRIBUTNE GRAMATIKE

Tabela 11.3: Sintaksno upravljana denicija za upis tipova podataka

Pravilo gramatike Semantike rutine

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)

T.type = real L.in = real

real
L.in = real , id3

L.in = real , id2

id1
Slika 11.4: Oznaeno stablo za deniciju tipa uz primer 11.2

identikatora T. Ta vrednost se prenosi na atribut L.in i prosleuje nanie


kroz stablo sve do terminalnih simbola id, kada se upisuje u tablicu simbola
u slogu koji odgovara tom identikatoru. Ovaj upis u tablicu simbola vri
se preko funkcije addtype(id.entry, L.in), gde id.entry pokaziva na slog u
tablici simbola gde se pamte atributi identikatora id.
U tabeli 11.4 predstavljen je redosled i vrednosti atributa koji se izrauna-
vaju prema pravilima datim u tabeli 11.3 za izraz real id1, id2, id3.

Primer 11.3 Provera identikatora


U tabeli 11.4 predstavljena je gramatika kojom se denie struktura jedno-
vor Pravilo Vrednost Vrsta atributa

T T.type = real real generisani


11.3. NASLEENI ATRIBUTI

D L1 .in = T.type L1 .in := real nasleeni

L2 .in := L1 .in L2 .in := real


L1 nasleeni
addtype(id3 .entry, L1 .in) U TS se upisuje (id3 .entry, real)
L3 .in := L2 .in L3 .in := real
L2 nasleeni
addtype(id2 .entry, L2 .in) U TS se upisuje (id2 .entry, real)

L3 addtype(id1 .entry, L3 .in) U TS se upisuje (id1 .entry, real) nasleeni

Tabela 11.4: Redosled izraunavanja i vrednosti atributa za primer 11.2


223
224 GLAVA 11. ATRIBUTNE GRAMATIKE

stavnog programa (neterminal P ) koji sadri opise (D) i naredbe (S ). Deo


sa denicijama se sastoji od liste denicija oblika var V , gde se neterminal
V preslikava u imena promenljivih. Predviene su samo promenljive x, y
i z.
Deo sa naredbama moe da ima jednu ili vie naredbi dodeljivanja oblika
V := E , gde je E neterminal koji se odnosi na aritmetiki izraz na desnoj
strani naredbe dodeljivanja. Oblik aritmetikih izraza ovom gramatikom
nije denisan.

Semantika pravila gramatike su tako denisana da se u delu sa denicijama


tipa formila lista promenljivih koje su denisane i ta lista pamti kao atribut
D.dl. Ta vrednost se kao nasleeni atribut preslikava na neterminal S
kao atribut S.dl. Ova lista se koristi kod prepoznavanja svake naredbe
dodeljivanja da se proveri da je promenljiva kojoj se dodeljuje vrednost
prethodno denisana.

Na slici 11.5 predstavljeno je oznaeno sintaksno stablo koje odgovara pre-


poznavanju sledeeg programa denisanog gramatikom iz tabele 11.4.

var x;
var z;
x := ...;
z := ...;

U tabeli 11.6 predstavljen je postupak i redosled izraunavanja atributa.


U poslednjoj koloni nalazi se naznaka tipa atributa.

Tabela 11.5: Sintaksno upravljana denicija za proveru identikatora

Pravilo gramatike Semantika rutina

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

Atributne gramatike se u praksi jako puno koriste za reavanje razliitih pro-


blema. U narednim poglavljima bie pokazano kako se preko atributa i seman-
11.4. PROVERA TIPOVA PODATAKA (TYPE CHECKING) 225

D1 S1

var V1 ; D2 V3 := E1 ; S2

x var V2 ; D3 x V4 := E2 ; S3

z x

Slika 11.5: Oznaeno sintaksno stablo za gramatiku iz primera 11.3

tikih rutina denie generisanje meukoda, kao i provera tipova podataka.

11.4 Provera tipova podataka (Type Checking )


Sastavni deo savremenih kompilatora su i moduli za proveru tipova podataka
koji se realizuju u skladu sa time kako je postavljen koncept tipova podataka
u jeziku na koji se odnosi kompilator. Za proveru tipova podataka danas se
obino koriste atributne gramatike.

11.4.1 Semantika pravila za proveru tipova podataka


Za proveru tipova podataka koriste se atributi tipa koji se za svaki element
jezika koji ima svojstvo tipa uvaju u tabeli simbola. Vrednosti ovih atributa
odreuju se u toku sintaksne analize denicija tipova podataka.

Razmotriemo primer jednog jednostavnog jezika denisanog sledeom grama-


tikom:

P D; E (program se sastoji od opisa i izvrnog dela)

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

Tabela 11.6: Izraunavanje atributa za program iz primera 11.3

vor Atributi Tip atributa

V1 V1 .name = x generisani

V2 V2 .name = z generisani

D3 D3 .dl = NULL generisani

D2 D2 .dl = addlist(z, D3 .dl) = (z) generisani

D1 D1 .dl = addlist(x, D2 .dl) = (x, z) generisani

P S1 .dl := D1 .dl = (x, z) nasleeni

V3 V3 .name = x generisani

S1 check(x, (x, z)), S2 .dl := S1 .dl = (x, z) nasleeni

V4 V4 .name = z generisani

S2 check(z, (x, z)), S3 .dl := S2 .dl nasleeni

u polje odgovarajueg identikatora.

Tabela 11.7: Semantika pravila za tipove identikatora

Pravila gramatika Semantike rutine

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)

Primer semantikih pravila kojima se proverava kompatibilnost tipova poda-


taka u aritmetikim izrazima dat je u tabeli 11.8. U poslednja tri reda, t je
elementarni tip dobijen iz strukturnog tipa array(s, t).
Atribut tipa moe da se primeni i na naredbe. Ako je naredba korektna onda
ovaj atribut dobija vrednost void ako nije generie se poruka o greci. Za ge-
nerisanje atributa tipa naredbi mogu se koristiti semantika pravila data u ta-
beli 11.9.
Pravila gramatike Semantike rutine

E literal E.type := char

E num E.type := integer

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)

E E1 (E2 ) type error, inae

Tabela 11.8: Provera tipova u izrazima.


227
228 GLAVA 11. ATRIBUTNE GRAMATIKE

Tabela 11.9: Provera strukture naredbe

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

Na slian nain mogu da se proveravaju i druga pravila vezana za tipove po-


dataka u jeziku. Na primer kod jezika kod kojih se koriste implicitna pravila
za konverziju tipova u izrazima koji sadre operande razliitog tipa mogu da
se deniu semantika pravila kojima se to realizuje. U tabeli 11.10 data su
semantika pravila za konverziju tipa integer u tip real.
Tabela 11.10: Konverzija tipova

Pravilo
Semantiko pravilo
gramatike

E num E.type := integer

E num.num E.type := real

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

2. Objasniti koncept generisanih atributa i dati primer gramatike sa ovim


atributima.

3. Objasniti koncept nasleenih atributa i dati primer gramatike sa ovim


atributima.

4. ta je zadatak modula za proveru tipova podataka.

5. Dati primer semantikih pravila kojima se generiu atributi tipa identi-


katora.

6. Dati primer semantikih pravila kojima se vri provera kompatibilnosti


tipova u izrazima.

7. Dati primer semantikih pravila kojima se vri provera upravljakih na-


redbi programa.

8. Dati primer semantikih pravila kojima se vri konverzija tipa u izrazima.

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.

2. U tabeli 11.11 data je gramatika sa semantikim pravilima kojima se de-


niu binarni brojevi i izraunava njihova dekadna vrednost. Korienjem
ove gramatike,

(a) nacrtati sintaksno stablo za binarni broj 1011;


(b) na oznaenom sintaksnom stablu prikazati izraunavanje vrednosti
binarnog broja 1011 i

(c) prikazati koji su atributi generisani, a koji nasleeni.

3. U tabeli 11.12 data je gramatika sa semantikim pravilima kojima se de-


niu identikatori kod kojih se pojavljuju slova a, b i c, ali ne u parovima.
Za zadatu gramatiku

(a) prikazati koji su atributi generisani, a koji nasleeni;

(b) nacrtati sintaksno stablo za identikator bca i

(c) na oznaenom sintaksnom stablu prikazati proveru za bca.


230 GLAVA 11. ATRIBUTNE GRAMATIKE

Tabela 11.11: Pravila za izraunavanje vrednosti binarnih brojeva

Pravila gramatike Semantike rutine


B.pos = 1
B1 B.val = D.val
D.pow = 0
B1 .pos = B2 .pos + 1
B1 = DB2 B1 .val = B2 .val + D.val
D.pow = B2 .pos

D=0 D.val = 0

D=1 D.val = 2D.pow

Tabela 11.12: Provera identikatora. je znak za nadovezivanje.

Pravila gramatike Semantike rutine


I.str = {}
I.last =
DI
D.val = I.val
accept, ako je D.val 6= error
L.str = I.str
L.last = I.last
I LI1
I1 .str = L.val
I.val = I1 .val
L.str = I.str
IL L.last = I.last
I.val = L.val
(
L.str a L.last 6= a
L.val =
La error inae
L.last = a
(
L.str b L.last 6= b
L.val =
Lb error inae
L.last = b
(
L.str c L.last 6= c
L.val =
Lc error inae
L.last = c
Glava 12

Meukodovi

U ovom poglavlju bie razmotrene vrste meukodova koji se koriste u okviru


kompilatora kao i tehnike za njihovo generisanje. Akcenat e biti na apstrakt-
nom sintaksnom stablu kao strukturi koja predstavlja osnovu za generisanje
koda kao i na troadresnom meukodu koji se danas najvie koristi u praksi.

12.1 Mesto meukoda u procesu prevoenja


Proces analize koda se obino zavrava generisanjem meukoda koji je mainski
nezavisna reprezentacija koda pogodna za generisanje asemblerskog ili main-
skog koda razliitih ciljnih maina (slika 12.1).

sintaksni generator meukod generator


analizator meukoda koda

Slika 12.1: Mesto meukoda u okviru kompilatora

Kompilator moe da koristi i meukod u vie nivoa, kako je to predstavljeno na


slici 12.2.

izvorni meukod meukod ciljni


kod vieg nivoa nieg nivoa kod

Slika 12.2: Meukod u vie nivoa

Postoji vie razloga zbog kojih se uvodi meukod, od kojih su najznaajniji:

Prenosivost koda  na osnovu meukoda moe se generisati kod za razliite


ciljne maine.

231
232 GLAVA 12. MEUKODOVI

Optimizacija koda  na nivou meukoda moe da se vri mainski nezavi-


sna optimizacija.

Meukod moe da bude generisan u razliitim oblicima. Ovde emo razmotriti


apstraktno sintaksno stablo i troadresni meukod kao dva najire rasprostra-
njena oblika meukoda. Nekada se kao meukod koristila i poljska inverzna
notacija koja je pogodna za interpretiranje koda i generisanje mainskog koda
korienjem steka. Veoma esto se kao meukod koristi i programski jezik C,
zato to se naredbe ovog jezika postavljene dosta blizu asemblerskom jeziku i
lako se transformiu u asemblerski jezik.

12.2 Apstraktno sintaksno stablo


Apstraktno sintaksno stablo je struktura koja se generie na osnovu sintaksnog
stabla i na neki nain predstavlja redukovanu reprezentaciju sintaksnog sta-
bla. Obino se generie direktno u toku same sintaksne analize ili se najpre
generie sintaksno stablo (parse tree ) a nakon toga ta struktura transformie u
apstraktno sintaksno stablo. U tabeli 12.1 predstavljena su pravila gramatike
kojom se deniu aritmetiki izrazi, kao i semantika pravila koja se pridruuju
ovim pravilima, koja se koriste za generisanje apstraktnog sintaksnog stabla.
U sluaju bootum-up analize, semantika pravila se primenjuju posle reduk-
cije pravilom gramatike kome su pridruena dok se u sluaju top-down analize
najpre generie sintaksno stablo (utvrdi redosled primene pravila gramatike),
a zatim to stablo obilazi odozdo navie i pri tome se primenom semantikih
pravila generie apstraktno sintaksno stablo.

Tabela 12.1: Semantika pravila kojima se generie apstraktno sintaksno stablo

Pravila gramatika Semantike rutine

S id := E S.sptr := mknode(:=, mkleaf(id, id.entry), E.nptr)


E E1 + E2 E.nptr := mknode(+, E1 .nptr, E2 .nptr)
E E1 E2 E.nptr := mknode(, E1 .nptr, E2 .nptr)
E E1 E.nptr := mknode(, E1 .nptr)
E (E1 ) E.nptr := E1 .nptr
E id E.nptr := mkleaf(id, id.entry)

Korienjem semantikih pravila datih u tabeli 12.1 moe se konstruisati ap-


strakno sintaksno stablo za naredbe dodeljivanja denisane datom gramatikom.

U tabeli 12.1, izraz oblika

P.nptr := mknode(V, A.nptr, B.nptr)


12.2. APSTRAKTNO SINTAKSNO STABLO 233

predstavlja poziv funkcije kojom se generie vor apstraktnog sintaksnog stabla


pri emu je P.nptr pokaziva na taj vor, prvi argument (V ) vrednost u voru
stabla, a druga dva argumenta su pokazivai na vorove potomke.

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.

Primer 12.1 Generisanje apstraktnog sintaksnog stabla


U sluaju naredbe dodeljivanja a := b * (d + c) + b * (d + c) koju
sintaksni analizator dobija u obliku id := id * (id + id) + id * (id +
id), primenom semantikih pravila iz tabele 12.1 bie generisano sintaksno
stablo prikazano na slici 12.3. Na slici 12.4 prikazan je i odgovarajui
dijagram koji se dobija redukcijom stabla tako to se ne generiu novi
vorovi u sluaju da odgovarajui ve postoje.

Na osnovu date gramatike, levim izvoenjem izraz id := id * (id + id)


+ id * (id + id) se generie primenom sledeih smena:
S id := E
id := E + E
id := E E + E
id := id E + E
id := id (E) + E
id := id (E + E) + E
id := id (id + E) + E
id := id (id + id) + E
id := id (id + id) + E E
id := id (id + id) + id E
id := id (id + id) + id (E)
id := id (id + id) + id (E + E)
id := id (id + id) + id (id + E)
id := id (id + id) + id (id + id)

U ovom sluaju prilikom generisanja apstraktnog sintaksnog stabla bie


234 GLAVA 12. MEUKODOVI

izvren sledei niz koraka.

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.

12.3 Implementacija apstraktnog sintaksnog sta-


bla
Apstraktno sintaksno stablo se moe memorisati kao statika ili dinamika struk-
tura.

Procedure iz tabele 12.1 denisane su tako da se generie dinamika struktura


koja je za razmatrani primer prikazana na slici 12.4. Prilikom generisanja struk-
ture mogu da se izvravaju i procedure za redukciju stabla tako da se ne gene-
riu novi vorovi ako u stablu ve postoje odgovarajui. U tom sluaju dobija
se struktura dijagrama u okviru koje do nekih vorova vodi vie pokazivaa, za
razmatrani primer, slika 12.5.

U sluaju statike implementacije umesto pokazivaa u poljima slogova pamte


se adrese odgovarajuih slogova sa kojima su povezani. Za naredbu dodeljivanja
iz primera 12.1, statika implementacija je data u tabeli 12.2.

12.4 Troadresni meukod


Troadresni meukod je neka vrsta pseudoasemblerskog jezika koji se moe lako
preslikati u drugi asemblerski jezik ili mainski kod. Sastoji se od jednostavnih
naredbi koje mogu da imaju najvie jedan operator tako da se sloeni izrazi
predstavljaju sekvencom naredbi. Na primer, izraz x + y * z moe da se pred-
236 GLAVA 12. MEUKODOVI

:=

id a +

id b +

id d id c

Slika 12.5: Apstraktno sintaksno stablo memorisano kao dijagram

stavi sekvencom troadresnih instrukcija

t1 = y z
t2 = t1 + x

gde su t1 i t2 privremene (temporalne) promenljive koje generie kompilator.


Takoe, troadresni kod sadri i jednostavne upravljake naredbe, kao to su
bezuslvni skokovi i uslovni skokovi, koje se direktno preslikavaju u asemblerske
naredbe.

Lista osnovnih naredbi troadresnog koda se sastoji od sledeih naredbi.

1. Naredba dodeljivanja x := y op z , gde je op aritmetiki ili logiki binarni


operator.

2. Naredba dodeljivanja x := op y , gde je op aritmetiki ili logiki unarni ope-


rator (npr. minus, logika negacija, shift operator, operatori za konverziju
tipova i sl).

3. Naredba kopiranja x := y kojom x dobija vrednost y.


4. Oznaka ili labela L:
5. Naredba bezuslovnog skoka goto L.
6. Naredba uslovnog skoka if x relop y goto L.
7. param x, navoenje parametara.
8. call p, n za poziv potprograma. Pre ove naredbe navode se parametri
12.4. TROADRESNI MEUKOD 237

Tabela 12.2: Statika implementacija apstraktnog stabla

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

9. x := fcall f, n  poziv funkcijskog potprograma. n oznaava broj argume-


nata potprograma koji se kao i u prethodnom sluaju navode pre naredbe
za poziv potprograma.

10. return  povratak iz potprograma.


11. freturn x  povratak iz funkcijskog potprograma kada se kao rezultat
vraa vrednost promenljive x.
12. x := y[i]  preuzimanje vrednosti elementa polja.

13. x[i] := y  dodeljivanje vrednosti elementu polja.

Primer 12.2 Primer troadresnog meukoda


238 GLAVA 12. MEUKODOVI

U sluaju naredbe dodeljivanja

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

Navedeni niz naredbi troadresnog koda je u sutini samo simbolika reprezenta-


cija ovih naredbi. Kompilator moe da koristi svoje specine strukture poda-
taka za reprezentaciju troadresnih naredbi. U praksi se sreu tri modela koji se
obino nazivaju quadriples, triples i indirect triples.

12.4.1 Quadriples struktura


U sluaju reprezentacije pomou Quadruples strukture koriste se slogovi sa po
etri polja koja su namenjena smetaju operatora (op), prvog argumenta (arg1 ),
drugog argumenta (arg2 ) i rezultata (rez). Kod nekih naredbi naka od ovih polja
ostaju neiskoriena. U tabeli 12.3 date su osnovne naredbe troadresnog koda
predstavljene u formatu Quadriplesa.

Primer 12.3 Quadriples struktura


Troadresni kod iz primera 12.2 kojim je predstavljena naredba dodeljivanja

a := b (d + c) + b (d + c)

bie memorisan preko quadrapilsa prikazanih u tabeli ??. Napomenimo da


e kompilator umesto imena promenljivih a, b i c koristiti pointere na ove
identikatore u tabeli simbola. Temporalne promenljive kompilator moe
takoe da ubaci u tabelu simbola kao da se radi o promenljivima koje je
uveo programer ili za njih generie posebnu klasu Temp.

12.4.2 Triples struktura


Kod reprezentacije troadresnog meukoda pomou triples strukture koriste se
slogovi sa tri polja. Uoimo da se kod reprezentacije pomou quadruples slogova
polje rez uglavnom koristi za smetaj temporalnih promenljivih koje se generiu
12.4. TROADRESNI MEUKOD 239

Tabela 12.3: Osnovne troadresne naredbe predstavljene kao Quadriplesi

Naredba Quadriples Opis


binop je binarni operator:
1 x := y binop z op x y z +, , , /, , , <, , =, , >, 6=
op {PLUS, MINUS, TIMES, DIV, LT, LE, EQ, GE, NE}
unop je unarni operator: ,
2 x := unop y op x y
op {NEG, NOT}
3 x := y ASSIGN x y kopiranje vrednosti y u x
4 L: LABEL L oznaka (labela)

5 goto L GOTO L naredba bezuslovnog skoka

6 if x goto L IF L x naredba uslovnog skoka

7 paramf x PAR x denisanje parametara potprograma

8 call p, n CALL p n poziv potprograma p sa n argumenata

9 x := fcall f, n FCALL x f n poziv funkcijskog potprograma

10 return RET povratak iz potprograma

povratak iz funkcijskog potprograma


11 return x FRET x
kada se kao rezultat vraa x
12 x := y[k] LDAR x y k preuzimanje vrednosti promenljive sa indeksom

13 x[k] := y STAR x k y dodeljivanje vrednosti promenljivoj sa indeksom

Tabela 12.4: Meukod memorisan kao quadriples struktura

op rez arg1 arg2

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

u procesu generisanja meukoda i uglavnom slue za uvanje meurezultata. U


sluaju triples strukture na temporalne promenljive se ukazuje preko pozicije
odgovarajueg sloga umesto preko rednog broja promenljive.

Primer 12.4 Triples format


Troadresni kod iz primera 12.2 kojim je predstavljena naredba dodeljivanja

a := b (d + c) + b (d + c)

bie memorisan preko triples slogova kao u tabeli 12.5.

Tabela 12.5: Meukod memorisan kao triples struktura

op arg1 arg2

0 + d c
1 b 0
2 + d c
3 b 2
4 + 1 3
5 = a 4

12.4.3 Indirect triples struktura


U sluaju strukture indirect triples koristi se i dodatna lista pokazivaa na tri-
ples slogove kojima su predstavljene naredbe. Ovo moe da bude pogodno kod
implementacije razliitih algoritama za optimizaciju koda, kada se vri preure-
ivanje naredbi. U tom sluaju razmetanja se vre samo u listi pokazivaa, a
sama struktura sa slogovima naredbi ostaje nepromenjena.

Primer 12.5 Indirect triples


Troadresni kod iz primera 12.2 kojim je predstavljena naredba dodeljivanja

a := b (a + c) + b (a + c)

memorieindirect triples strukturom kao to je to prikazano u tabeli 12.6.


12.5. TROADRESNI MEUKOD ZA NAREDBE DODELJIVANJA 241

Tabela 12.6: Troadresni kod predstavljen indirect triples strukturom

naredbe op arg1 arg2

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

12.5 Troadresni meukod za naredbe dodeljiva-


nja
Slino kao i kod generisanja apstraktnog sintaksnog stabla, i troadresni kod se
moe generisati u toku samog procesa sintaksne analize ili nakon generisanja sin-
taksnog stabla. I u ovom sluaju pravilima gramatike se pridruuju semantike
rutine koje se vezuju za sintaksna pravila. U tabeli 12.7 data su pravila gra-
matike i pridruena semantika pravila kojima se generie troadresni meukod
aritmetikih izraza. Uoimo da se semantikim pravilima generie atribut addr
neterminala E koji oznaava adresu memorijske lokacije gde se uva vrednost za
E. Funkcija top. get(id.lexeme) ita iz tabele simbola leksemu koja predstavlja
ime identikatora (simboliku adresu odreenog identikatora), dok funkcija
top. get(cons.lexval) preuzima iz tabele simbola vrednost konstante
cons. Funk-
cijagen() generie navedeni kod i nadovezuje ga na ve postojei kod. Sa new
Temp() generie se nova temporalna promenljiva i smeta u tabelu simbola.

Primer 12.6 Generisanje troadresnog meukoda za naredbu dodeljivanja


Na slici 12.6 Predstavljeno je sintaksno stablo koje se dobija u toku sin-
taksne analize naredbe dodeljivanja

a := b (a + c) + b (a + c)

iz primera 12.1. U vorovima stabla predstavljeni su atributi pridreeni ne-


terminalnim simbolima kao i vrednosti koje im se dodeljuju prema seman-
tikim pravilima iz tabele 12.7. Ovakvo stablo, na kome su predstavljeni i
atributi naziva se oznaeno sintsaksno stablo.

Da bi generisanje meukoda bilo jasnije, na istoj slici predstavljene su i


naredbe troadresnog koda koji se generie. Sa slike se vidi koja sintaksna
242 GLAVA 12. MEUKODOVI

Tabela 12.7: Semantika pravila za naredbu dodeljivanja

Pravilo gramatike Semantiko pravilo

(1) S id := E; {gen(top. get(id.lexeme) ':=' E.addr)}


{E.addr = new Temp()}
(2) E E1 + E2
{gen(E.addr ':=' E1 .addr '+' E2 .addr)}
{E.addr = new Temp()}
(3) E E1 E2
{gen(E.addr ':=' E1 .addr '*' E2 .addr)}
{E.addr = new Temp()}
(4) E E1
{gen(E.addr ':=' minus E1 .addr)}

(5) E (E1 ) {E.addr = E1 .addr}

(6) E id {E.addr = top. get(id.lexeme)}

(6) E cons {E.addr = top. get(const.lexval)}

pravila se izvravaju u vorovima i kako tee generisanje koda. Napome-


nimo da se sintaksno stablo obilazi odozdo navie.

U tabeli 12.8 data su semantika pravila koja omoguavaju generisanje troadre-


snog koda za aritmetike izraze koji sadre promenljive sa indeksima.

Primer 12.7 Meukod za promenljive sa indeksima


Razmotriemo generisanje troadresnog meukoda za izraz

b = c[i] + a[i][j],

gde je a celobrojna matrica dimenzija 4 3, c celobrojni vektor sa 4 ele-


menata a iij su celobrojne promenljive. Ako pretpostavimo da je duina
jednog celobrojnog podatka 4 bajta, tada su u tabelu simbola uneti sledei
atributi i njihove vrednosti.

a.type = array(4, array(3, integer))


a.type.with = 4 3 4 = 48
a[].type = array(3, integer)
a[].type.with = 3 4 = 12
a[][].type = integer
a[][].type.with = 4
a := t5

id := E.addr = t5
t5 := t2 + t4

E.addr = t2 + E.addr = t4
t2 := b * t1 t4 := b * t3

E.addr = b E.addr = t1 E.addr = b E.addr = t3

id id

( E.addr = t1 ) ( E.addr = t3 )
t1 := d + c t3 := d + c

E.addr = d + E.addr = c E.addr = d + E.addr = 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

Tabela 12.8: Semantika pravila za generisanje troadresnog meukoda za izraze sa indeksima

Pravilo gramatike Semantiko pravilo

(1) S id := E; {gen(top. get(id.lexeme ':=' E.addr))}

(2) S L := E; {gen(L.array.base '[' L.addr ']' ':=' E.addr)}


{E.addr = new Temp()}
(3) E E1 + E2
{gen(E.addr ':=' E1 .addr '+' E2 .addr)}

(4) E id {E.addr = top. get(id.lexeme)}


{E.addr = new Temp()}
(5) E L
{gen(E.addr ':=' L.array.case '[' L.addr ']')}
{L.array = top. get(id.lexeme)}
{L.type = L.array.type.elem}
(6) L id[E]
{L.addr = new Temp()}
{gen(L.addr ':=' E.addr '*' L.type.with)}
{L.array = L1 .array}
{L.type = L1 .type.elem}
{t = new Temp()}
(7) L L1 [E]
{L.addr = new Temp()}
{gen(t ':=' E.addr '*' L.type.width)}
{gen(L.addr ':=' L1 .addr '+' t)}
12.6. TROADRESNI MEUKOD UPRAVLJAKIH NAREDBI 245

c.type = array(4, integer)


c.type.with = 4 4 = 16
c[].type = integer
c[].type.with = 4.

Sintaksno stablo za izraz

b = c[i] + a[i][j]

dato je na slici 12.7, a odgovarajue oznaeno sintaksno stablo na kome su


prikazani svi atributi i vrednosti koje im se dodeljuju, kao i generisani kod
dato je na slici 12.8.

Za zadati izraz generie se sledei meukod:

t1 := i 4
t2 := c[t1 ]
t3 := i 12
t4 := j t4
t5 := t1 + t2
t6 := a[t5 ]
t7 := t2 + t6
b := t7

12.6 Troadresni meukod upravljakih naredbi


U tabeli 12.9 predstavljena su semantika pravila koja omoguavaju generisa-
nje troadresnog meukoda za upravljake naredbe. U ovoj tabeli funkcijom
newlabel() generiu se nove labele, a funkcijom label(Labela), u kod se ubacuje
labela. Atribut code pamti odreeni deo koda (Bulovog izraza ili naredbe), a
atribut S.next labelu koja ukazuje na naredbu koja sledi iza naredbe S.
Kako se u okviru upravljakih naredbi javljaju logiki izrazi potrebno je deni-
sati i semantika pravila za generisanje troadresnog meukoda logikih izraza.
U tabeli 12.10 data su ova semantika pravila.

Primer 12.8 Troadresni kod za if naredbu


Razmotrimo sledeu if naredbu.

if (x < 100 || x > 200 && x != y) x := 0;


246 GLAVA 12. MEUKODOVI

id := E

E + E

L L

id [ E ]
L [ E ]
c id
id [ E ] id
i
a id j

Slika 12.7: Sintaksno stablo za izraz b = c[i] + a[i][j] iz primera 12.7


12.6. TROADRESNI MEUKOD UPRAVLJAKIH NAREDBI 247

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

Slika 12.8: Oznaeno sintaksno stablo sa slike 12.7 uz primer 12.7


GLAVA 12. MEUKODOVI

Pravilo gramatike Semantiko pravilo


S.next = newlabel()
P S
P.code = S.code; label(S.next)
S assign S.code = assign.code
B.true = ()
S id (B) S1 B.false = S1 .next = S.next
S.code = B.code; label(B.true); S1 .code
B.true = newlabel()
B.false = newlabel()
S if (B) S1 else S2
S1 .next = S2 .next = S.next
S.code = B.code; label(B.true); S1 .code; gen(goto S.next); label(B.false); S2 .code
begin = newlabel()
B.true = newlabel()
S while (B) S1 B.false = S.next
S1 .next = begin
S.code = label(begin); B.code; label(B.true); S1 .code; gen('goto' begin)
S1 .next = newlabel()
S S1 S2 S2 .next = S.next
S.code = S1 .code; label(S1 .next); S2 .code
Tabela 12.9: Semantika pravila za generisanje troadresnog meukoda za upravljake naredbe
248
12.6. TROADRESNI MEUKOD UPRAVLJAKIH NAREDBI 249

Tabela 12.10: Semantika pravila za generisanje troadresnog meukoda za Bulove izraze

Pravilo gramatike Semantike rutine


B1 .true = B.true
B1 .false = newlabel()
B B1 || B2 B2 .true = B.true
B2 .false = B2 .false
B.code = B1 .code; label(B1 .false); B2 .code
B1 .true = newlabel()
B1 .false = B.false
B B1 && B2 B2 .true = B.true
B2 .false = B2 .false
B.code = B1 .code; label(B1 .true); B2 .code
B1 .true = B.false
B !B1 B1 .false = B.true
B.code = B1 .code
B.code = E1 .code; E2 .code;
B E1 rel E2 gen('if' E1 .addr rel E2 .addr 'goto' B.true);
gen('goto' B.false)

B true B.code = gen('goto', B.true)

B false B.code = gen('goto', B.false)


250 GLAVA 12. MEUKODOVI

Primenom gramatika iz tabela 12.9 i 12.10 za zadatu naredbu generie se


sintaksno stablo prikazano na slici 12.9. Napomenimo da je operacija &&
(and ) vieg prioriteta od operacije || (or ).
Na osnovu semantikih pravila iz tabela bie generisane sledee vrednosti
atributa i troadresni meukod prikazan u tabeli 12.11. vorvi su navedeni
u redosledu koji odgovara obilasku stabla odozdo navie.

Korienjem semantikih pravila datih u tabeli 12.9 i tabeli 12.10 bie


generisan sledei troadresni meukod.

if x < 100 goto Lab3 goto Lab2


Lab2: if x < 100 goto Lab1 goto Lab4
Lab1: if x 6= y goto Lab3 goto Lab4
Lab3: x := 0
Lab4:

if ( B ) S1

id5 := con3

B1 || B2

E1 < E2
B3 && B4
id1 con1
E3 > E4 E5 6= E6

id2 con2 id3 id4

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

vor Atribut i kod

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

Sledei primer ilustruje generisanje troadresnog meukoda na primeru jednog


funkcijskog potprograma.

Primer 12.9 Meukod funkcijskog potprograma


Primenom pravila iz tabele 12.9 i tabele 12.10 generisaemo meukod sle-
deeg funkcijskog potprograma.

function fact(x: integer): integer;


var u: integer;
begin
if x = 0 then u := 1
else u := fact(x - 1) * x;
fact := u
end {fact}
Bie generisan sledei meukod.

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.

2. Navseti osnovne vrste meukoda.

3. Dati primer apstraktnog sintaksnog stabla.

4. Kako se implementira sintaksno stablo?

5. Navesti semantika pravila za generisanje apstraktnog sintaksnog stabla.

6. ta je to troadresni meukod?

7. Kako se implementira troadresni meukod?

8. Objasniti strukturu quadriples i dati primer.


12.8. ZADACI 253

9. Objasniti strukturu triples i dati primer.

10. Objasniti strukturu indirect triples i dati primer.

11. Navesti osnovne naredbe troadresnog meukoda.

12. Dati primer semantikih pravila kojima se generie troadresni meukod za


izraze.

13. Dati primer semantikih pravila kojima se generie troadresni meukod za


promenljive sa indeksima.

14. Dati primer semantikih pravila kojima se generie troadresni kod osnov-
nih upravljakih struktura.

15. Dati primer semantikih pravila kojima se generie troadresni meukod za


Bulove izraze.

12.8 Zadaci
1. Generisati apstraktno sintaksno stablo za sledee aritmetike izraze.

a+bc+ad
b + c (a) + d + c (a)

Generisana stabla prikazati kao dinamike i kao statike strukture.

2. Generisati oznaeno sintaksno stablo za generisanje troadresnog meukoda


za izraze iz prethodnog zadatka.

3. Generisati troadresni meukod za izraz iz provog zadatka.

4. Dati quadrapiles strukturu za troadresni kod iz prethodnog primera.

5. Korienjem gramatike iz tabele 12.8 generisati sintaksno stablo za na-


redbu dodeljivanja
a[i] := b[i][k] + c[i].

6. Korienjem semantikih pravila iz tabele 12.8 generisati oznaeno sintak-


sno stablo za naredbu dodeljivanja, za sluaj kada je b celobrojna matrica
dimenzija 5 5, a aic celobrojni vektori sa po 5 elemenata.

7. Za naredbu dodeljivanja iz prethodnog zadatka generisati troadresni me-


ukod i predstaviti ga quadrapiles strukturom.

8. Korienjem gramatike iz tabela 12.9 i 12.10 generisati sintaksno stablo


za sledeu naredbu:

if a b && a < c then a := b + c


else if c < d then a := d
254 GLAVA 12. MEUKODOVI

9. Korienjem semantikih pravila iz tabela 12.9 i 12.10 generisati oznaeno


sintaksno stablo za if naredbu iz prethodnog zadatka.

10. Za if naredbu iz prethodnog zadatka generisati troadresni meukod i pred-


staviti ga quadrapiles strukturom.

11. Korienjem gramatike iz tabela 12.9 i 12.10 generisati oznaeno sintaksno


stablo za sledeu sekvencu naredbi.

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.

13. Za sekvencu naredbi iz prethodnog zadatka generisati troadresni meukod


i predstaviti ga quadrapiles strukturom.
Glava 13

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.

Pored ove osnovne optimizacije, koja je praktino obavezna, obino se prime-


njuje i itav niz dodatnih optimizacija sa ciljem da se dobije to ekasniji kod.
esto se ostavlja mogunost da se ove dodatne optimizacije ukljuuju opciono,
tako da se kod praktinog rada najpre nastoji da se dobije funkcionalno ispravan
kod, a nakon toga se ukljuuju raspoloive optimizacije. Osnovno pravilo kod
svake optimizacije koda je da ne sme da se narui ispravnost koda. Kod mora
da ostane funkcionalno ispravan posle optimizacije.

13.1 Osnovna optimizacija koda (peephole opti-


mizacija)
Osnovna optimizacija se obino vri ve na nivou meukoda i najveim delom
je mainski nezavisna. Nekad se u osnovnu optimizaciju ukljuuju i neki koraci
kojima se koriste prednosti procesora za koji se generie kod, odnosno mainski
zavisne transformacije.

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.

Transformacije koda koje se vre u okviru peephole optimizacije se mogu svrstati


u sledeih nekoliko grupa:

eliminisanje redundantnih naredbi,

optimizacija toka programa,

algebarska uproenja i

korienje mainskih idioma.

13.1.1 Eliminisanje redundantnih naredbi


Ovom grupom obuhvaene su transformacije kojima se iz koda izbacuju suvine
naredbe, ili grupe naredbi, koje su obino posledica samog automatizma koji se
primenjuje kod generisanja koda.

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.

Oigledno je da se ove dve naredbe mogu izbaciti, a da se time ne narui funk-


cionalnost koda.

Meutim, elminisanje se ne sme izvriti u sluaju kada je druga naredba ozna-


ena labelom jer to znai da se u nekim sluajevima do naredbe LOAD dolazi
tako da joj ne prethodi naredba STORE.
STORE T1, R1
Lab1: LOAD T1, R1
Slian primer redundantnosti imamo i u sledeem sluaju:

MOV R0, A ; (A) => R0


MOV A, R0 ; (R0) => A
Druga naredba moe da bude izostavljena zato to prilikom kopiranja sadraja
memorijske lokacije A u registar R0 , sadraj te lokacije ostaje neizmenjen i nije
potrebno ponovo ga obnavljati.
13.1. OSNOVNA OPTIMIZACIJA KODA (PEEPHOLE OPTIMIZACIJA)257

13.1.2 Optimizacija toka


U toku generisanja meukoda esto se javljaju skokovi na skokove, skokovi na
uslovne skokove ili uslovni skokovi na bezuslovne skokove. U mnogim takvim
sluajevima mogue su redukcije.

Ovakvi sluajevi nastaju kao posledica generisanja meukoda u sluajevima


kada se u okviru petlji javljaju if naredbe ili druge petlje ili kada u okviru jedne
if naredbe imamo umetnute if naredbe i petlje.

Bezuslovni skok na bezuslovni skok

Na primer, sekvencu naredbi

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.

Uslovni skok na bezuslovni

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.

Bezuslovni skok na uslovni

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.

13.1.3 Nedosegljiv kod


Eliminiu se naredbe koje se u odreenom kontekstu nee nikada izvriti. Na
primer, naredba koja sledi iza naredbe bezuslovnog skoka se moe izbaciti.

Razmotrimo sledeu sekvencu nardbi u C-u.

# 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

13.1.4 Algebarska uproenja


Kao rezultat automatskog generisanja koda, u nekim posebnim sluajevima
mogu da budu generisane naredbe koje se mogu zameniti jednostavnijim na-
redbama ili potpuno izbaciti. Na primer, sledee naredbe mogu da se potpuno
izbace zato to se dodavanjem nule ili mnoenjem jedinicom ne menja vrednost.

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

13.1.5 Direktna redukcija


Sastoji se u tome da se sloene operacije zamenjuju jednostavnijima koje se bre
izvravaju. Neke od moguih transformacija su:

Stepenovanje se zamenjuje viestrukim mnoenjem X2 = X X


Mnoenje i deljenje stepenom dvojke se zamenjuje ift operacijma.

Deljenje realnom konstantnom se zamenjuje mnoenjem sa konstantom


ija je vrednost jednaka recipronoj vrednosti te konstante, to je nekad
bre.

13.1.6 Korienje mainskih idioma


Osnovna optimizacija moe da ukljuuje i neke mainski zavisne transformacije,
kojima se koriste prednosti i specinosti asemblerskog jezika maine za koju se
generie kod. Na taj nain mogu da se iskoriste neki posebni oblici adresiranja,
neki specini registri procesora ili neke posebne naredbe ciljnog jezika. Ove
transformacije se najee odnose na korienje:

samoindeksiranja,

samoinkrementiranja,

specinih adresiranja,

specinih registara procesora i

korienje steka.
260 GLAVA 13. OPTIMIZACIJA KODA

13.2 Dodatna optimizacija


U cilju poboljanja kvaliteta generisanog koda kompilator moe da ukljui i
niz dodatnih transformacija koje se izvravaju na nivou meukoda ili na nivou
samog asemblerskog koda.

Ova optimizacija moe da ukljuuje i neke transformacije koje zahtevaju jako


sloene analize koda. Ovde e biti dat samo kratak osvrt na osnove tehnike koje
su danas ve postale standardne sa naglaskom na to da se na novim tehnikama
za optimizaciju jo uvek radi i da kompletno prouavanje ovih tehnika izlazi iz
okvira ovog predmeta.

Osnovne tehnike optimizacije bie ilustrovane na primeru programa kojim se


realizuje quicksort algoritam za ureivanje vektora dat u sledeem primeru.

Primer 13.1 C program quicksort algoritma


U nastavku je dat quicksort algoritam napisan u C-u.

void quicksort(int m, int n) {


int i, j;
int v, x;
if (n <= m) return;
/* Poetak dela koji optimizujemo */
i = m - 1; j = n; v = a[n];
while (j) {
do i = i +1 ; while (a[i] < v);
do j = j -1 ; while (a[j] > v);
if (i >= j) break;
x = a[i]; a[i] = a[j]; a[j] = x;
}
x = a[i]; a[i] = a[n]; a[n] = x;
/* Kraj dela koda koji nas interesuje */
quicksort(m, j); quicksort(i + 1, n);
}

Kompilator e na osnovu C koda iz prethodnog priemra generisati troadresni


meukod prikazan u nastavku.

Primer 13.2 Meukod quicksort programa


U nastavku je dat meukod quicksort programa iz primera 13.1.

(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

Prilikom realizacije optimizatora najpre se nastoji da se meukod programa


prikae u vidu grafa u kome su identikovani i izdvojeni delovi koda koji pred-
stavljaju neke celine. U meukodu iz primera 13.2 se moe identikovati est
razliitih blokova. Prvi se odnosi na naredbe za inicijalizaciju koje prethode pr-
voj petlji. Drugi i trei blok obuhvataju petlje koje se jasno izdvajaju. etvrti
blok je if naredba sama za sebe, dok su njena then i else grana peti i esti
blok.
262 GLAVA 13. OPTIMIZACIJA KODA

(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

(14) t6 := 4 i (23) t11 := 4 i


(15) x := a[t6 ] (24) x := a[t11 ]
(16) t7 := 4 i (25) t12 := 4 i
(17) t8 := 4 j (26) t13 := 4 n
(18) t9 := a[t8 ] (27) t14 := a[t13 ]
(19) a[t7 ] := t9 (28) a[t12 ] := t14
(20) t10 := 4 j (29) t15 := 4 n
(21) a[t10 ] := x (30) a[t15 ] := x
(22) goto B2

Slika 13.1: Graf toka za meukod iz primera 13.2


13.2. DODATNA OPTIMIZACIJA 263

13.2.1 Zajedniki podizrazi

Jedna od osnovnih transformacija koja se primenjuje kod optimizacije koda


svodi se na eliminisanje suvinih temporarnih promenljivih. Nastoji se da se
identikuju promenljive kojima se dodeljuje ista vrednost, i da se umesto uvo-
enja nove promenljive koristi stara. Ove transformacije se najpre izvravaju
na nivou blokova.

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 .

Posle ove transformacije, blok B5 dobija oblik prikazan na slici 13.2.

t6 := 4 i
x := a[t6 ]
t8 := 4 j
t9 := a[t8 ]
a[t6 ] := t9
a[t8 ] := x
goto B2

Slika 13.2: Blok B5 posle eliminacije zajednikih podizraza

Slinu transformaciju mogue je izvriti i u bloku B6 . Ovde se najpre uvodi


promenljiva t11 , dok se kasnije ista vrednost pamti i kao t12 . Isto vai i za t13
i t15 . Na svim mestima gde se koristi t12 moe da stoji t11 , a umesto t15 moe
da stoji t13 . Blok B6 posle ovih transformacija prikazan je na slici 13.3.

t11 := 4 i
x := a[t11 ]
t13 := 4 n
t14 := a[t13 ]
a[t11 ] := t14
a[t13 ] := x

Slika 13.3: Blok B6 posle eliminacije zajednikih podizraza


264 GLAVA 13. OPTIMIZACIJA KODA

13.2.2 Zajedniki podizrazi na globalnom nivou

Zajedniki podizrazi mogu da se pronalaze i na globalnom nivou tako to se


posmatraju zavisnosti izmeu blokova i vrednosti uvedene u jednom bloku ko-
riste u narednim. Na primer, u bloku B2 uvedena je promenljiva t2 := 4 i,
pri emu se ta vrednost zadrava po izlasku iz tog bloka. U bloku B5 uvodi se
t6 i dodeljuje mu se ista ta vrednost. Praktino, t6 nije potrebno i moe da se
eliminie, a svuda umesto t6 da se stavi t2 . Posle slinih eliminacija B5 i B6
dobijaju oblik prikazan na slici 13.4.

x := t3 x := t3
a[t2 ] := t5 t14 := a[t1 ]
a[t4 ] := x a[t2 ] := t14
goto B2 a[t1 ] := x

Slika 13.4: Blokovi B5 i B6 posle eliminacije zajednikih podizraza na globalnom nivou

13.2.3 Prostiranje naredbi za kopiranje

Ukoliko u generisanom kodu postoje naredbe oblika f := g (naredbe za kopi-


ranje), kojima se vrednost promenjlive g kopira u promenljivu f. Efekat ove
naredbe se moe postii tako to se svuda u kodu gde se pojavljuje f ubacuje
g. Prilikom optimizacije koda, prvo se izvrava ta transformacija, a nakon nje
je mogue izbaciti naredbu za kopiranje kao redundantnu.

Ovo je jedna od tipinih transformacja koja se koristi kod svih optimizatora


koda.

U primeru koji razmatramo postoji naredba za kopiranje x := t3 . Prostiranjem


ove naredbe blok B5 se transformie u oblik prikazan na slici 13.5.

x := t3
a[t2 ] := t5
a[t4 ] := t3
goto B2

Slika 13.5: Blok B5 posle prostiranja naredbe za kopiranje x := t3

Slinu transformaciju mogue je izvriti i u bloku B6 , u odnosu na naredbu za


kopiranje x := t3 (slika 13.6).
13.2. DODATNA OPTIMIZACIJA 265

x := t3
t14 := a[t1 ]
a[t2 ] := t14
a[t1 ] := t3

Slika 13.6: Blok B6 posle prostiranja naredbe za kopiranje x := t3

13.2.4 Eliminisanje neaktivnog koda


Neaktivne naredbe su naredbe koje se nikada nee izvriti ili nemaju nikakav
efekat na program. Takoe mogu da postoje i neaktivne (mrtve) promenljive
koje se nikada ne koriste u programu. Ovakve naredbe i promenljive esto
nastaju kao posledica prostiranja naredbi za kopiranje. U prethodnom primeru
to je bio sluaj sa naredbom x := t3 u blokovima B5 i B6 . Ove naredbe se
jednostavno mogu izbaciti. Blokovi B5 i B6 nakon ove transformacije prikazani
su na slici 13.7.

a[t2 ] := t5 t14 := a[t1 ]


a[t4 ] := t2 a[t2 ] := t14
goto B2 a[t1 ] := t3

Slika 13.7: Blokovi B5 i B6 posle eliminisanja neaktivnog koda

13.2.5 Optimizacija petlji


Optimizacija petlji zauzima vano mesto u optimizaciji programa ire posma-
trano, a primenjuje se i kod optimizacije koda na nivou kompilatora. Na primer,
vreme izvravanja programa moe se znaajno smanjiti ukoliko se smanji broj
naredbi unutar petlji ak i ako se pri tome povea broj naredbi van petlje . Opti-
mizacija petlji moe da obuhvati razliite transformacije od kojih neke zahtevaju
sloenu analizu koda radi utvrivanja zavisnosti izmeu podataka u razliitim
iteracijama petlje i sl. Kako ove analize nee biti predmet razmatranja u ovom
osvrtu na optimizaciju petlji, ovde emo se zadrati na nekim jednostavnijim
transformacijama koje ne trae sloene analize. Na primer, sledee tehnike se
mogu lako primeniti:

pomeranje koda (code motion ),

eliminisanje indukcionih promenljivih i

direktna redukcija.
266 GLAVA 13. OPTIMIZACIJA KODA

Pomeranje koda (code motion )


Transformacija se sastoji u tome da se iz petlje izbacuju izrazi ija se vrednost
ne menja u petlji (ne zavisi od broja prolaza kroz petlju). Ako se izraunavanje
takvih izraza prebaci u deo za inicijalizaciju petlje onda e se oni izraunavati
samo jednom umesto da se izraunavaju prilikom svakog prolaza kroz petlju.

Primer 13.3 Pomeranje koda


Zaglavlje while -petlje
while (i <= limit - 2)
transformie se u

t := limit - 2;
while (i <= t)

Eliminisanje indukcionih promenljivih

Indukcione promenljive su promenljive ija promena izaziva promenu drugih


promenljivih. Ove zavisnosti se mogu iskoristiti za direktnu redukciju koda i
mogu da imaju poseban efekat kada se primene u petljama, zato to se uproa-
vanjem jedne naredbe u petlji postie efekat kao da je transformisan veliki broj
naredbi.

Na primer, u bloku B3 imamo j := j 1, a zatim t4 := 4 j . U svakom


prolazu kroz petlju prethodna vrednost promenljive j se umanjuje za jedan, a
to onda utie na to da se vrednost promenljive t4 umanjuje za 4. To znai
da naredba t4 := 4 j moe da bude zamenjena naredbom t4 := t4 4, koja je
jednostavnija od prethodne; naredba j := j 1 moe da se izbaci, ali je potrebno
da se pre ulaza u petlju denie poetna vrednost promenljive t4 . Posle ovih
transformacija, blok B3 dobija oblik prikazan na slici 13.8.

t4 := 4 j

t4 := t4 4
t5 := a[t4 ]
if t5 > v goto B3

Slika 13.8: Blok B3 posle eliminisanja indukcionih promenljivih

Slina redukcija moe da se izvri i bloku B2 gde se javlja naredba i := i + 1, a


zatim t2 := 4 i. Ova naredba moe da bude zamenjena naredbom t2 := t2 + 4.
Blok B2 posle eliminisanja indukcionih promenljivih prikazan je na slici 13.9.
13.3. PITANJA 267

t2 := 4 i

t2 := t2 + 4
t3 := a[t2 ]
if t3 < v goto B2

Slika 13.9: Blok B2 posle eliminisanja indukcionih promenljivih

Uoimo takoe da se umesto uslova i j , moe koristiti uslov t2 t4 , nakon


ega se naredbe i := i + 1 u bloku B2 i naredba j := j 1 u bloku B3 mogu
sasvim izbaciti.

Direktna redukcija

Direktna redukcija se odnosi na transformacije kojima se sloenije (skuplje)


naredbe zamenjuju jednostavnijim (jeftinijim) naredbama. U naem primeru,
direktna redukcija je primenjena u sprezi sa eliminisanjem indukcionih promen-
ljivih. U okviru petlji u blokovima B2 i B3 , naredbe mnoenja t2 := 4 i i
t4 := 4 j zamenjene su jednostavnijim naredbama oduzimanja t4 := t4 4 i
sabiranja t2 := t2 + 4.

Nakon opisanih transformacija meukod programa iz naeg primera dobija oblik


prikazan na slici 13.10.

13.3 Pitanja
1. Objasniti razloge zbog kojih se vri osnovna optimizacija koda.

2. Objaniti kako se izvodi osnovna optimizacija koda.

3. Navesti osnovne transformacije koda koje su deo osnovne opimizacije.

4. ta je to mainski zavisna a ta mainski nezavisna optimizacija?

5. Objasniti tehniku eliminisanja redundantnih naredbi.

6. ta obuhvata optimizacija toka programa?

7. Koja algebarska uproenja mogu da se koriste u okviru osnovne optimi-


zacije?

8. ta se podrazumeva pod direktnom redukcijom.

9. ta je cilj dodatne optimizacije koda?

10. Objasniti tehniku otkrivanja zajednikih podnizova.


268 GLAVA 13. 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

(140 ) a[t2 ] := t5 (170 ) t14 := a[t1 ]


0
(15 ) a[t4 ] := t3 (180 ) a[t2 ] := t14
(160 ) goto B2 (190 ) a[t1 ] := t3

Slika 13.10: Graf toka za meukod iz primera 13.2 nakon optimizacije


13.3. PITANJA 269

11. Kako se koristi prostiranje naredbi za kopiranje naredbi u optimizaciji


koda.

12. Objasniti znaaj optimizacije petlji za optimizaciju koda i navesti osnovne


transformacije koje se pri tome koriste.
270 GLAVA 13. OPTIMIZACIJA KODA
Glava 14

Generisanje koda

Faza generisanja koda je praktino poslednja faza u procesu prevoenja jezika.


Obino se nadovezuje na generisanje meukoda i koristi informacije sauvane u
tabeli simbola (slika 14.1). Kod nekih kompilatora se nakon generisanja koda
vri njegova optimizacija mada se veliki deo optimizacije vri na nivou meu-
koda, o emu je bilo rei u prethodnom poglavlju.

Osnovni zadatak generatora koda je da generie ispravan kod pri emu je bitno
da taj kod bude i to je mogue ekasniji.

izvorni meukod meukod generator ciljni


analizator optimizator
kod koda kod

tabela
simbola

Slika 14.1: Pozicija generatora koda u procesu prevoenja

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.

Kada se generie mainski kod sa apsolutnim adresama, on se direktno smeta


u memorijske lokacije i neposredno posle toga izvrava. Ovo je pristup koji
se obino primenjuje kod manjih kompilatora koji se realizuju kao studentski
projekti.

U sluaju kada se generie kod sa relativnim adresama, delovi programa (kao


to su potprogrami) mogu da se prevode nezavisno, pa da se naknadno povezuju

271
272 GLAVA 14. GENERISANJE KODA

pomou linkera i ubacuju u memoriju pomou loader -a.


Kada generator koda generie asemblerski jezik, sam generator se lake realizuje
 koriste se simbolike naredbe asemblerskog jezika, kao i raspoloive makro-
naredbe, ali se tada na fazu generisanja koda nadovezuje faza asembliranja koda.
U ovom poglavlju baviemo se tim pristupom u realizaciji kompilatora.

Da bi se realizovao generator koda, potrebno je poznavati:

odredinu mainu na kojoj e se program izvravati, tj.

 ciljni jezik  skup instrukcija koje asemblerski jezik sadri i naini


adresiranja koji se koriste za pristup podacima,

 arhitekturu procesora  skup registara koje procestor sadri;

strategiju organizacije operativne memorije koja je programu dodeljena u


toku izvrenja;

algoritam za generisanje koda, tj. preslikavanje meukoda u ciljni asem-


blerski jezik.

14.1 Odredina maina  procesor Intel 8086


Proces generisanja jezika direktno zavisi od ciljnog jezika i nemogue je u optem
sluaju sagledati sve probleme koji mogu da nastanu. U ovom odeljku bie
opisana arhitektura i asembleski jezik procesora 8086 koji e se koristiti kao
odredina maina u opisu generatora.

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,

BX kao bazni registar,

CX kao brojaki registar,

DX kao registar podataka.

Za pristup podacima u procesorkom steku (o ijoj e ulozi biti rei u odeljku o


upravljanju memorijom) koriste se dva pokazivaka registra: SP (stack pointer )
i BP (base pointer ).
Za pristup elementima polja koriste se indeksni registri SI (source index ) i DI
(destination index ).
14.1. ODREDINA MAINA  PROCESOR INTEL 8086 273

Procesor sadri i broja naredbi IP (instruction pointer ), statusni registar kao


i 4 registra koji ukazuju na poetke odgovarajuih segmenata u operativnoj
memoriji:

CS (code segment ),
DS (data segment ),
SS (stack segment ) i

ES (extra segment ).

14.1.1 Osnovni skup instrukcija


U ovom odeljku bie prikazan samo deo instrukcija ovog asemblerskog jezika koje
e biti koriene pri generisanju koda. Sve instrukcije ovog jezika podeliemo u
sledee grupe:

instrukcija za prenos podataka (tabela 14.1),

aritmetike instrukcije (tabela 14.2),

instrukcije za rad sa procesorskim stekom (tabela 14.3) i

instrukcije za promenu toka izvrenja programa (tabela 14.4).

Tabela 14.1: Instrukcije za prenos podataka

Instrukcija Znaenje

Podatak sa adrese src se prenosi


MOV dst, src
na lokaciju dst : [dst ] [src ]

Tabela 14.2: Aritmetike instrukcije

Instrukcija Znaenje

ADD dst, src [dst ] [dst ] + [src ]


SUB dst, src [dst ] [dst ] [src ]
INC src [dst ] [dst ] + 1

DEC src [dst ] [dst ] 1

MUL src [DX : AX] [DX] [src ]


[AX] [DX : AX] / [src ]
DIV src [DX] [DX : AX] mod [src ]
274 GLAVA 14. GENERISANJE KODA

Tabela 14.3: Instrukcije za rad sa procesorskim stekom

Instrukcija Znaenje

PUSH src Stavlja na stek podatak src


Izbacuje podataka sa steka i upisuje ga na
POP dst
adresu dst

Tabela 14.4: Instrkcije za promenu toka izvrenja programa

Instrukcija Znaenje

Bezulsovni skok na naredbu sa zadatom adre-


JMP adr
som: [IP] [adr ]
Uslovni skok na naredbu sa zadatom adresom.
Uslov skoka c se obino vezuje za vrednost ne-
Jc adr kog ega u statusnom registru, pa se ova na-
redba uglavnom upotrebljava nakon naredbe
CMP: if c then [IP] [adr ]
Poziv potprograma iji se kod nalazi na zada-
toj adresi. U procesorski stek se upisuje tekui
CALL adr
sadraj brojaa naredbi, a u broja naredbi se
upisuje data adresa: PUSH IP, [IP] [adr ]
Povratak na pozivajui modul, adresa koja se
RET nalazi na vrhu procesorskog steka se upisuje u
broja naredbi: POP IP.

14.1.2 Naini adresiranja

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

Tabela 14.5: Pregled zastupljenih naina adresiranja

Nain
Format Primer Znaenje
adresiranja

Vrednost operanda je nave-


neposredno CONST 100
dena konstanta.

Vrednost operanda je sadr-


direktno NAME ili X ili aj memorijske lokacije ija
memorijsko [CONST] [0100] je adresa data simbolikim
imenom ili konstantom.

direktno Vrednost operanda je sadr-


REG AX
registarsko aj datog registra.

Vrednost operanda je u me-


indirektno morijskoj lokaciji ija se
[REG] [BX]
registarsko adresa nalazi u datom regi-
stru.

Bazni registar uva po-


etnu adresu nekog bloka,
a stvarna adresa operanda
bazno [REG+CONST] [BP + 4] se dobija tako to se na
sadraj datog baznog regi-
stra doda vrednost nave-
dene konstante.

Konstanta ili simboliko


ime predstavlja poetnu
adresu bloka, a u registru
NAME[REG]
X[SI] ili je zapamen pomeraj u od-
indeksno ili
25h[DI] nosu na tu poetnu adresu.
CONST[REG]
Adresa operanda se opet
dobija sabiranjem poetne
adrese i pomeraja.
276 GLAVA 14. GENERISANJE KODA

14.2 Upravljanje memorijom u toku izvrenja pro-


grama
Zadaci ove komponente kompilatora su sledei.

Organizacija memorije u toku izvrenja programa  to podrazumeva odre-


ivanje gde e se u memoriji smestiti kod programa, kako e se memorisati
podaci razliitih tipova, gde e se u memoriji smestiti podaci razliitih
klasa memorije...

Pristup podacima smetenim u razliitim zonama memorije,

Pristup podacima denisanim u nekom spoljanjem opsegu (npr. kod


ugnjedenih potprograma obezbeivanje pristupa podacima denisanim u
spoljanjim potprogramima),

Promena sadraja memorije prilikom poziva potprograma i povratka na


pozivajui modul, tj. prevod poziva potprograma i povratka na pozivajui
modul.

14.2.1 Organizacije memorije


Operativni sitem dodeljuje neki deo memorije programu pri pokretanju njegovog
izvrenja. Zavisno od toga da li se sadraj memorije dodeljen programu menja
u toku izvrenja programa ili ne, vii programski jezici se dele na:

statike (eng. static ),


dinamike (eng. dynamic ) i

polustatike (eng. semistatic ).


Kod statikih jezika se pre poetka izvrenja programa u memoriju uita komple-
tan kod programa i rezervie prostor za sve podatke koji se u programu koriste
i u toku izvrenja programa se organizacija memorije ne menja. U ovu grupu
jezika spadaju jezici Fortran 77, Cobol i dr. Koncept organizacije memorije koji
se koristi kod statikih jezika je poznat kao statika alokacija memorije.

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.

Koncept polustatikih jezika je neto izmeu statikih i dinamikih. Kod njih


se kd programa u toku izvrenja programa ne menja i postoje i takozvani
statiki podaci koji se nalaze u memoriji za sve vreme izvrenja programa, ali
postoje i takozvani dinamiki podaci za koje se rezervie prostor u toku izvrenja
14.2. UPRAVLJANJE MEMORIJOM U TOKU IZVRENJA PROGRAMA277

programa i koji se uklanjaju iz memorije kada se vie ne koriste. Kod ovakvih


jezika se memorija dodeljena programu deli na statiku zonu (u koju se smeta
kod programa i statiki podaci) i dinamiku zonu u koju se smetaju dinamiki
podaci. U ovu grupu jezika spadaju Pascal, C, C++...

Kod polustatikih jezika se i statika i dinamika zona dalje dele na po dva


segmenta. Jedan segment statike zone se koristi za smetaj koda programa, a
drugi za smetanje statikih podataka. Jedan deo dinamike zone memorije se
organizuje u vidu steka i slui za smetanje aktivacionih slogova potprograma (o
emu e biti rei kasnije) a drugi deo (heap ) se koristi za smetanje dinamikih
podataka (slika 14.2). Ovakav koncept organizacije memorije se naziva stek
alokacija memorije.

procesorski
stek

dinamiki
podaci

statiki podaci

kod programa

Slika 14.2: Organizacija memorije kod polustatikih jezika (stek alokacija)

Veliina generisanog koda je poznata u toku prevoenja programa, a takoe


moe da se izrauna i memorijski prostor potreban za smetaj statikih po-
dataka. Ove informacije kompilator moe da iskoristi i da za kod i podatke
odredi memorijske lokacije u koje e biti smeteni, tj. odredi njihove odreene
apsolutne ili relativne adrese.

Veliina steka i dinamikog dela memorije moe da se menja u toku izvravanja


programa. Zbog toga se memorija organizje tako da neiskorieni deo bude
izmeu ova dva dela (kao to je prikazano na slici 14.2) tako da u nekom trenutku
moe procesorski stek da zauzima vei deo dinamike zone memorije, a u drugom
dinamiki podaci.

14.2.2 Aktivacioni slogovi


Za svaki poziv potprograma kompilator obino generie jedan aktivacioni slog
u kome uva sve informacije potrebne tom pozivu potprograma. U optem slu-
278 GLAVA 14. GENERISANJE KODA

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

Slika 14.3: Struktura aktivacionog sloga

Namena polja u aktivacionom slogu je sledea:

1. Na poetku sloga smeta se vrednost koju potprogram vraa glavnom


programu. Ova vrednost se zbog ekasnosti moe da vraa i kroz neki od
registra procesora.

2. Polje namenjeno stvarnim parametrima se koristi od strane glavnog pro-


grama da prenese parametre potprogramu koji odgovaraju konkretnom
pozivu potprograma.

3. Opciono polje sa upravljakim linkovima se koristi da se obezbedi veza sa


aktivacionim slogom modula iz kojeg je pozvan potprogram.

4. Opciono polje sa linkovima za pristup podacima postoji kod jezika koji


dozvoljavaju da se koriste nelokalni podaci, podaci iz aktivacionih slogova
drugih potprograma.

5. Deo aktivacionog sloga namenjen uvanju statusa procesora slui da se u


njemu memoriu vrednosti registara pocesora koje su zateene u trenutku
poziva potprograma. Ovde se obino smeta vrednost brojaa neredbi i
registara procesora opte namene.

6. Polje namenjeno lokalnim podacima slui za smetaj podataka koji pripa-


daju samo potprogramu, denisani su u potprogramu.

7. Polje namenjeno privremenim podacima slui za memorisanje podataka


koje generie kompilator kao pomone lokacije u koje smeta meurezul-
tate.
14.3. STATIKA ALOKACIJA MEMORIJE 279

14.3 Statika alokacija memorije

Kod statikih jezika se u toku kompiliranja programa generie po jedan aktiva-


cioni slog za svaki potprogram tako da se isti aktivacioni slog koristi kod svakog
poziva potprograma. Ovaj aktivacioni slog se smeta u statiki deo memorije.
U ovom sluaju nema mogunosti za rekurzivne pozive potprograma zato to
bi svaki naredni poziv potprograma prebrisao sadraj aktivacionog sloga koji
odgovara prethodnom pozivu koji jo nije zavren.

Primer 14.1

Uzmimo kao primer kod programa CONSUME i potprograma PRODUCE, napi-


sanih u programskom jeziku FORTRAN.

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

CHACTER FUNCTION PRODUCE ( )


CHARACTER * 80 BUFFER
INTEGER NEXT
SAVE BUFFER, NEXT
DATA NEXT /81/
IF (NEXT .GT. 80 ) THEN
READ (*, '(A)') BUFFER
NEXT = 1
END IF
PRODUCE = BUFFER(NEXT:NEXT)
NEXT = NEXT + 1
END
Kako su veliina memorijskog prostora potrebnog za smetaj koda pro-
grama i potprograma, kao i aktivacionih slogova za ova dva modula poznati
u fazi kompiliranja programa raspodela memorije u ovom sluaju e biti
kao to je prikazano na slici 14.4.
280 GLAVA 14. GENERISANJE KODA

aktivacioni slog za PRODUCE


aktivacioni slog za CONSUME
kod funkcije PRODUCE
kod programa CONSUME

Slika 14.4: Statika alokacija memorije

14.4 Alokacija memorije pomou steka


Ako programski jezik dozvoljava rekurzivne pozive potprograma onda nije mo-
gue koristiti statiku alokaciju memorije. Naime u ovom sluaju u jednom
trenutku moe da postoji vie aktiviranih instanci potprograma i za svaki takav
poziv potreban je poseban aktivacioni slog.

Jedna od tehnika koju je u ovom sluaju mogue koristiti je alokacija memorije


pomou steka u okviru koje se prilikom svakog poziva potprograma kreira novi
aktivacioni slog i smeta na stek. Kada se izvravanje odreene instance potpro-
grama zavi odgovarajui aktivacioni slog se skida sa steka. U jednom trenutku
u steku moe da se nalazi vie instanci aktivacionog sloga jednog potprograma,
kao i vie razliitih aktivacionih slogova. U vreme kompiliranja programa zna se
samo veliina aktivacionog sloga ali ne i dubina rekurzije (koliko e aktivacionih
slogova jednog potprograma u nekom trenutku biti u steku).

Primer 14.2

Uzmimo kao primer rekurzivnu proceduru quicksort kojom se ureuje


vektor brojeva, iji je kod dat u nastavku.

void quiksort(int m, int n)


{
if (n > m)
{
i = partition(m,n);
quiksort(m, i - 1);
quiksort(i + 1, n);
}
}
int a[11];
void main ()
{
a[0] = -9999;
a[10] = 9999;
readarray();
14.5. DINAMIKA ALOKACIJA MEMORIJE 281

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.

Na slici 14.6 je prikazan redosled ubacivanja aktivacionih slogova u stek koji


odgovara prikazanom delu aktivacionog stabla za program iz primera 14.2.

14.5 Dinamika alokacija memorije


Kod dinamikih jezika se i kod i svi podaci (pa i aktivacioni slogovi) smetaju
u dinamiku memoriju (heap) i ne izbacuju se iz memorije odmah po zavretku
potprograma kao kod stek alokacije. Kod dinamikih jezika, postoji posebna
komponenta koja se povremeno aktivira i koja iz memorije brie sve podatke koji
se vie ne koriste (odnosno na koji se ne referencira ni jedna aktivna promenljiva
u kodu) i koja se popularno zove garbage collector. Na primer, u sluaju izvrenja
programa iz primera 14.2, u trenutku prvog poziva potprograma quicksort, u
memoriji bi bio sauvan i aktivacioni slog potprograma readarray sve dok se ne
aktivira garbage collector. Dakle, u heap -u bi se nali istovremeno i aktivacioni
slog potprograma ije je izvrenje ve zavreno i potprograma koji se trenutno
izvrava, kao to je to prikazano na slici 14.7.

14.5.1 Generisanje koda za poziv potprograma


U ovom poglavlju bie prikazan nain generisanja koda pri pozivu potprograma
i pri povratku iz potprograma za asemblerski jezik procesora Intel 8086. Reeno
je ve da ovaj procesor podrava alokaciju memorije pomou steka pa e u ovom
poglavlju biti pokazano prevoenje poziva potprograma kod polustatikih jezika
u ovaj asemblerski jezik.

Dakle, prilikom poziva potprograma se generie akrivacioni slog i smeta na


stek. Reeno je ve, da ovaj asemblerski jezik koristi bazni pokaziva za pristup
podacima u steku. Dakle taj bazni pokaziva uvek ukazuje na neku lokaciju
aktivacionog sloga poslednjeg pozvanog potprorama, tj. potprograma koji se
trenutno izvrava. Kad se izvrenje aktuelnog potprograma zavri, bazni po-
kaziva treba da se vrati da ukazuje na aktivacioni slog pozivajueg modula.
GLAVA 14. GENERISANJE KODA

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.

U trenutku poziva potprograma izvrava se skup instrukcija za generisanje ak-


tivacionog sloga i njegovo smetanje u stek. Ovaj skup instrukcija se naziva
sekvencom poziva.

U trenutku povratka iz potprograma izvrava se skup instrukcija za izbacivanje


aktivacionog sloga iz steka. Ovaj skup instrukcija se naziva sekvencom povratka.

rezultat programa
stvarni parametri
adresa povratka
staro BP
(kontrolna veza) BP

prethodni sadraj
radnih registara
lokalne promenljive
privremene promenljive SP

Slika 14.8: Aktivacioni slog koji se koristi u jeziku 8086


14.5. DINAMIKA ALOKACIJA MEMORIJE 285

14.5.2 Generisanje sekvence poziva


Iz strukture aktivacionog sloga se vidi da je izvestan skup podataka koji treba da
se upiu u aktivacioni slog poznat pozivajuem potprogramu, dok je drugi skup
podataka koji se nalazi u aktivacionom slogu poznat pozvanom modulu. Zato
e sekvenca poziva biti podeljena na dva dela: prvi deo je onaj koji treba da se
genrie u pozvivajuem modulu, a drugi deo se generie na poetak pozvanog
modula.

Deo sekvence poziva koji se generie u pozivajuem potprogramu.

1. Rezervacija prostora u steku za smetanje rezultata. Poto stek


raste od najviih memorijskih adresa, prema niim (slika 14.2), rezervacija
prostora se svodi na umanjenje vrednosti pokazivaa steka za veliinu me-
morijskog prostora potrebnog da se smesti povratna vrednost, odnosno,
rezervacija prostora za rezultat se vri sledeom naredbom.

SUB SP, size


Poto se u ovom asemblerskom jeziku adresiraju bajtovi, a celobrojni po-
daci zauzimaju jednu re, rezervacija prostora za rezultat celobrojnog tipa
bi bila sledea.

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.

3. Izvrenje CALL naredbe. CALL naredba automatski stavlja na stek tre-


nutni sadraj brojaa naredbi IP, odnosno adresu povratka.

Deo sekvence poziva koji se generie u pozivajuem potprogramu je sledei.

1. Smetanje u stek stare vrednosti baznog pokazivaa. Za ovu akciju


treba generisati naredbu:

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.

Stanje procesora pre poziva je denisano sadrajem registara opte namene


i indeksnih registara. Dakle, treba generisati skup instrukcija za njihovo
smetanje u stek:

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:

SUB SP, size

14.5.3 Generisanje sekvence povratka


Prilikom povratka u pozivajui modul, deo aktivacionog sloga koji je kreirao
pozvani modul, pozvani modul treba i da ukloni sa steka, a deo koji je kreirao
pozivajui modul, pozivajui modul treba i da ukloni. Dakle i sekvenca povratka
se opet deli na dva dela: onaj koji izvrava pozvani potprogram i onaj koji
izvrava pozivajui modul.

Kako se podaci sa steka skidaju u obrnutom redosledu u odnosno na ono kako


su smetani, bie najpre prikazana sekvenca instrukcija koja treba da bude ge-
nerisana u pozvanom potprogramu:

1. Upis rezultata u predvienu memorijsku lokaciju u steku.


2. Izbacivanje iz steka lokalnih promenljivih. Jednostavnim povea-
njem pokazivaa steka za veliinu memorijskog prostora potrebnog za
smetanje lokalnih podataka, taj deo memorijskog prostora je osloboen i
spreman za upis novih podataka. Znai, naredba koju treba generisati je:

ADD SP, size


14.5. DINAMIKA ALOKACIJA MEMORIJE 287

3. Preuzimanje iz steka starog stanja procesora. Za preuzimanje starih


vrednosti radnih registara treba generisati skup instrukcija:

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.

1. Izbacivanje iz steka stvarnih parametara. Kao i kod izacivanja lo-


kalnih promenljivih i ovde je dovoljno samo poveati vrednost pokazivaa
steka za vrednost koja predstavalja veliinu memorijskog prostora koji je
korien za smetanje stvarnih parametara. Generisana instrukcija bie:

ADD SP, size


2. Preuzimanje rezultata Instrukcija koju treba generisati je:
POP destination
destination je adresa na koju treba smestiti rezultat potprograma.

Primer 14.3

Pokazaemo kako e izgledati generisana sekvenca poziva i sekvenca po-


vratka za proceduru quicksort iz primera 14.2. Da bismo ispravno ge-
nerisali te sekvence, najpre treba denisati kako e izgledati aktivacioni
slog ove procedure. Zbog jednostavnosti reenja u aktivacionom slogu se
nee pamtiti staro stanje procesora. Aktivacioni slog procedure je dat na
sledeoj slici.
288 GLAVA 14. GENERISANJE KODA

n
m
adresa povratka
staro BP BP
SP i

Pretpostavimo da je procedura pozvana na sledei nain:

quicksort(1, 9);
U pozivajuem modulu, u taki poziva ove funkcije generisae se sledee
instrukcije.

; DEO SEKVENCE POZIVA U POZIVAJUEM MODULU


; potprogram je opteg tipa pa se ne rezervie prostor
; za rezultat

; smetanje stvarnih parametara na stek:


MOV AX, 9
PUSH AX
MOV AX, 1
PUSH AX

; prelaz na potprogram
CALL QUICKSORT

; DEO SEKVENCE POVRATKA U POZIVAJUEM MODULU


; izbacivanje stvarnih parametara iz steka
ADD SP, 4

; 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
;...

; DEO SEKVENCE POVRATKA U POZVANOM POTPROGRAMU


; izbacivanje lokalnih promenljivih iz steka
ADD SP, 2
14.5. DINAMIKA ALOKACIJA MEMORIJE 289

; preuzimanje stare vrednosti baznog pokazivaa


POP BP
; vraanje u pozivajui modul
RET

14.5.4 Smetanje promenljivih i pristup promenljivama u


razliitim delovima memorije
Kod veine polustatikuh programskih jezika promenljive se u memoriji sme-
taju na sledei nain:

globalne promenljive se smetaju u statikoj zoni memorije;

parametri programa i lokalne promenljive se smetaju u procesorskom


steku;

dinamike promenljive (promenljive za koje programer rezervie prostor


onda kada su mu potrebne) se smetaju u heap -u.
Programski jezik C, na primer, ima dodatnu mogunost da programer eksplicit-
nim denisanjem klase memorije za promenljve denie gde e ona biti smetena.
Lokalne promenljive u ovom programskom jeziku mogu imati klasu memorije:

static  takve promenljve se smetaju u statiku zonu memorije jer se


njihova vrednost denisana u jednom pozivu potprograma moe koristiti
prilikom narednog poziva;

auto  podrazumevana klasa memorije, takve promenljive se smetaju u


procesorski stek;

register  takve promenljive se smetaju u neki registar procesora (ako


ima slobodnih registara, ako ne, tretiraju se na isti nain kao i promenljive
sa klasom memorije auto).

Prevodilac je taj koji e predvideti memorijske lokacije za smetanje promenlji-


vih i pri pojavi odreene promenljive u kodu znati kako da im pristupi, odnostno
koje e adresiranje koristiti za pristup promenljivama. U sluaju asemblerskog
jezika 8086, pristup podacima se vri na sledei nain:

promenljivama smetenim u statikoj zoni memorije se pristupa korie-


njem direktnog memorijskog adresiranja,

promenljivama smetenim u procesorskom steku se pristupa korienjem


baznog adresiranja,

promenljivama smetenim u registrima se pristupa korienjem direktnog


registarskog adresiranja,

pristup promenljivama zapamenim u heap-u se obino pristupa u dva


koraka:
290 GLAVA 14. GENERISANJE KODA

 najpre se adresa podatka smesti u neki registar procesora (obino


BX, ali ne obavezno),

 zatim se indirektnim registarskim adresiranjem pristupa samom po-


datku.

Primer 14.4

Neka se u nekoj C funkciji nalazi sledei skup naredbi:

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.

Promenljiva i treba da bude smetana u nekom registru (neka je to


registar AI).
Promenljiva j je u delu za statike podatke ija je adresa odreena u
fazi prevoenja i zapamena u tabeli simbola. Neka je to adresa 100.
Promenljiva a je zapamena u steku (poto je to prva lokalna pro-
menljiva sa klasom meorije auto; njen pomeraj u odnosu na registar
BP je 2).
Pokazivaka promebljiva b je takoe u statikoj zoni memorije i neka
je ona zapisana na adresi 102.
U skladu sa navedenim nainom smetanja promenljivih, navedene naredbe
dodele e biti prevedene na sledei nain.

1. Naredbi i = j; odgovara kod

MOV AI, [0100]


pri emu je direktno registarsko adresiranje iskorieno za pristup za
pristup promenljivoj i, a direktno memorijsko adresiranje za pristup
promenljivoj j.
2. Naredbi a = *b; odgovara kod

MOV BX, [0102] ; direktno memijsko adresiranje za


; pristup pokazivau b
MOV AX, [BX] ; indirektno registarsko adresiranje
; za pristup neimenovanoj promenljivoj
; na koju ukazuje b
14.6. REALIZACIJA GENERATORA KODA 291

MOV [BP-02], AX ; bazno adresiranje za pristup


; promenljivoj a

14.6 Realizacija generatora koda


Pre nego deniemo sam generator koda, uveemo ogranienje da se rezultat
izvravanja neke operacije zadrava u registru sve dok je potreban. Iz registra
emo ga prebacivati u memorijsku lokaciju samo u sluaju kad je taj registar
potreban za neku drugu operaciju kao i neposredno pre poziva potprograma,
pre naredbe skoka kao i pre naredbe sa labelom.

14.6.1 Algoritam generisanja koda


Generator koda preuzima naredbe iz ulazne sekvence koja predstavlja troadre-
sni meukod. U okviru ovih sekvenci se obino identikuju delovi (blokovi)
koji sami za sebe predstavljaju celine, tako da se moe uitavati blok po blok.
Takoe, za svaki od raspoloivih registara koristimo deskriptor registra koji uka-
zuje na to vrednost koje promenljive je memorisana u registru. Takoe, za svaku
od promenljivih imamo deskriptor adrese koji ukazuje na to gde je memorisana
vrednost te promenljive.

Za svaku troadresnu naredbu oblika x := y op z izvravaju se sledei koraci.

1. Odreivanje lokacije L u kojoj e biti zapamen rezultat. U ove


svrhe koristi se funkcija getreg koja je data neposredno iza ovog algoritma.
Nastoji se da odredite bude neki od registara u procesoru, ali isto tako
to moe da bude i neka od memorijskih lokacija.

2. Odreivanje podatka nad kojim se izvrava operacija. Odreuje


se gde se nalazi podatak y nad kojim se izvrava operacija. On moe da
bude u memoriji ili u nekom od registara procesora. Ukoliko se nalazi na
oba mesta prednost se daje registrima. Ako podatak ve nije u L, generie
se naredba MOV L, y', kojom se podatak y prebacuje u lokaciju L (sa y 0
je oznaena adresa lokacije u kojoj se nalazi podatak y ).
3. Generisanje naredbe. Generie se naredba oblika OP L, z', gde je sa
z0 oznaena lokacija u kojoj se nalazi podatak simboliki oznaen sa z.
Deskriptor adrese za x se koriguje tako da pokazuje na lokaciju L. Ako
je L registar, treba korigovati njegov deskriptor tako da pokazuje da on
sadri podatak x, i izbrisati x iz sadraja svih drugih deskriptora registara.
4. Oslobaanje registara. Ako se podaci y i z ne koriste neposredno iza
razmatrane naredbe, nisu ivi po izlasku iz bloka onda, ako se nalaze u
registrima treba osloboditi registre i naznaiti da se posle bloka ti sadraji
ne koriste.
292 GLAVA 14. GENERISANJE KODA

14.6.2 Funkcija getreg


Funkciju getreg koristimo da odredimo lokaciju gde e biti smeten rezultat ge-
nerisane naredbe. Ako je cilj generisanje optimalnog koda, ovaj zadatak moe
da bude jako sloen. Ovde e biti razmatrano jedno jednostavno reenje koje
daje prednost registrima procesora u odnosu na memorijske lokacije ako ta mo-
gunost postoji.

1. Ako deskriptor nekog registra pokazuje da je y u tom registru i ako se y


vie ne koristi posle naredbe x := y op z, onda se taj registar vraa kao
L. Kako e posle izvrenja naredbe u ovom registu biti rezultat operacije,
a ne vie y treba korigovati deskriptor adrese za y da y vie nije u tom
registru.

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.

4. Ako se x ne koristi dalje u bloku ili ne moe da se nae odgovarajui prazan


registar onda se za L uzima memorijska lokacija u kojoj je zapamena
vrednost za x.

Primer 14.5

Razmotrimo kao primer naredbu dodeljivanja

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

Genarator koda opisan gore datom procedurom generisae sekvencu asem-


blerskih naredbi prikazanu u tabeli 14.6.
14.6. REALIZACIJA GENERATORA KODA 293

Tabela 14.6: Generisani kod za blok naredbi iz primera 14.5

Naredba Generisani Deskriptor Deskriptor


meukoda kod registra adrese

registri prazni a, b, c i d u memoriji

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

MOV d, AX registri prazni a, b, c i d u memoriji

14.6.3 Generisanje koda za neke specijalne naredbe


Sloenije naredbe troadresnog koda, kao to su naredbe u kojima se javljaju
indeksirane promenljive i pointeri, se transformiu u asemblerski kod na slian
nain kao i naredbe sa binarnim operatorom.

14.6.4 Generisanje koda za naredbe sa indeksnim promen-


ljivama
Kod koji se generie za sluaj naredbi dodeljivanja u kojima se javljaju promen-
ljive sa indeksima prikazan je u tabeli ??.
U tabeli 14.7 su razmatrani sluajevi naredbi a := b[i] i a[i] := b, a uzeta su
u obzir tri sluaja: kada je indeks zapamen u registru procesora, u memorijskoj
lokaciji ili se uva na steku.

14.6.5 Generisanje koda za naredbe sa pokazivaima


Kod koji se generie u sluaju naredbi u kojima se koriste pokazivai prikazan
je u tabeli 14.8. I ovde su uzeta u obzir dva oblika meunaredbi: a := *p i
*p := a. Takoe su razmatrane sluajevi kada se vrednost pokazivaa nalazi u
registru procesora, u memorijskoj lokaciji ili na steku.
294 GLAVA 14. GENERISANJE KODA

Tabela 14.7: Generisani kod za naredbe sa indeksima

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

Tabela 14.8: Generisani kod za naredbe sa pokazivaima

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

14.6.6 Generisanje koda za naredbe uslovnog skoka


Naredbe uslovnog skoka troadresnog koda oblika if x relop y goto z mogu
da budu transformisane u asemblerski, u principu, na dva naina.

Jedan nain je da se najpre x oduzme od y i da se rezultat zapamti u nekom


registru R, nakon ega se generie naredba skoka na z ako je vrednost registra
R negativna.

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:

CMP 'x, 'y


JNGE z
14.6. REALIZACIJA GENERATORA KODA 295

Najpre se poredi vrednost podataka x i y, nakon ega se postavljaju vrednosti


bitova kojima se registruje sadraj rezultata. Druga naredba je skok na labelu
z ako je u bitu kojim se registruje uslov < upisana vrednost 1.

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

Generisani asemblerski kod u tom sluaju bi bio:

; upis BP na stek:
PUSH BP

; promena vrednosti pokazivaca BP:


MOV BP, SP
296 GLAVA 14. GENERISANJE KODA

; rezervacija prostora za lokalnu promenljivu:


ADD SP, 2

; 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

; upis stvarnih parametara u stek:


lab3: MOV AX, [BP + 6]
PUSH AX
MOV BX, [BP + 4]
MOV AX, [BX + 2]
PUSH AX

; poziv funkcije:
CALL find

; izbacivanje stvarnih parametara iz steka:


ADD SP,4

; preuzimanje rezultata funkcije:


MOV [BP - 2], CX

; smestanje rezultata u CX:


lab2: MOV CX, [BP - 2]

; izbacivanje lokalnih promenljivih iz steka:


MOV SP, BP

; uzimanje stare vrednosti BP-a:


POP BP
RET
Aktivacioni slog funkcije find u sluaju kad se rezultat prenosi kroz listu
parametara prikazan je na sledeoj slici.
14.7. PITANJA 297

rezultat
x
l
adresa povratka
staro BP BP
SP RES

Izmene u generisanom kodu koje bi u tom sluaju trebalo uraditi su sledee:

1. Pre upisa stvarnih parametara u stek treba rezervisati prostor za


rezultat funkcije, dakle dodati instrukciju SUB SP, 2.
2. Naredbu za preuzimanje rezultata funkcije zameniti naredbama:

POP AX
MOV [BP - 2], AX
3. Naredbu za smetanje rezultata zameniti naredbama:

MOV AX, [BP - 2]


MOV [BP + 6], AX

14.7 Pitanja
1. ta su zadaci komponente za upravljanje memorijom.

2. Kako se vii programski jezici dele na osnovu toga kako je organizovana


memorija koja im se dodeljuje u toku izvrenja.

3. ta je to aktivacioni slog i kako izgleda njegov uobiajeni sadraj?.

4. Kako je organizovana memorija pri izvranju programa kod polustatikih


programskih jezika.

5. ta se podrazumeva pod sekvencom poziva, a ta pod sekvencom po-


vratka?

6. Objasniti skup instrukcija koje treba generisati pri prevoenju poziva pot-
programa.

7. Objasniti skup instrukcija koje treba generisati pri prevoenju povratka


iz potprograma.

8. Pokazati na primeru kako treba da izgledaju generisane instrukcije u asem-


blerskom jeziku 8086 za pristup podacima smetenim u razliitim zonama
memorije.
298 GLAVA 14. GENERISANJE KODA

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;
};

int sum( struct node* head )


{
int s=0;
if (head != 0)
s = head->info + sum(head->next);
return s;
}
2. Data je funkcija za nalaenje maksimuma u ureenom binarnom stablu:

struct node
{
int info;
struct node* left;
struct node* right;
};

int max(struct node* head)


{
int m;
if ( head->right == 0 )
m = head->info;
else
m = max(head->right);
return m;
}
(a) Denisati sadraj aktivacionog sloga funkcije max. Pretpostaviti da
se rezultat funkcije prenosi kroz listu parametara.

(b) Denisati 8086 asemblerski kod za datu funkciju.


Glava 15

Realizacija kompilatora

Iz svega to je u prethodnim poglavljima reeno moe se zakljuiti da je kompi-


lator sam po sebi jedan neto sloeniji program koji se moe napisati na nekom
viem programskom jeziku koji omoguava rad sa strukturama kakve su liste
stabla i slino. U sutini, najvei problem je bio da se napravi prvi kompilator
koji je morao da bude napisan na nekom asemblerskom ili mainskom jeziku.
Sve naredne generacije kompilatora su pisane na viim programskim jezicima, a
kako smo ve videli, danas se za realizaciju pojedinih modula koriste i generatori
koda.

U ovom poglavlju razmotriemo pristupe koji su korieni u realizaciji nekih ko-


mercijalnih reenja kompilatora za programske jezike koji imaju iroku primenu.

15.1 Tehnika butstrepovanja


Za razvoj novih verzija kompilatora za odreeni programski jezik se mogu kori-
stiti postojei (stari) kompilatori za isti programski jezik ili za novi programski
jezik, tako to se program novog kompilatora pie u jeziku za koji postoji kom-
pilator i prevodi u mainski kod pomou postojeeg kompilatora. Ova tehnika
u kojoj se postojei kompilatori koriste za razvoj novih poznata je pod ime-
nom butstrepovanje. Na primer, na slici 15.1 je pokazano kako se postojei C
kompilator moe iskoristiti za razvoj Java kompilatora.

U okviru ove tehnike za predstavljanje reenja kompilatora koriste se dijagrami u


kojima je svaki kompilator prikazan jednim T -blokom kao na slici 15.2. Na slici
sa S je obeleen izvorni jezik (source language ), T je ciljni jezik (target language ),
a I je jezik na kome je napisan kompilator (implementation language ).
T -dijagramom obuhvaene su tri komponente koje karakteroiu jedan kompi-
lator. Jednim blokom (S ) predstavljen je izvorni jezik, jezik sa kojeg se vri

299
300 GLAVA 15. REALIZACIJA KOMPILATORA

program kompilatora
kompilator za C kompilator za Javu
za Javu napisan na C-u
(EXE) (EXE)
(C kod)

aplikativni program kompilator za Javu izvrni fajl


(Java kod) (EXE) (EXE)

Slika 15.1: Razvoj novog kompilatora

S T

Slika 15.2: Kompilator predstavljen T -dijagramom.

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.

Primer 15.1 Kompilator za FORTRAN


Na slici 15.3, T -dijagramom je predstavljen kompilator za programski jezik
FORTRAN koji generie programe za mainu IBM360 i sam predstavlja iz-
vrni program koji moe da se koristi na istoj toj maini, odnosno preveden
je u mainski jezik raunara IBM360.

FORTRAN IBM360
(program) (EXE)

IBM360
(EXE)

Slika 15.3: Kompilator iz primera 15.1


15.1. TEHNIKA BUTSTREPOVANJA 301

15.1.1 Kompilator za novi programski jezik

Primenom tehnike butstrepovanja, postojei kompilatori se mogu iskoristiti za


realizaciju kompilatora za novi programski jezik. Na slici 15.1 predstavljeno je
kako se postojei kompilator za programski jezik C moe iskoristiti za realiza-
ciju kompilatora za programski jezik Java. Preko T -dijagrama ovaj proces je
predstavljen na slici 15.4. Raspolaemo kompilatorom za programski jezik C
na maini M (CM M), a cilj nam je da realizujemo kompilator za programski
jezik Java koji e se koristiti na istoj maini (JavaM M). Program novog kom-
pilatora piemo na programskom jeziku C i prevodimo ga pomou postojeeg
kompilatora u mainski kod.

Java M Java M
(program) (EXE) (program) (EXE)

C C M M
(program) (program) (EXE) (EXE)

M
(EXE)

Slika 15.4: Generisanje kompilatora za JavaM M

15.1.2 Prenoenje kompilatora sa jedne na drugu mainu

Tehnikom Butstrepovanja moe da se rei i zadatak generisanja kompilatora za


novu mainu. Raspolae se kompilatorom za neki programski jezik na jednoj
maini i zadatak je da se realizuje kompilator za isti taj jezik ali za novu mainu.
Na primer hoemo da kompilator za programski jezik C za mainu M (CM M)
iskoristimo za realizaciju kompilatora za C ali koji e moi da se primenjuje na
maini N (CN N). Za pisanje novog kompilatora koristimo programski jezik C.
Piemo program kompilatora koji za programe napisane na jeziku C generie
EXE fajl za novu mainu. Ovaj program prevodimo kroz postojei kompilator
pri emu se dobija kompilator (CM N) koji moe da se koristi za generisanje EXE
fajlova za novu mainu, ali to mora da se radi na staroj maini. Taj kompilator
je samo privremeno reenje. Program kompilatora koji je napisan na jeziku
C treba prevesti ovim privremenim kompilatorom kako bi se dobilo konano
reenje, kompilator koji moe da se koristi za prevoenje C programa na novoj
maini, slika 15.5.
302 GLAVA 15. REALIZACIJA KOMPILATORA

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)

Slika 15.5: Realizacija kompilatora CN N pomou kompilatora CM M

15.1.3 Optimizacija postojeeg kompilatora


Butstrepovanjem se reava i problem oprimizacije postojeih kompilatora. Kre-
nimo opet od kompilatora za jezik C na maini M (CM M). Cilj je da se opti-
mizuje ovaj kompilator tako da generie ekasniji kod i da sam (kao program)
bude ekasniji. U ovom sluaju, na jeziku ponovo piemo program kompila-
tora za programski jezik C ali sa ugraenim algoritmima za optimizaciju. Taj
program se prevodi pomou postojeeg kompilatora (CM M) pri emu se dobija
kompilator koji generie optimizovani EXE fajl programa koji se prevodi ali
sam nije optimizovan. Ovaj kompilator je samo privremeno reenje. Kada se
pomou ovog kompilatora prevede polazni C program dobija se konano ree-
nje, kompilator koji generie optimizovane EXE fajlove i sam je optimizovan
(CM-opt M-opt).

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.

15.1.4 Razvoj kompilatora za programski jezik Pascal


Prvi primer se odnosi na proces koji je primenjen kod generisanja kompilatora
za programski jezik Pascal 1981 kada je zadatak bio da se realizuje kompilator
za novu, neto izmenjenu verziju jezika Pascal kao i da se pri tome ugrade i neki
15.1. TEHNIKA BUTSTREPOVANJA 303

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)

Slika 15.6: Optimizacija kompilatora CM M

postupci za optimizaciju kompilatora koji su tada bili poznati. Za razvoj novog


kompilatora korien je kompilator za staru verziju Pascal-a koji je na maini
CDC 6000 napisan 1972. godine. U ovom sluaju butstrepovanje je izvreno u
nekoliko koraka.

1. Na starom Pascal-u napisan je program kompilatora NPSP 6000-opt koji


treba da prevodi sa novog Pascal-a i da generie optimizovan kod. Ovaj
program je proputen kroz postojei kompilator SP6000 6000. Dobijen je
kompilator NP6000 6000-opt za novi Pascal koji generie oprimizirani kod,
ali sam nije optimiziran (slika 15.7).

2. U sledeem koraku, cilj je bio da se optimizuje i sam kod dobijenog kom-


pilatora. Isti program kompilatora prekodiran je sa starog Pascal-a u novi
Pascal i proputen kroz dobijeni kompilator. Znai, napisan je kompila-
tor NPNP 6000-opt, proputen kroz kompilator NP6000 6000-opt i dobijen
NP6000-opt 6000-opt (slika 15.8).

Prethodna dva koraka objedinjeno su predstavljena na slici 15.9.

15.1.5 Razvoj kompilatora za programski jezik FORTRAN


Drugi sluaj koji emo razmotriti odnosi se na proces generisanja kompilatora
za programski jezik FORTRAN za mainu IBM 360 , kada je za razvoj kori-
en postojei kompilator za FORTRAN za mainu IBM 7094. Cilj je bio da se
304 GLAVA 15. REALIZACIJA KOMPILATORA

N-Pascal 6000 N-Pascal 6000


(program) (EXE-opt) (program) (EXE-opt)

S-Pascal S-Pascal 6000 6000


(program) (program) (EXE) (EXE)

6000
(EXE)

Slika 15.7: Generisanje kompilatora NP6000 6000-opt

N-Pascal 6000 N-Pascal 6000


(program) (EXE-opt) (program) (EXE-opt)

N-Pascal N-Pascal 6000 6000


(program) (program) (EXE-opt) (EXE)

6000
(EXE)

Slika 15.8: Generisanje kompilatora NP6000# 6000-opt

kompilator prenese na novu mainu i da se pri tome dobije bolje, optimizovano


reenje. Znai, raspolagalo se kompilatorom F7094 7094, a cilj je bio da se do-
bije kompilator F360# 360# (znak # i ovog puta oznaava optimizovanu verziju
kompilatora).

U prvoj fazi reavan je samo problem prenoenja kompilatora sa stare na novu


mainu kroz sledea dva koraka.

1. Koriena je maina IBM 7094. Na Fortranu je napisan kompilator FF 360


koji prevodi programe sa Fortrana u mainski kod maine IBM 360. Ovaj
program je proputen kroz postojei kompilator F7094 7094 na maini IBM

N-Pascal 6000 N-Pascal 6000


(program) (EXE-opt) (program) (EXE-opt)

N-Pascal 6000 N-Pascal N-Pascal 6000 6000


(program) (EXE-opt) (program) (program) (EXE-opt) (EXE)

S-Pascal S-Pascal 6000 6000


(program) (program) (EXE) (EXE)

6000
(EXE)

Slika 15.9: Objedinjeni koraci butstrepovanja sa slika 15.7 i 15.8


15.1. TEHNIKA BUTSTREPOVANJA 305

7094. Dobijen je kompilator F7094 360 koji moe na staroj maini IBM
7094 da generie programe za mainu IBM 360 (slika 15.10).

2. Koriena je maina IBM 7094. Napisani program kompilatora FF 360


proputen je kroz novodobijeni kompilator F7094 360. Dobijen je kompi-
lator F360 360 koji moe da se koristi na maini IBM 360 za grenerisanje
programa za istu tu mainu (slika 15.11).

Prethodnim koracima, koji su objedinjeno predstavljeni na slici 15.12, re-


en je problem prenosa kompilatora na novu mainu. U nastavku je rea-
van problem optimizacije kompilatora.

3. Koriena je maina IBM 360. Napisan je optimizovani kod kompilatora


FF 360# i proputen kroz kompilator F360 360, dobijen u prethodnoj fazi.
Kao rezultat je dobijen je kompilator F360 360# koji generie optimizovani
kod ali sam nije optimizovan (slika 15.13).

4. Koriena je maina IBM 360. Vrena je optimizacija samog kompila-


tora. Program kopilatora FF 360# proputen je kroz novodobijeni kom-
pilator F360 360# koji generie optimizovani kod. Dobijen je kompilator
F360# 360#, koji generie optimzovani kod i sam je optimizovan (slika 15.14).

FORTRAN IBM360 FORTRAN IBM360


(program) (EXE) (program) (EXE)

FORTRAN FORTRAN IBM7094 IBM7094


(program) (program) (EXE) (EXE)

IBM7094
(EXE)

Slika 15.10: Prva faza butstrepovanja

FORTRAN IBM360 FORTRAN IBM360


(program) (EXE) (program) (EXE)

FORTRAN FORTRAN IBM7094 IBM7094


(program) (program) (EXE) (EXE)

IBM7094
(EXE)

Slika 15.11: Druga faza butstrepovanja

Sva etri koraka butstrepovanja koje je izvreno u sluaju generisanja optimizo-


vanog kompilatora za FORTRAN za mainu IBM 360 prikazana su objedinjeno
306 GLAVA 15. REALIZACIJA KOMPILATORA

FORTRAN IBM360 FORTRAN IBM360


(program) (EXE) (program) (EXE)

FORTRAN IBM360 FORTRAN FORTRAN IBM360 IBM360


(program) (EXE) (program) (program) (EXE) (EXE)

FORTRAN FORTRAN IBM7094 IBM7094


(program) (program) (EXE) (EXE)

IBM7094
(EXE)

Slika 15.12: Objedinjene prve dve faze butstrepovanja sa slika 15.10 i 15.11

FORTRAN IBM360# FORTRAN IBM360#


(program) (EXE) (program) (EXE)

FORTRAN FORTRAN IBM360 IBM360


(program) (program) (EXE) (EXE)

IBM360
(EXE)

Slika 15.13: Trei korak butstrepovanja

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.

FORTRAN IBM360# FORTRAN IBM360#


(program) (EXE) (program) (EXE)

FORTRAN FORTRAN IBM360# IBM360#


(program) (program) (EXE) (EXE)

IBM360
(EXE)

Slika 15.14: etvrti korak butstrepovanja


FORTRAN IBM360# FORTRAN IBM360#
(program) (EXE) (program) (EXE)

FORTRAN IBM360# FORTRAN FORTRAN IBM360# IBM360#


(program) (EXE) (program) (program) (EXE) (EXE)

FORTRAN IBM360 FORTRAN FORTRAN IBM360 IBM360


(program) (EXE) (program) (program) (EXE) (EXE)

FORTRAN IBM360 FORTRAN FORTRAN IBM360 IBM360


15.1. TEHNIKA BUTSTREPOVANJA

(program) (EXE) (program) (program) (EXE) (EXE)

FORTRAN FORTRAN IBM7094 IBM7094


(program) (program) (EXE) (EXE)

IBM7094
(EXE)

Slika 15.15: Sve faze butstrepovanja primenjenog kod generisanja kompilatora za FORTRAN
307
308 GLAVA 15. REALIZACIJA KOMPILATORA

15.2 Struktura kompilatora


Kod praktinih reenja kompilator se obino realizuje kao vieprolazni sitem u
kome se jedna na drugu nadovezuje vie faza kompilatora. Kako e biti organi-
zovane faze kompilatora i ta e one obuhvatati zavisi od mnogih faktora. Ovde
emo dati strukturu nekih poznatih praktinih reenja kompilatora.

Na slici ?? prikazana je struktura kompilatora za programski jezik Pascal koji je


1971. godine realizovao prof. Wirt sa svojim saradnicima. Poznata je u litersturi
kao P verzija kompilatora za Pascal zato to je tada prvi put upotrebljen poseban
P meukod.

izvorni kod

vii programski jezik Pascal

leksiki analizator

sekvenca tokena

LL analizator
type checker

meukod

generator koda

mainski kod

CPU

rezultati
Slika 15.16: P kompilator za Pascal

15.2.1 C kompilator za mainu PDP 11


Na slici 15.17 prikazan je kompilator za programski jezik C , za mainu PDP
11.

15.2.2 FORTRAN H kompilator


Na slici 15.18 prikazan je kompilator za programski jezik FORTRAN poznat u
literaturi kao FORTRAN H kompilator.
15.3. PITANJA 309

izvorni kod

vii programki jezik C

leksiki i sintaksni analizator


generator meukoda

postksna notacija

generator koda

asemblerski kod

post-optimizacija

asemblerski kod

Slika 15.17: Kompilator za programki jezik C za mainu PDP 11

15.3 Pitanja
1. ta su to T-dijagrami i u koje svrhe se koriste?

2. Objasniti tehniku butstrepovanja.

3. Prikazati kako se tehnikom butstrepovanja postojei kompilator moe is-


koristiti za realizaciju kompilatora za novi programski jezik. Prikazati taj
proces preko T-dijagrama.

4. Pokazati kako se tehnikom butstrepovanja postojei kompilator moe isko-


ristiti za realizaciju naprednije (optimizovane) verzije kompilatora za isti
programski jezik. Prikazati taj proces preko T-dijagrama.

5. Pokazati kako se tehnikom butstrepovanja postojei kompilator moe isko-


ristiti za prenoenje kompilatora na novu platformu (realizaciju kompila-
tora za isti progrsamski jezik ali za novu platformu). Prikazati taj proces
preko T-dijagrama.

6. Opisati kako je tehnika butstrepovanja iskoriena u procesu realizacije


kompilatora za programski jezik Pascal kada su u staru verziju jezika unete
i neke izmene. Prikazati taj proces jednim T-dijagramom.

7. Opisati kako je tehnika butstrepovanja iskoriena u procesu realizacije


kompilatora za programski jezik Fortran za platformu IBM 360, kada je
ujedno izvrena i optimizacija tog kompilatora. Prikazati taj proces jed-
nim T-dijagramom.
310 GLAVA 15. REALIZACIJA KOMPILATORA

izvorni kod

programki jezik FORTRAN

leksiki analizator

operator-operand parovi

sintaksni analizator

meukod (quadruples )

optimizacija

modikovan meukod

generator koda

asemblerski kod

Slika 15.18: FORTRAN H kompilator


Bibliograja

[1] Aho. A.V, Sethi, R., Ullman, J. D., Compilers, Principles, Techniques, and
Tool, Addison-Wesley, 1986.

[2] Appel, A. W., Modern Compiler Implementation in Java, Canbridge Uni-


versity Press, 1998.

[3] Appel, A. W.,Modern Compiler Implementation in ML, Cambridge Univer-


sity Press, 1998.

[4] Appel, A. W., Modern Compiler Implementation in C , Cambridge Univer-


sity Press, 1998.

[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.

Optimizing Compilers dor Modern Architectu-


[7] Kennedy K. , K, Allen J. R.,
res: A Dependence Based Approach, Morgan Kaufmann Publishers Inc. San
Francisko, 2002, ISBN:1-55860-286-0

[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

[10] Mozgovoy M., Algorithms, Languages, Automata, and Compilers: A Prac-


tical Approach, Jones and Bartlett Publishers, 2010.

[11] Muchnick, S. S., Advanced Compiler Design Implementation, Academic


Press 1997.

[12] Ronald Mak, Writing Compilers and Interpreters: A Software Engineering


Approach, John Wiley & Sons, 2011.

[13] Safonov, V. O., Trustworthy Compilers, John Wiley & Sons, 2010.

311
312 BIBLIOGRAFIJA

[14] Stankovi, M., Stojkovi, S.,Vukovi, V., Programski prevodioci  prakti-


kum za laboratorijske vebe, Univerzitet u Niu, 1997.

[15] Su Y., Yan. S, Principles of Compilers: A New Approach to Compilers


Including the Algebraic Method, Springer Science & Business Media, 2011.
[16] Tremblay, J. P. The theory and Practice of Compiler Writing, McGrow-Hill
computer science series, New York, 1985.
Glava 16

Dodatak

16.1 Java bajtkod


U ovom delu bie data tabela Java bajtkoda. U prvoj koloni data je simbolika
oznaka koda operacije, u drugoj kod operacije u heksadecimalnom kodu, a u tre-
oj koloni su opisani dodatni bajtovi. Peta kolona daje promenu sadraja steka
pod dejstvom navedene naredbe, dok je u estoj dat tekstualni opis naredbe.

313
314 GLAVA 16. DODATAK

Oznaka hex drugi baj- Stek: Opis


kod tovi [pre][posle]
A

aaload 32 arrayref, index U stek se uitava referenca na


value polje.

aastore 53 arrayref, index, Pamti se referenca u polje.


value
aconst_null 01 null U stek se ubacuje null refe-
renca.

aload 19 index objectref U stek se ubacuje referenca iz


lokalne promenljive #index.
aload_0 2a objectref U stek se ubacuje referenca iz
lokalne promenljive 0.

aload_1 2b objectref U stek se ubacuje referenca iz


lokalne promenljive 1.

aload_2 2c objectref U stek se ubacuje referenca iz


lokalne promenljive 2.

aload_3 2d objectref U stek se ubacuje referenca iz


lokalne promenljive 3.

anewarray bd indexbyte1, count arrayref Kreira se novo polje promen-


indexbyte2 ljivih duine count i tip kom-
ponenti odreen klasom refe-
rence index(indexbyte1 <<
8 + indexbyte2).
areturn b0 objectref Vraa se referenca metoda.
[empty]

arraylength be arrayref length Daje duinu polja.

astore 3a index objectref Pamti se referenca u lokalnu


promenljivu #index.
astore_0 4b objectref Pamti se referenca u lokalnu
promenljivu 0.

astore_1 4c objectref Pamti se referenca u lokalnu


promenljivu 1.

astore_2 4d objectref Pamti se referenca u lokalnu


promenljivu 2.

astore_3 4e objectref Pamti se referenca u lokalnu


promenljivu 3.

athrow bf objectref Aktivira se greka ili izuze-


[empty],objectref tak (ostatak steka se brie pri
emu se ostavlja samo refe-
renca na Throwable)

baload 33 arrayref, index Uitava se bajt ili Boolova


value vrednost iz polja.

bipush 10 byte value Ubacuje se bajt u stek kao in-


16.1. JAVA BAJTKOD 315

caload 34 arrayref, index Uitava se znak iz


value

castore 55 arrayref, index, Pamti se znak u polje.


value
checkcast c0 indexbyte1, objectref objec- Proverava da li je objec-
indexbyte2 tref tref odreenog tipa, ija
je referenca klase konstanta
index(indexbyte1 << 8 +
indexbyte2).
D

d2f 90 value result Konvertuje se double u oat.

d2i 8e value result Konvertuje se double u int.

d2l 8f value result Konvertuje se double u long

dadd 63 value1, value2 Sabiraju se dva double po-


result datka.

daload 31 arrayref, index Uitava se double iz polja.


value

dastore 52 arrayref, index, Pamti se double u polje.


value
dcmpg 98 value1, value2 Porede se dve double vredno-
result sti.

dcmpl 97 value1, value2 Porede se dve double vredno-


result sti.

dconst_0 0e 0.0 U stek se ubacuje konstanta


0.0.

dconst_1 0f 1.0 U stek se ubacuje konstanta


1.0.

ddiv 6f value1, value2 Dele se dva double podatka.


result

dload 18 index value Uitava se double value iz lo-


kalne promenljive #index.
dload_0 26 value Uitava se double value iz lo-
kalne promenljive 0.

dload_1 27 value Uitava se double value iz lo-


kalne promenljive 1.

dload_2 28 value Uitava se double value iz lo-


kalne promenljive 2.

dload_3 29 value Uitava se double value iz lo-


kalne promenljive 3.

dmul 6b value1, value2 Mnoe se dva double po-


result datka.

dneg 77 value result Negira se double vrednost.

drem 73 value1, value2 Preuzima se ostatak deljenja


316 GLAVA 16. DODATAK

dstore_2 49 value Pamti se double vrdnost


value u lokalnu promenljivu
2.

dstore_3 4a value Pamti se double vrdnost


value u lokalnu promenljivu
3.

dsub 67 value1, value2 Oduzima se jedan double po-


result datak od drugog.

dup 59 value value, va- Duplira se vrednost u vrhu


lue steka.

dup_x1 5a value2, value1 U vrh steka se ubacuju kopije


value1, value2, va- prve dve vrednosti sa vrha
lue1 steka.

dup_x2 5b value3, value2, va- U vrh steka ubacuju se kopije


lue1 value1, va- dve vrednosti iz steka (ako je
lue3, value2, va- value2 double ili long ubacuje
lue1 se i value3) ( ili se ubacuju
tri vrednosti sa vrha (ako je
value2 nije double ni long).

dup2 5c value2, value1 Dupliraju se prve dve rei u


value2, value1, va- vrhu steka (dve vrednosti ako
lue2, value1 value1 nije double ni long; a
jedna vrednost ako je value1
double ili long).

dup2_x1 5d value3, value2, Dupliraju se dve rei u vrha


value1 value2, steka i ispod njih ubacuje
value1,value3, trea.
value2, value1

dup2_x2 5e value4, value3, va- Dupliraju se dve rei u vrhu


lue2, value1 va- steka i ispod njih ubacuje e-
lue2, value1, va- tvrta re.
lue4, value3, va-
lue2, value1

f2d 8d value result Konvertuje se oat u double.

f2i 8b value result Konvertuje se oat u int.


16.1. JAVA BAJTKOD 317

f2l 8c value result Konvertuje se oat u long.

fadd 62 value1, value2 Sabiraju se dva oat podatka.


result

faload 30 arrayref, index Uitava se oat iz polja.


value

fastore 51 arreyref, index, Pamti se oat u polje.


value
fcmpg 96 value1, value2 Porede se dva oat podatka.
result

fcmpl 95 value1, value2 Porede se dva oat podatka.


result

fconst_0 0b 0.0f Ubacuje se 0.0f u stek.

fconst_1 0c 1.0f Ubacuje se 1.0f u stek.

fconst_2 0d 2.0f Ubacuje se 2.0f u stek.

fdiv 6e value1, value2 Dele se dva oat podatka.


result

oad 17 index value Uitava se oat vrednost


value iz lokalne promenljive
#index.
oad_0 22 value Uitava se oat vrednost
value iz lokalne promenljive
0.

oad_1 23 value Uitava se oat vrednost


value iz lokalne promenljive
1.

oad_2 24 value Uitava se oat vrednost


value iz lokalne promenljive
2.

oad_3 25 value Uitava se oat vrednost


value iz lokalne promenljive
3.

fmul 6a value1, value2 Mnoe se dva oat podatka.


result

fneg 76 value result Negira se oat vrednost.

frem 72 value1, value2 Preuzima se vrednost ostatka


result deljenja dva oat podatka.

freturn ae value [empty] Vraa se oat iz metoda.

fstore 38 index value Pamti se oat vrednost


value u lokalnu promenljivu
#index.
fstore_0 43 value Pamti se oat vrednost value
u lokalnu promenljivu 0.

fstore_1 44 value Pamti se oat vrednost value


u lokalnu promenljivu 1.
318 GLAVA 16. DODATAK

fstore_2 45 value Pamti se oat vrednost value


u lokalnu promenljivu 2.

fstore_3 46 value Pamti se oat vrednost value


u lokalnu promenljivu 3.

fsub 66 value1, value2 Oduzimaju se dva oat po-


result datka.

geteld b4 index1,index2 objectref value Preuzima se element value


objekta objectref gde je
element odreen referen-
com u index(index1 <<
8 + index2).
getstatic b2 index1,index2 value Dobija se statiki podatak
value iz klase, gde je po-
datak identikovan referen-
com index(index1 << 8 +
index2).
goto a7 branchbyte1, [no change] Ide se na drugu instrukciju
branchbyte2 na branchoset (ozna-
enu sa short konstru-
isano od neoznaenih
bajtova branchbyte1 <<
8 + branchbyte2)
goto_w c8 branchbyte1, [no change] Ide se na drugu instrukciju
branchbyte2, na branchoset (ozna-
branchbyte3, enu sa short konstru-
branchbyte4 isano od neoznaenih
bajtova branchbyte1 <<
24 + branchbyte2 <<
16 + branchbyte3 <<
8 + branchbyte4)
I

i2b 91 value result Konvertuje se int u byte.

i2c 92 value result Konvertuje se int u character.

i2d 87 value result Konvertuje se int u double.

i2f 86 value result Konvertuje se int u oat.

i2l 85 value result Konvertuje se int u long.

i2s 93 value result Konvertuje se int u short.

iadd 60 value1, value2 Sabiraju se dva int podatka.


result

iaload 2e arrayref, index Uitava se int iz polja.


value

iand 7e value1, value2 Izvrava se logiko and dva


result int podatka.
16.1. JAVA BAJTKOD 319

iastore 4f arrayref, index, Pamti se int u array


value
iconst_m1 02 -1 Uitava se int vrednost -1 u
stek.

iconst_0 03 0 Uitava se int vrednost 0 u


stek.

iconst_1 04 1 Uitava se int vrednost 1 u


stek.

iconst_2 05 2 Uitava se int vrednost 2 u


stek.

iconst_3 06 3 Uitava se int vrednost 3 u


stek.

iconst_4 07 4 Uitava se int vrednost 4 u


stek.

iconst_5 08 5 Uitava se int vrednost 5 u


stek.

idiv 6c value1, value2 Dele se dva int podatka.


result

if_acmpeq a5 branchbyte1, value1, value2 Ako su reference jednake


branchbyte2 skae se na naredbu na
branchof f set.
if_acmpne a6 branchbyte1, value1, value2 Ako reference nisu jednake
branchbyte2 skae se na naredbu na
branchof f set.
if_icmpeq 9f branchbyte1, value1, value2 Ako su dva int podatka jed-
branchbyte2 naka skae se na instrukciju
na branchof f set.
if_icmpne a0 branchbyte1, value1, value2 Ako dva int podatka nisu jed-
branchbyte2 naka skae se na instrukciju
na branchof f set.
if_icmplt a1 branchbyte1, value1, value2 Ako je vrednost value1 manja
branchbyte2 od vrednosti value2, skok na
instrukciju na branchof f set.

if_icmpge a2 branchbyte1, value1, value2 Ako je vrednost value1 vea


branchbyte2 ili jednaka od vrednosti
value2, skok na instrukciju
na branchof f set.

if_icmpgt a3 branchbyte1, value1, value2 Ako je vrednost value1 vea


branchbyte2 od vrednosti value2, skok na
instrukciju na branchof f set.

if_icmple a4 branchbyte1, value1, value2 Ako je vrednost value1 ma-


branchbyte2 nja ili jednaka od vrednosti
value2, skok na instrukciju na
branchof f set.
ifeq 99 branchbyte1, value Ako je vrednost value jed-
branchbyte2 naka 0, skok na instrukciju na
branchof f set.
320 GLAVA 16. DODATAK

ifge 9c branchbyte1, value Ako je vrednost value vea ili


branchbyte2 jednaka od 0, skok na instruk-
ciju na branchof f set.
ifgt 9d branchbyte1, value Ako je vrednost value vea
branchbyte2 od 0, skok na instrukciju na
branchof f set.
ie 9e branchbyte1, value Ako je vrednost value manja
branchbyte2 ili jednaka 0, skok na instruk-
ciju na branchof f set.
ifnonnull c7 branchbyte1, value Ako je vrednost value nije
branchbyte2 null, skok na instrukciju na
branchof f set.
ifnull c6 branchbyte1, value Ako je vrednost value null,
branchbyte2 skok na instrukciju na
branchof f set.
iinc 84 index, const [No change] Inkrementira se lokalna pro-
menjljiva #index za vred-
nost datu oznaenim bajtom
const.
iload 15 index value Uitava se int vrednosti value
iz promenljive #index.
iload_0 1a value Uitava se int vrednosti value
iz promenljive 0.

iload_1 1b value Uitava se int vrednosti value


iz promenljive 1.

iload_2 1c value Uitava se int vrednosti value


iz promenljive 2.

iload_3 1d value Uitava se int vrednosti value


iz promenljive 3.

imul 68 value1, value2 Mnoe se dva integer po-


result datka.

ineg 74 value result Negira se int podatak.

instanceof c1 indexbyte1, objectref result Odreuje se da li je obje-


indexbyte2 kat objectref datog tipa koji
je identikovan referencom na
klasu index(indexbyte1 <<
8 + indexbyte2).
invoke- b9 indexbyte1, objectref, [arg1, Poziva se metod interfejsa
interface indexbyte2, arg2, ...] za objekat objectref , gde
count, 0 je metod interfejsa identi-
kovan referencom na metod
index(indexbyte1 << 8 +
indexbyte2) i count je broj ar-
gumenata koji se izbacuju iz
steka ukljuujui i objekat za
koji je pozvan metod i mora
uvek da bude vei ili jednak
od 1.
16.1. JAVA BAJTKOD 321

invokespecialb7 indexbyte1, objectref, [arg1, Poziva se metod istance za


indexbyte2 arg2, ...] objekat objectref koji za-
hteva posebno upravljanje
(metod za inicijalizaciju is-
tance, privatni metod, ili me-
tod superklase), gde se me-
tod identikuje referencom
index(indexbyte1 << 8 +
indexbyte2).
invoke- b8 indexbyte1, [arg1, arg2, ...] Poziva se statiki metod za
static indexbyte2 objekat objectref , gde je me-
tod identikovan referencom
index(indexbyte1 << 8 +
indexbyte2).
invoke- b6 indexbyte1, objectref, [arg1, Poziva se viruelni metod za
virtual indexbyte2 arg2, ...] objekat objectref , gde je me-
tod identikovan referencom
index(indexbyte1 << 8 +
indexbyte2).
ior 80 value1, value2 Logika or operacija dva int
result podatka.

irem 70 value1, value2 Logiki int ostatak.


result

ireturn ac value [empty] Vraa integer iz metoda.

ishl 78 value1, value2 Pomeraj ulevo int podatka.


result

ishr 7a value1, value2 Pomeraj udesno int podatka.


result

istore 36 index value Pamti se int vrednost value u


promenljivoj #index.
istore_0 3b value Pamti se int vrednost value u
promenljivoj 0.

istore_1 3c value Pamti se int vrednost value u


promenljivoj 1.

istore_2 3d value Pamti se int vrednost value u


promenljivoj 2.

istore_3 3e value Pamti se int vrednost value u


promenljivoj 3.

isub 64 value1, value2 Oduzimanje int podataka.


result

iushr 7c value1, value2 Pomeraj udesno int podatka.


result

ixor 82 value1, value2 Xor operacija int podataka.


result
322 GLAVA 16. DODATAK

jsr a8 branchbyte1, address Skok na potprogram na


branchbyte2 branchof f set i postavljanje
adrese povratka na stek.

jsr_w c9 branchbyte1, address Skok na potprogram na


branchbyte2, branchof f set i postavljanje
branchbyte3, adrese povratka na stek.
branchbyte4

l2d 8a value result Konvertuje se long u double.

l2f 89 value result Konvertuje se long u oat.

l2i 88 value result Konvertuje se long u int.

ladd 61 value1, value2 Sabiraju se dva long podatka.


result

laload 2f arrayref, index Uitava se long iz polja.


value

land 7f value1, value2 Logiko and dva long podatka


result (bit po bit).

lastore 50 arrayref, index, Pamti se long u polje.


value
lcmp 94 value1, value2 Porede se dve long vrednosti.
result

lconst_0 09 0L Ubacuje se long 0 u stek.

lconst_1 0a 1L Ubacuje se long 1 u stek .

ldc 12 index value Ubacuje se konstanta #index


u stek (string, int, oat ili
class tipa).

ldc_w 13 indexbyte1, value Ubacuje se konstanta #index


indexbyte2 (tipa string, int, oat ili class)
u stek (iri index se for-
mira kao indexbyte1 << 8 +
indexbyte2).
ldc2_w 14 indexbyte1, value Ubacuje se konstanta #index
indexbyte2 (tipa double ili long) u
stek (iri index se formira
kao indexbyte1 << 8 +
indexbyte2).
ldiv 6d value1, value2 Dele se dve long vrednosti.
result

lload 16 index value Uitava se long vrednost iz lo-


kalne promenljive #index.
lload_0 1e value Uitava se long vrednost iz lo-
kalne promenljive 0.

lload_1 1f value Uitava se long vrednost iz lo-


kalne promenljive 1.
16.1. JAVA BAJTKOD 323

lload_3 21 value Uitava se long vrednost iz lo-


kalne promenljive 3.

lmul 69 value1, value2 Mnoe se dva long podatka.


result

lneg 75 value result Negira se long podatak.

lookup- ab < 0 3 bytes key Ciljna adresa se korienjem


switch padding>, kljua preuzima iz tabele I iz-
default- vravanje se nastavlja sa in-
byte1, de- strukcijom na toj adresi.
faultbyte2,
default-
byte3, de-
faultbyte4,
npairs1,
npairs2, npa-
irs3, npairs4,
match-oset
pairs...

lor 81 value1, value2 Pokomponentna or operacija


result dva long podatka.

lrem 71 value1, value2 Ostatak deljenja dva long po-


result datka.

lreturn ad value [empty] Vraa se long vrednost.

lshl 79 value1, value2 Pokomponentno pomeranje


result ulevo long vrednosti value1
za value2 pozicija.

lshr 7b value1, value2 Pokomponentno pomeranje


result udesno long vrednosti value1
za value2 pozicija.

lstore 37 index value Pamti se long vrednost


value u lokalnu promenljivu
#index.
lstore_0 3f value Pamti se long vrednost value
u lokalnu promenljivu 0.

lstore_1 40 value Pamti se long vrednost value


u lokalnu promenljivu 1.

lstore_2 41 value Pamti se long vrednost value


u lokalnu promenljivu 2.

lstore_3 42 value Pamti se long vrednost value


u lokalnu promenljivu 3.

lsub 65 value1, value2 Oduzimanje dva long po-


result datka.

lushr 7d value1, value2 Pokomponentno pomeranje


result udesno long vrednosti value1
za value2 pozicija.

lxor 83 value1, value2 Pokomponento xor dva long


result podatka.
324 GLAVA 16. DODATAK

monitor- c2 objectref Ulaz u monitor za obje-


enter kat ( poetak sekcije
synchronized() ).

monitor- c3 objectref Izlaz iz monitora za objekat


exit kraj sekcije synchronized() )
.


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.

new bb indexbyte1, objectref Kreira se novi objekat tipa


indexbyte2 koji je identikovan referen-
com na klasu.

newarray bc atype count arrayref Kreira se novo polje sa count


elemenata primitivnog tipa
koji je identikovan sa atype.
nop 00 [No change] izvrava se no operacija

pop 57 value izbacuje vrednost sa vrha


steka

pop2 58 value2, value1 Izbacuju se dve vrednosti sa


vrha steka (ili jedna vrednost,
ako je tipa double ili long).

puteld b5 indexbyte1, objectref, value Postavlja se podatak value


indexbyte2 u objekat objectref, gde
je podatak identikovan
referencom na podatak
index(indexbyte1 <<
8 + indexbyte2).
putstatic b3 indexbyte1, value Postavlja se statiki po-
indexbyte2 datak value u klasu, gde
je podatak identikovan
referencom na podatak
index(indexbyte1 <<
8 + indexbyte2).
R

ret a9 index [No change] Nastavlja se izvravanje sa


adrese koja se uzima iz lo-
kalne promenljive #index.
return b1 [empty] Vraa se void iz metoda.

saload 35 arrayref, index Uitava se short iz polja.


value
16.1. JAVA BAJTKOD 325

swap 5f value2, value1 Permutuju se dve vrednosti


value1, value2 u vrhu steka (napomena da
value1 i value2 ne smeju da
budu tipa double i long)

table- aa [0-3 bytes index  Nastavlja se izvravanje sa


switch padding], de- adrese u tabeli sa pozicije
faultbyte1, index.
default-
byte2, defa-
ultbyte3, de-
faultbyte4,
lowbyte1,
lowbyte2,
lowbyte3,
lowbyte4,
highbyte1,
highbyte2,
highbyte3,
highbyte4,
jump o-
sets...

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

breakpoint ca Rezervisano za take prekida


u Java debageru.

impdep1 fe Rezervisano za operacije de-


bagera koje zavise od imple-
mentacije.

impdep2  Rezervisano za operacije de-


bagera koje zavise od imple-
mentacije.

(no cb- Rezervisano su za neku bu-


name) fd duu primenu.

xunusedx ba Ovaj kod operacije se ne ko-


risti.
Indeks
goto funkcija, 142 dinami;ka memorija , 281
ablon, 63 dinamiki jezici, 276
direktna redukcija, 24, 259, 267
adresiranje, 274 direktno izvoenje, 24
akcije, 190 dodatni atributi, 189
aktivacioni slog, 278, 284 dvosmerni automat, 36
aktivaciono stablo, 281
apstraktna klasa, 160 eksponent rei, 17
apstraktno sintaksno stablo, 232
aritmetiki operatori, 65 at pristup, 160

asembler, 4 formalna gramatika, 16, 24, 37

asemblerski jezik, 4, 273, 285 formalni jezik, 15, 19

asocijativnost, 188 formalni opis, 5

asocijativnost operatora, 210 FORTRAN, 300, 303

atribut tipa, 226 fraza, 140

atributi, 217 fraze, 119

automat, 35 funkcija Follow, 99

azbuka, 16 funkcija zatvaranja closure, 142


funkcije prvenstva, 121, 132
beskonteksne gramatike, 28, 32, 111 funkcijski potprogram, 252
beskonteksne gramatike , 135
bezkonteksne gramatike, 94 generator koda, 271, 291

bezuslovni skok, 257 generisani atributi, 217

bottom-up analiza, 79, 86, 119 generisanje koda, 12, 271

broja naredbi, 273 globalne promenljive, 191

Bulovi izrazi, 250 globalni nivo, 264

butstrepovanje, 299 graf automata, 43, 47, 142


grafovi zavisnosti, 218
C, 308 gramatika prvenstva, 124
celobrojne konstante, 66 gramatike tipa dva, 28
ciljni jezik, 272, 300 gramatike tipa jedan, 27
Cup, 175, 207 gramatike tipa nula, 27
Cup specikacija, 209 gramatike tipa tri, 29
granini simbol, 80
denicije, 179, 187 greka, 192
denicije makroa, 180 grupisanje simbola, 177
desno izvoenje, 74
deterministiki automat, 36 hash tabela, 166

326
INDEKS 327

heap, 281 LR sintaksna tabela, 137, 142


LR(0) lanovi, 141
IBM 360, 303
identikatori, 66 mainski idiomi, 259
indeksirane promenljive, 293 mainski jezik, 3
indeksni registri, 272 mainski kod, 271
indirect triple struktura, 240 magacinski automat, 39, 94
indirektna rekurzija, 83 makro, 203
indirektna rekurzivna pravila, 82 maksroasemblerski jezik, 4
indukcione promenljive, 266 meukod, 6, 231
interpretator, 7, 197 memorijski prostor, 163
izvoenje rei, 21 meta-jezik, 5
izvorni jezik, 299 metasimboli, 176

jednaine stanja, 45, 48 naredba dodeljivanja, 241


jednosmerni automat, 36 nasleeni atributi, 217
JFlex, 175, 200 navoenje alternativa, 178
neaktivan kod, 265
klasa, 204, 209 nedeterministiki automat, 36
kljune rei, 178 nedosegljiv kod, 258
komentari, 65, 180 nejednoznana gramatika, 25
kompilator, 6 neterminalni simboli, 23, 124
konani automati, 42 normalne forme gramatika, 31
konguracija automata, 95 numerike konstante, 176
konguracija magacinskog automata, 39
konteksne gramatike, 28, 31 operatori, 178
korisniki potprogrami, 181, 187 operatorska gramatika prvenstva, 113
operatorske gramatike, 111
lanana lista, 163 optimizacija, 302
leksema, 62 optimizacija toka, 257
leksika analiza, 5, 60 organizacija memorije, 276
leksiki analizator, 59 osnovna optimizacija, 255
leksiki elementi jezika, 15 otvoreni kod, 207
leva faktorizacija, 97 oznaeno sintaksno sztablo, 224
levo izvoenje, 74
levo rekurzivna pravila, 82 Pascal, 302
levo rekurzivne gramatike, 81 PDP 11, 308
Lex, 175, 181 peephole optimizacija, 256
Lex specikacija, 175 petlje, 265
linearno ogranien automat, 38 podniz, 18
literali, 66 podsekvenca, 18
LL-1 analizatori, 93 pokazivai, 293
LL-1 gramatika sa -pravilima, 103 polustatiki jezici, 276
LL-1 gramatike bez -pravila , 100 pomeranje koda, 266
lokalne promenljive, 286 postupak LR analize, 138
LR analizator, 135 postupak sintaksne analize, 126
328 INDEKS

potpuno zatvaranje jezika, 20 sintaksno stablo, 6, 22, 26, 73, 90


pozitivno zatvaranje jezika, 20 sintaksno upravljane denicije, 217
pravila, 16, 176, 189 specijalna poetna stanja, 179
pravila gramatike, 21 stanja procesora, 286
pravila prioriteta, 122 startni simbol, 79, 143
preks, 18 statika alokacija memorije, 279
prepoznavanje jezika, 35, 41 statiki jezici, 276
preuzimanje rezultata, 287 stek, 280
prioritet operatora, 188, 210 struktura kompilatora, 163
privremene promenljive, 236 suks, 18
Programski jezici, 5
programski jezik, 3, 61, 299 t-dijagram, 299

programski prevodioci, 3 tabela prvenstva, 126

promenljive sa indeksima, 242 tabela simbola, 10, 64, 159

prostiranje copy naredbe , 264 tehnika dvostrukog bafera, 68


terminalni simboli, 23, 111

quadruple struktura, 238 tipovi vorova, 160


tipovi podataka, 225
re, 16 Tjuringova maina, 37
reenina forma, 30 tokeni, 61

redukcija, 24 top-down analiza, 79, 93

redukovana gramatika, 25 transakcione eme, 217

redundantne naredbe, 256 transponovana re, 17

registri procesora, 274 triples struktura, 238

regularne gramatike, 29 troadresni meukod, 235, 241, 260

regularni izrazi, 49, 63, 176


ulazna konverzija, 60
regularni jezici, 49
upravljake naredbe, 245
rekurzija , 281
ureeno binarno stablo, 165
relacija istog prioriteta, 111
uslovni skok, 257
relacija nieg prioriteta, 112
relacija prvenstva, 125
viejeziki kompilatori, 9
relacija vieg prioriteta, 112
vidljivi preksi, 139
relacije prvenstva, 111
virtuelna maina, 7
relacioni operatori, 65
relativne adrese, 271
Yacc, 175, 186
Yacc specikacija, 186
sekvenca povratka, 286
sekvenca poziva, 285 zajedniki podizrazi, 263
semantika analiza, 6
semantika pravila, 232, 241
shift-reduce analizatori, 137
simbolika imena, 167
sintaksa jezika, 15
sintaksna analiza, 5
sintaksna tabela, 94, 101, 104, 135
sintaksni analizator, 73, 119

You might also like