11. MENYUSUN KODE ANTARA - Teknik Kompilasi.zip

11. MENYUSUN KODE ANTARA

  (INTERMEDIATE CODE)

  i dalam model analisis-sintesa dari suatu kompilator, bagian awal dari

  ƒ D

  bagian sintesis adalah bagian yang mengubah suatu program sumber menjadi suatu representasi/kode antara (intermediate code). Kode antara ini dipakai untuk membentuk kode target (sasaran) dalam

  ƒ bahasa sasaran. ƒ Keuntungan pemakaian kode antara ini antara lain: 1. Dapat dibentuk suatu kompilator untuk berbagai mesin yang berbeda.

2. Optimasi kode dapat dilakukan pada kode antara, di mana optimasi ini tidak bergantung pada mesin.

  Yang dimaksud dengan kode antara (intermediate code) adalah suatu

  ƒ

  bentuk penyajian program sumber yang dihasilkan oleh penganalisis sintaksis guna mempermudah proses berikutnya. Salah satu metode dalam penyusunan kode antara adalah metode translasi berdasarkan sintaks (syntax-directed translation.)

  

ƒ Dalam merancang sebuah pembangkit kode antara (intermediate code

generator) terdapat dua hal mendasar, yaitu:

  • menentukan terlebih dahulu bentuk kode antara yang akan disusun, - mengerjakan aksi-aksi semantik untuk menyusunnya.

  Translasi berdasarkan sintaks (Syntax-directed translation)

ƒ Translasi berdasarkan sintaks pada dasarnya adalah perluasan dari

  tatabahasa bebas konteks (contex-free grammar) untuk keperluan penyusunan kode antara.

  

ƒ Dengan translasi berdasarkan sintaks dimungkinkan pembentukan relasi

  antara aksi semantik dengan produksi-produksi dari tatabahasa bebas konteks. Aksi semantik adalah penetapan arti dari suatu statemen atau → XYZ. produksi. Misalnya, aksi semantik dikaitkan ke produksi B Aksi semantik dikerjakan pada saat produksi B XYZ diterapkan,

  ƒ

  yaitu pada saat lambang B dikembangkan menjadi XYZ. Dengan kata lain, aksi semantik ini akan dikerjakan pada saat produksi yang bersesuaian diterapkan dalam proses analisis sintaksis.

  ƒ Konsep translasi berdasarkan sintaks dapat dijelaskan sbb.:

  • uraikan token-token masukan yang telah diterima baik secara leksikal maupun secara tatabahasa (grammar),
  • susunlah pohon urainya untuk token-token tersebut,

  • kemudian telusuri pohon urai itu untuk mengevaluasi aturan semantik

  (aksi semantik) pada simpul-simpul (node-node) pohon urai itu dengan menyusun graf ketergantungan. Graf ketergantungan adalah graf berarah yang menggambarkan ketergantungan antara atribut tersintesis dan atribut terinheritasi pada simpul-simpul pohon urai.

  • evaluasi aturan semantik (aksi semantik) bisa membentuk kode, menyimpan informasi pada tabel simbol, menampilkan pesan-pesan kesalahan, atau menampilkan aktivitas lainnya.

  Konsep translasi berdasarkan sintaks dapat digambarkan sbb.:

  ƒ evaluation order

input parse dependen for semantic

string Î tree Î cy graph Î rules Gambar 1. Konsep translasi berdasarkan sintak.

  ƒ Implementasi translasi berdasarkan sintaks tidak selalu mengikuti garis

  besar konsep pada Gambar1 di atas. Untuk kasus-kasus khusus translasi berdasarkan sintak dapat diimplementasi dalam satu langkah dengan mengevaluasi aturan semantik dalam proses penguraian, tanpa secara eksplisit membuat pohon urai atau graf yang menunjukkan ketergantungan antara atribut-atribut tersebut. Implementasi satu langkah ini sangat penting untuk efisiensi waktu kompilasi.

  Secara umum translasi berdasarkan sintaks merupakan bentuk umum

  ƒ

  dari tatabahasa bebas konteks di mana masing-masing simbol tatabahasa mempunyai himpunan atribut yang dipartisi menjadi dua subhimpunan yakni himpunan atribut tersintesis dan himpunan atribut terinheritasi (terwarisi). Jika suatu simpul untuk satu simbol tatabahasa pada pohon urai diperlakukan sebagai rekaman (record) dengan medan-medan (fields) untuk menyimpan informasi, maka atribut merupakan nama dari medan-medan tersebut.

  

ƒ Suatu atribut dapat merepresentasikan apa saja sesuai dengan pilihan

  pemakai (user) misalnya; rangkaian, angka, type, lokasi memori dan lainnya. Agar dapat dievaluasi, maka setiap atribut diberi nilai. Nilai suatu atribut pada simpul pohon urai didefinisikan oleh aturan semantik yang berkaitan dengan produksi yang dipakai pada simpul itu. Nilai atribut tersintesis pada suatu simpul dihitung dari nilai atribut pada anak dari simpul itu, sedangkan nilai atribut terinheritasi (terwarisi) dihitung dari nilai atribut pada saudara kandung (simpul sejajar) dan simpul induknya.

  Aturan/aksi semantik memberikan ketergantungan di antara atribut-

  ƒ atribut yang akan direpresentasikan oleh suatu graf ketergantungan.

  Dari graf ini dapat dicari suatu urutan evaluasi aksi semantik dikaitkan ke setiap produksi. Aksi semantik bisa berupa kalkulasi harga suatu variabel, penyusunan

  ƒ

  kode antara, pencetakkan pesan kesalahan, dan lain-lain. Sebuah harga yang dikaitkan ke sebuah simbol tata bahasa disebut sebagai sebuah

  translasi. Translasi ini dapat berupa struktur yang terdiri dari beberapa

  elemen data. Notasi X.HARGA digunakan untuk menyatakan elemen data HARGA dari translasi yang dikaitkan ke simbol X. Jika terdapat produksi dengan beberapa simbol yang sama pada ruas kanan, simbol- simbol ini dibedakan dengan superscript seperti berikut ini.

  1

  2

  1

  2 E E + E {E.HARGA := E .HARGA + E .HARGA}

  Aksi semantik berada dalam kurung kurawal sebelah kanan produksi,

  ƒ

  berupa rumus yang menyatakan bahwa translasi E.HARGA yang dikaitkan ke simbol E pada ruas kiri merupakan hasil penjumlahan translasi yang dikaitkan ke simbol-simbol E pada ruas kanan. Translasi untuk lambang + dalam produksi di atas adalah operasi penjumlahan.

  Misalnya diberikan contoh sebuah translasi berdasarkan sintaks sebagai

  ƒ

  berikut: Translasi E.HARGA berupa bilangan bulat dan angka menyatakan angka 0 sampai dengan 9.

  Produksi Aksi semantik

  1

  2

  1

  2

  → E {E.HARGA := E .HARGA + E .HARGA} E + E

  {E.HARGA := angka} E → angka

  Harga-harga translasi ditentukan dengan membuat sebuah pohon urai

  ƒ

  (parse tree) dan kemudian mengkalkulasi harga tersebut untuk setiap simpul.

  

ƒ Misal masukannya 1+2+3. Parse tree untuk masukan ini diperlihatkan

oleh Gambar 6.1.

Gambar 6.1. Parse tree untuk ungkapan 1+2+3

  →

  ƒ Simpul 1 pada Gambar 6.1. merupakan hasil penerapan produksi E angka untuk angka berharga 1 terhadap simpul E di atasnya. Aksi

  semantik yang bersesuaian dengan produksi ini memberikan harga 1 → kepada E.HARGA. Dengan cara yang sama penerapan produksi E

  angka

  untuk angka berharga 2 mengerjakan aksi semantik yang memberikan harga 2 kepada E.HARGA.

  

ƒ Dalam gambar berikut ditunjukkan harga E.HARGA untuk akar

subtree ini yang dihitung dengan menggunakan aksi semantik

  1

2 E.HARGA := E .HARGA + E .HARGA

  1

  2

  dengan E .HARGA = 1 dan E .HARGA = 2 Gambar 6.2. Pohon urai dengan translasi lengkap.

  Contoh 2. di bawah ini adalah translasi berdasarkan sintak untuk program

  ƒ kalkulator.

ƒ Translasi ini mengkaitkan atribut tersintesis bernilai integer (disebut

  val) dengan masing-masing simbol non-terminal E, T, dan F. Untuk masing-masing produksi E, T, dan F, aturan semantik menghitung nilai atribut val untuk simbol non-terminal di sebelah kiri dari nilai val untuk simbol non-terminal di sebelah kanan.

  Tabel translasi berdasarkan sintaks untuk sebuah kalkulator.

  Produksi Aturan Semantik

  L Ö E n print(E.val) E Ö E + T E.val := E .val + T.val

  1

  1 E Ö T E.val := T.val

  T Ö T * F T.val := T .val * F.val

  1

  1 T Ö F T.val := F.val

  F Ö (E) F.val := E.val F Ö digit F.val := digit.lexval

  Token digit mempunyai atribut tersintesis lexval yang nilainya

  ƒ

  diassumsikan disuplai dari penganalisis leksikal. Aturan untuk produksi L Ö E n hanyalah suatu prosedur yang mencetak nilai ekspresi aritmetik yang dibentuk oleh E.

  Dalam translasi berdasarkan sintaks, simbol-simbol terminal

  ƒ

  diasumsikan hanya mempunyai atribut tersintesis. Nilai-nilai atribut untuk terminal biasanya disuplai oleh penganalisis leksikal. Jika tidak disebutkan maka simbol awal diasumsikan tidak mempunyai atribut terinheritasi.

  ƒ Sebagai contoh, diberikan ekspresi 3*5+4 n, program itu akan mencetak

  angka 19. Gambar 3. merupakan pohon urai teranotasi untuk masukan 3*5+4 n. Keluaran, yang dicetak pada akar pohon merupakan nilai dari E.val pada anak pertama akar itu.

  Gambar 3. Pohon urai teranotasi untuk 3*5+4 n.

  ƒ Untuk melihat bagaimana atribut itu dihitung, perhatikan simpul interior paling kiri bawah, ini berkaitan dengan pemakaian produksi F Ö digit.

  Aturan semantiknya, yakni F.val := digit.lexval, menyatakan banwa nilai atribut F.val pada simpul itu adalah 3 karena nilai digit.lexval pada anak node itu adalah 3. Dengan cara yang sama pada simpul induk F ini atribut T.val mempunyai nilai 3.

  Sekarang perhatikan simpul untuk produksi T Ö T*F. Nilai atribut T.val

  ƒ

  pada simpul ini didefinisikan oleh

  Produksi Aturan semantik

  T Ö T * F T.val := T .val * F.val

  1

  1 Jika kita pakai aturan ini pada simpul itu, T .val mempunyai nilai 3 dari ƒ

  1

  anak di sebelah kiri dan F.val mempunyai nilai 5 dari anak di sebelah kanan. Jadi, T.val mempunyai nilai 15 pada node itu.

  Aturan semantik untuk produksi awal simbol non-terminal L Ö E n

  ƒ mencetak nilai ekspresi yang dibentuk oleh E.

  Pemakaian atribut terinheritasi.

  Atribut terinheritasi adalah atribut yang nilainya pada suatu simpul

  ƒ

  pohon urai didefinisikan oleh atribut pada induknya dan / atau saudara sekandung/sejajar simpul itu. Atribut ini sangat baik untuk mengekspresikan ketergantungan pembentuk suatu bahasa pemrograman dalam penulisannya. Sebagai contoh, kita dapat memakai atribut ini untuk memeriksa apakah suatu identifier muncul di sebelah kiri atau kanan suatu assignment. Ini diperlukan untuk menentukan apakah address atau nilai dari suatu atribut diperlukan. Pada contoh berikut, suatu atribut terinheritasi memberikan informasi ke beberapa identifier di dalam suatu deklarasi. Contoh 3.

  ƒ Suatu deklarasi yang dibentuk oleh simbol non-terminal D pada

  translasi berdasarkan sintak (Gambar 4) terdiri dari kata kunci int atau real, dan diikuti oleh sederetan identifier. Simbol non-terminal T mempunyai atribut tersintesis type, yang nilainya ditentukan oleh kata kunci pada deklarasi. Aturan semantik L.in := T.type (berkaitan dengan produksiD Ö TL) menentukan banwa atribut terinheritasi mempunyai type seperti dideklarasikan. Aturan itu kemudian menyebarkan type ini menuruni pohon urai dengan memakai atribut terinheritasi L.in. Lalu aturan untuk produksi L memanggil prosedur addtype untuk menambahkan type masing-masing identifier ke entrinya di dalam tabel simbol (ditunjukkan oleh attribut entry).

  Produksi Aturan Semantik

  D Ö T L L.in := T.type Ö int

  T T.type := integer T Ö real T.type := real L Ö L , id L .in := L.in

  2

  1

  addtype (id.entry, L.in) L Ö id addtype (id.entw, L.in) Gambar 4. Definisi berdasarkan-sintak dengan atribut terinheritasi L.in.

  Gambar 5. menunjukkan pohon urai teranotasi untuk kalimat real id ,

  ƒ

  1

  id , id . Nilai L.in pada tiga L-node memberikan type identifier id , id ,

  2

  3

  1

  2 dan id . Nilai-nilai ini ditentukan dengan menghitung nilai atribut

3 T.type pada anak sebelah kiri akar dan mengevaluasi L.in dari puncak

  ke bawah pada ketiga L-node yang di sebelah kanan sub-pohon. Pada masing-masing L-node kita juga memanggil prosedur addtype untuk menyisipkannya ke dalam tabel simbol.

  Gambar 5. Pohon urai dengan atribut terinheritasi pada setiap simpul berlabel L.

  Graph Ketergantungan ƒ Jika suatu atribut b pada suatu node di pohon urai tergantung pada suatu

  atribut c, maka aturan semantik untuk b (pada node itu) harus dievaluasi setelah aturan semantik yang mendefinisikan c. Ketergantungan antara atribut tersintesis dan atribut terinheritasi pada node-node pohon urai dapat digambarkan oleh suatu graph berarah yang disebut graph ketergantungan. Sebelum kita membuat graph ketergantungan ini, kita tulis

  ƒ

  masing-masing aturan semantik dalam bentuk b := f(c , c ,...,c ,),

  1 2 k

  dengan membuat atribut tersintesis dummy b untuk masing-masing aturan semantik yang memuat suatu panggilan prosedur. Graph itu mempunyai suatu node untuk masing-masing atribut dan sisi dari node c ke node b jika atribut b tergantung pada atribut c. Graph itu selengkapnya dibuat sebagai berikut

  for masing-masing node n di dalam pohon urai do

for masing-masing atribut a dari simbol grammar pada n to

  buat suatu node untuk a pada graph itu

  for masing-masing node n di pohon urai do for masing-masing aturan semantik b:=f(e l ,e 2 , ...... , c k )

  yang berkaitan dengan produksi yang dipakai pada n do

  for i:=l to k do buat suatu sisi dari node untuk A ke node untuk b; Sebagai contoh, misalkan A.a := f(X.x,Y.y) merupakan aturan semantik

  ƒ

  untuk produksi A Ö XY. Aturan ini mendefinisikan suatu atribut tersintesis A.a yang tergantung pada atribut X.x dan Y.y. Jika produksi ini dipakai di dalam pohon urai, maka akan ada tiga node A.a, X.x, dan Y.y di dalam graph itu dengan sisi dari X.x ke A.a karena A.a tergantung pada X.x dan sisi dari Y.y ke A.a karena A.a tergantung pada Y.y. Jika produksi A Ö XY mempunyai aturan semantik X.i := g(A.a Y.y),

  ƒ

  maka akan ada sisi dari A.a ke X.i dan sisi dari Y.y ke X.i karena X.i tergantung kepada A.a dan Y.y.

  Contoh 4.

  Jika produksi berikut dipakai dalam pohon urai maka kita

  ƒ

  menambahkan sisi ke dalam graph ketergantungan seperti ditunjukkan pada Gambar 6.

   Produksi Aturan semantik

  E Ö E + E E.val : = E .val + E .val

  1 2 l

  2 Tiga node yang diberi tanda dot besar pada graph ketergantungan ƒ

  merepresentasikan atribut E.val, E .val dan E .val. Sisi dari E .val ke

  

1

  2

  1 E.val menunjukkan bahwa E.val tergantung pada E .val dan sisi dari

  1 E .val ke E.val menunjukkan banwa E.val tergantung pada E .val. Garis

  2

  2

  tipis pada Gambar 6. itu merepresentasikan pohon urai dan bukan bagian dari graph ketergantungan itu.

  Gambar 6. E.val tersintesis dari E .val dan E .val.

  1

  2 Gambar 7. Graph ketergantungan untuk pohon urai Gambar 5. Contoh 5. Gambar 7. menunjukkan graph ketergantungan untuk pohon

  ƒ

  urai pada Gambar 5. Node-node pada graph itu diberi label oleh angka-angka seperti berikut. Ada sisi dari node 4 (T.type) ke node 5 (L.in) karena atribut terinheritasi L.in tergantung pada atribut T.type berdasarkan aturan semantik L.in := T.type untuk produksi D Ö TL. Dua sisi ke node 7 dan 9 karena L .in tergantung pada L.in menurut

  1 aturan semantik L .in := L.in untuk produksi L Ö L1, id.

1 Masing-masing aturan semantik addtype(id.entry, L.in) (berkaitan

  dengan L-produksi) mengakibatkan pembentukan attritut dummy. Node 6, 8, dan 10 dibuat untuk attribut dummy ini.

  Urutan Evaluasi

  Pengurutan secara topologi dari suatu graph acyclic berarah adalah

  ƒ

  sembarang urutan node-node m , m , ...., m , sehingga jika ada sisi dari

  1 2 k

  node m ke node m maka m muncul lebih dahulu dari m pada urutan

  l j i j tadi.

  Pengurutan secara topologi dari suatu graph acyclic berarah

  ƒ

  memberikan urutan pengevaluasian aturan semantik yang benar (yang berhubungan dengan node yang bersangkutan) dalam pohon urai. Dengan perkataan lain, atribut c , c , ..., c di dalam aturan semantik b

  1 2 k := f(c , ..., c ,) sudah ada pada suatu node sebelum f dievaluasi. 1 k

  Translasi yang ditentukan oleh definisi berdasarkan-sintak dapat dibuat

  ƒ

  seperti berikut. Tata bahasa dipakai untuk membuat suatu pohon urai untuk suatu masukan. Graph ketergantungan dibuat seperti dijelaskan di atas. Dari urutan secara topologi graph berarah, kita peroleh urutan evaluasi untuk aturan-aturan semantik. Evaluasi aturan semantik dalam urutan ini memberikan translasi dari rangkaian masukan. Contoh 6.

  ƒ

  .entry, a

  ); a

  9

  := a

  7

  ; addtype(id

  1

  9

  .entry, a

  );

  ƒ Evaluasi aturan-aturan semantik ini akan menyimpan type real ke dalam entry tabel simbol untuk masing-masing identifier.

  ƒ Beberapa metoda yang telah diusulkan untuk mengevaluasi aturan

  semantik adalah:

  1. Metoda pohon-urai (Parse-tree methods). Pada waktu pengkompilasian, metoda-metoda ini memperoleh suatu urutan evaluasi dari urutan secara topologi graph ketergantungan yang dibuat dari pohon urai untuk masing-masing masukan. Metoda-metoda ini akan gagal menemukan urutan evaluasi hanya jika graph ketergantungannya untuk pohon urai tertentu mempunyai cycle.

  2. Metoda berdasarkan aturan (Rule-based methods). Pada saat pembentukan kompilator, aturan semantik dari suatu produksi dianalisa, apakah dengan tangan atau dengan alat khusus. Untuk masing-masing produksi, urutan evaluasi atribut sebelumnya ditentukan pada waktu pembentukan kompilator.

  7

  2

  Masing-masing sisi pada graph ketergantungan pada Gambar 7. berasal dari simpul yang bernomor rendah ke simpul yang bernomor tinggi. Jadi urutan secara topologi dari graph ketergantungan diperoleh dengan menulis simpul-simpul sesuai dengan urutan nomor-nomor itu. Dari urutan secara topologi ini, kita akan mendapatkan program berikut. Kita tulis a

  4

  n untuk atribut dengan simpul bernomorkan n.

  a

  4

  := real; a

  5

  := a

  ; addtype(id

  ; addtype(id

  3

  .entry, a

  5

  ); a

  7

  := a

  5

  3. Metoda oblivious. Urutan evaluasi dipilih tanpa mempertimbangkan aturan semantiknya. Sebagai contoh, jika translasi terjadi selama penguraian, maka urutan evaluasi ditentukan oleh metoda penguraian dengan tidak bergantung pada aturan semantik. Metoda ini membatasi kelas definisi berdasarkan-sintak yang dapat diimplementasikan.

  Metoda 2 dan 3 pada waktu pengkompilasian tidak perlu secara eksplisit membentuk graph ketergantungan, sehingga akan lebih effisien. Suatu definisi berdasarkan-sintak dikatakan sirkular jika graph ketergantungan ini untuk beberapa pohon urai mempunyai siklus.

SYNTAX TREE

  

ƒ Sebenarnya pohon urai (parse tree) sudah merupakan kode antara yang

  cukup berdaya guna, namun sering mengandung informasi yang berlebihan. Informasi-informasi yang demikian dapat dieliminasi sehingga dihasilkan kode antara yang lebih ekonomis. Salah satu bentuk lain pohon urai tersebut adalah pohon sintaks. Pada sintaks tiap simpul daun menyajikan operan, sedangkan tiap simpul yang bukan simpul daun menyajikan operator. Gambar 6.3 memperlihatkan pohon sintaks untuk ungkapan aritmetika 1+2+3. Bandingkan dengan pohon urai pada Gambar 6.1.

Gambar 6.3. Pohon sintaks untuk ungkapan 1+2+3

  

ƒ Translasi berdasarkan sintaks dapat mendefinisikan pohon sintaks

dengan mudah. Bagan berikut mendefinisikan ungkapan aritmetika.

  

E.HARGA adalah translasi yang mempunyai harga berupa penunjuk ke

simpul pohon sintaks.

  Produksi Aksi semantik

  1

  2

  1

  2

  → E .HARGA, E .HARGA)}

  E op E {E.HARGA := SIMPUL(op, E

  1

  1

  → (E {E.HARGA := E .HARGA} E )

  1

  → - E {E.HARGA := UNER(-, E .HARGA)} E

  1

  → angka {E.HARGA := DAUN(angka)} E Routine SIMPUL(OP, KIRI, KANAN) mempunyai tiga masukan.

  ƒ

  Masukan pertama adalah nama operator, masukan kedua dan ketiga adalah penunjuk-penunjuk ke simpul akar subtree. Routine ini membuat simpul baru yang dilabeli dengan OP serta menjadikan KIRI dan KANAN masing-masing sebagai anak kiri dan anak kanan simpul ini.

  

Routine UNER(OP, ANAK) membuat simpul baru berlabel OP dan

  menjadikan ANAK sebagai anaknya. Routine DAUN(ANGKA) membuat simpul baru berlabel ANGKA sebagai simpul daun. Masing- masing routine ini menghasilkan penunjuk ke simpul yang dibuatnya. Sebagai contoh, gambar berikut yang memperlihatkan penyusunan

  ƒ syntax tree untuk ungkapan aritmetika 1+2+3.

  Gambar 4. Sebuah contoh penyusunan pohon sintaks

  Directed Acylic Graph (DAC) untuk Ekspresi

  DAG untuk suatu ekspresi menentukan sub-ekspresi yang sama dalam

  ƒ

  suatu ekspresi. seperti halnya pohon sintaks, DAG mempunyai suatu simpul untuk setiap sub-ekspresi, simpul interior merepresentasikan suatu operator sedangkan anak-nya merepresentasikan operand. Perbedaan pohon sintaks dengan DAG adalah dalam suatu simpul yang merepresentasikan sub-ekspresi yang sama mempunyai lebih dari satu induk, dalam pohon sintaks sub-ekspresi. Yang sama akan direpresentasikan oleh sub-pohon duplikatnya. a + a * (b-c) + (b-c) * d

  

ƒ Daun untuk a mempunyai dua induk karena a muncul pada dua

  sub-ekspresi a dan a*(b-c). Hal yang sama terjadi pada sub-ekspresi (b-c).

Gambar 5.11 DAG untuk ekspresi a+a*(b-c)+(b-c)*d.

  Translasi berdasarkan sintaks akan membentuk suatu DAG jika kita

  ƒ ubah operasi pembentukan simpulnya. Suatu DAG diperoleh jika fungsi pembentukan suatu simpul pertama-tama memeriksa dahulu apakah ada simpul yang sama. Sebagai contoh, sebelum membuat suatu simpul dengan label op dan field dengan pointer ke kiri dan ke kanan, mknode(op,left,right) dapat memeriksa apakah simpul semacam ini sudah pernah dibuat. Jika demikian, maka mknode(op,left,right) dapat mengembalikan suatu pointer yang menunjuk ke simpul yang sudah pernah dibuat itu. Hal yang sama juga dapat dilakukan pada mkleaf.

  Contoh 5.9.

  l3

  ,p

  9

  ); (11) p

  11

  := mkleaf(id,d); (12) p

  l2

  := mknode('*',p

  10

  .p

  ll

  ); (13) p

  := mknode('+',p

  := mknode('-',p

  7

  ,p

  l2

  ); Gambar 5.12 Instruksi untuk membuat DAG Gambar 5.11.

  

ƒ Pada saat mkleaf(id,a) diulangi pada baris 2, node yang telah dibuat

  oleh mkleaf(id,a) dikembalikan, jadi p

  1

  := p

  2

  . Juga node yang dikembalikan pada baris 8 dan 9 sama dengan node yang didapat pada baris 3 dan 4. Dan akhirnya node yang dikembalikan pada baris 10 harus sama dengan node yang dikembalikan oleh mknode pada baris 5.

  ƒ

  8

  10

  ƒ Instruksi-intruksi pada Gambar 5.12 membuat DAG pada Gambar 5.11

  3

  (dengan syarat mknode dan mkleaf akan membuat simpul baru kalau perlu saja) dan jika mungkin mengembalikan pointer-pointer yang menunjuk pada node yang sudah ada dengan label dan anaknya. Pada Gambar 5.12, a, b, c, dan d menunjuk pada entri tabel untuk identifier a, b, c dan d. (1) p

  l

  := mkleaf (id,a); (2) p

  2

  := mkleaf (id,a); (3) p

  3

  := mkleaf (id,b); (4) p

  4

  := mkleaf (id,c); (5) p

  5

  := mknode ( '-',p

  ,p

  := mkleaf(id,c); (10) p

  4

  ); (6) p

  6

  := mknode ('*'.p

  2

  .p

  5

  ); (8) p

  8

  := mkleaf(id,b); (9) p

  9

  Pada banyak aplikasi, node-node diimplementasikan sebagai record yang disimpan di dalam array seperti Gambar 5.13. Pada gambar itu, masing-masing record mempunyai suatu field berlabel yang menentukan ciri-ciri nodenya. Kita dapat menyebut suatu node dengan indeknya atau posisi di dalam array. Indek integer dari suatu node sering disebut angka nilai. Sebagai contoh, kita bisa mengatakan node 3 mempunyai label +, anak kirinya adalah node 1 dan anak kanannya adalah node 2. Algoritma berikut dapat dipakai untuk membuat node suatu representasi dag dari suatu ekspresi.

  ASSIGNMENT DAC REPRESENTATION GamDar 5.13 Node-node dalam Dag untuk l:=i+10.

  Algorltma 5.1. Metoda angka-nilal untuk membuat suatu node dl dalam suatu DAG.

  Misalkan node-node disimpan di dalam array seperti pada Gambar 5.13,

  ƒ dan masing-masing node diwakili.oleh indeksnya (angka nilai).

  Misalkan signature dari suatu node operator adalah triple op. I, dan r terdiri dari label op. anak kiri 1, dan anak kanan r.

  Masukan: Label op. node 1, dan node r. Keluaran: Suatu node dengan signature ( op,l,r )

  Metod: Pada array itu, cari node m dengan la bel op. anak kiri 1, dan

  ƒ

  anak kanan r. Jika node yang demikian ditemukan, berikan m kalau tidak buat suat node baru n dengan label op. anak kiri 1, dan anak kanan r, dan berikan n. Salah satu cara untuk menentukan apakah suatu node m sudah ada di

  ƒ

  dalam array adalah dengan menyimpan semua node yang sudah dibuat pada suatu list dan periksa list tersebut apakah memang ada signature Yang dicari. Pencarian m dapat dibuat lebih efisien jika dipakai list sebanyak k, yang disebut keranjang (Ducket), dan memakai fungsi hashing h untuk menentukan keranjang mana yang harus dlcari.

  

ƒ Fungsi hashing h menghitung angka suatu keraniang dari nilai op. I, dan

  r. Jika argument Yang sama dipakai, maka akan diberikan angka keranjang yang sama. Jika m tidak di dalam keraniang h(op,l,r), maka suatu node baru n dibuat dan ditambahkan ke dalam keranjang itu, sehingga jika dicari maka node ini akan ditemukan di keranjang ini.

  

ƒ Beberapa signatur bisa berada di dalam keranjang Vang sama, dalam

  prakteknya kita mengharaptan bahwa jumiah node di dalam suatu keranJang sedikGt. Setiap keraniang dapat diimplementasikan sebagai suatu list yang

  ƒ

  bersambungan (linked list) seperti pada Gambar 5.14. Sethap cell di dalam linked list merepresentasikan suatu node. Kepala beranjang, terdiri dari pointer ke cell yang pertama di dalam list, disimpan di dalam suatu array. Nomor keranjang yang diperoleh dari h(op,l,r merupakan Indek array kepala keranjang.

INTERMEDIATE CODE UNTUK BAGIAN DEKLARASI

  VARIABEL ƒ agian deklarasi variabel berfungsi untuk mendeklarasikan variabel-

  B

  variabel yang digunakan pada bagian definisi data maupun bagian perintah. Deklarasi variabel meliputi penamaan dan pemberian tipe variabel. Mengingat fungsi dari tabel lambang (symbol table),

  

intermediate code untuk bagian deklarasi variabel adalah tabel lambang

  itu sendiri. Dengan demikian aksi-aksi semantik untuk bagian deklarasi variabel adalah proses pengisian tabel lambang dengan informasi- informasi mengenai variabel-variabel.