Teknik Kompiler 8
oleh: antonius rachmat c,
Bentuk Normal Greibach
disebut juga LL(1)
z Syarat GNF adalah:
z Hasil produksinya selalu diawali oleh satu simbol terminal dan
selanjutnya bisa diikuti oleh rangkaian simbol variabel ( A => aV )
z Untuk setiap terminal yang memulai GNF harus berbeda-beda z Tidak memiliki produksi ε
z Tidak bersifat rekursif kiri z Sudah dalam bentuk CNF
z Contoh:
S => aS | bT T => aS | b
LL1 (2)
z Cara pengubahan TBBK yang belum GNF
S => CA A => a | d B => b C => DD D => AB
z Tentukan urutan simbol variabel, misalnya S < A < B < C < D.
Pengurutan ini terserah, yang penting memudahkan proses berikutnya
z Periksa aturan produksi simbol pertama yang berupa simbol
variabel, apakah sudah sesuai dengan aturan urutan simbol variabel yang dibuat diatas.
S => CA (sudah karena S < C) C => DD (sudah karena C < D) D => AB (belum karena D > A)
z Maka lakukan substitusi pada simbol variabel A sehingga:
LL1 (3)
z Setelah semua memenuhi aturan urutan variabel, maka kita
lakukan substitusi mundur pada TBBK yang belum GNF: C => DD menjadi C => aBD | dBD
S => CA menjadi S => aBDA | dBDA
z Substitusi mundur dilakukan mulai dari aturan produksi yang
memiliki urutan variabel yang paling akhir (S<A<B<C<D) sehingga C disubstitusi lebih dahulu daripada S
z Hasil akhir GNF: S => aBDA | dBDA A => a | d B => b C => aBD | dBD D => aB | dB
PDA (Push Down Automata)
z
Adalah mesin otomata dari TBBK yang
diimplementasikan dengan stack sehingga
hanya terdapat operasi “push” dan “pop”
z
Stack (tumpukan) adalah suatu struktur data
yang menggunakan prinsip LIFO (Last In First
Out).
z
Sebuah stack selalu memiliki top of stack dan
elemen-elemen stack itu yang akan masuk ke
dalam stack dengan method “push” dan akan
keluar dari stack dengan method “pop”.
PDA (2)
z
Sebuah PDA dinyatakan dengan :
z Q = himpunan state
z Σ = himpunan simbol input
z T = simbol stack
z Δ = fungsi transisi
z S = state awal
z F = state akhir
PDA (3)
z PDA memiliki 2 jenis transisi, yaitu Δ yang merima
simbol input, simbol top of stack, dan state.
z Setiap pilihan terdiri dari state berikutnya dan
simbol-simbol.
z Penggantian isi stack dilakukan dengan opersi push dan
pop.
z Jenis transisi yang kedua adalah transisi ε.
z Transisi ε tidak melakukan pembacaan input namun hanya
menerima simbol top of stack dan state.
z Transisi ini memungkinkan PDA untuk memanipulasi isi
PDA (4)
z Contoh: z TBBK = D => aDa | bDb | c z Q = {q1,q2,q3} z Σ = {a,b,c} z T = {D, A, C, Z} z S = q1 z F = {q3}z Memiliki fungsi transisi sebagai berikut:
z Δ(q1,ε,Z) = {(q2,DZ)} z Δ(q2,ε,D) = {(q2,aDa), (q2,bDb), (q2,c)} z Δ(q2,a,a) = {(q2,ε)} z Δ(q2,b,b) = {(q2,ε)} z Δ(q2,c,c) = {(q2,ε)} z Δ(q2,ε,Z) = {(q3,Z)}
PDA (5)
z Misalkan inputan string: “aca”.
z Kita tahu hal itu dihasilkan oleh
z D => aDa => aca
z Maka PDA yang bisa kita buat:
z Kondisi awal : state q1, top of stack Z
z Tanpa menerima input (ε)
z Fungsi transisinya : Δ(q1,ε,Z) = {(q2,DZ)}
PDA (6)
z
Tanpa menerima input (ε)
z
Fungsi transisinya : Δ(q2,ε,D) = {(q2,aDa)}
zStack menjadi : state q2, pop top of stack,
PDA (7)
z Menerima input ‘a’
z Fungsi transisinya : Δ(q2,a,a) = {(q2,ε)}
z Stack menjadi : state q2, pop top of stack
z Tanpa menerima input (ε)
z Fungsi transisinya : Δ(q2,ε,D) = {(q2,c)}
PDA (8)
z
Menerima input ‘c’
z
Fungsi transisinya : Δ(q2,c,c) = {(q2,ε)}
z
Stack menjadi : state q2, pop top of stack
z
Menerima input ‘a’
z
Fungsi transisinya : Δ(q2,a,a) = {(q2,ε)}
PDA (9)
z
Tanpa menerima input (ε)
z
Fungsi transisinya : Δ(q2,ε,Z) = {(q3,Z)}
zStack menjadi : state q3
z
Tidak ada transisi lagi dari q3, dan karena q3
adalah state akhir dan semua input sudah
dibaca semua, maka ‘aca’ diterima oleh PDA
tersebut
Pseudocode TBBK dengan
stack
while(masih ada input){
if(top_of_stack adalah terminal){
if(input == karakter_dalam_top_of_stack){ pop top of stack;
baca karakter input selanjutnya } else ERROR;
} else {
Cari produks yang cocok dengan karakter inputan; if(ada produksi) ganti stack dengan produksi ruas kanan;
else ERROR; }
}
Contoh
z
S => aT | bSa
zT => aT | bS | c
Recursive Descent Parsing
z Melakukan penelusuran grammar di ruas kanan
sesuai dengan masukkannya, sampai ditemukan token yang cocok.
z Jika ditemukan non terminal maka akan dipanggil
fungsi lain yang bersesuaian dengan non terminal tersebut.
z Setiap simbol non terminal memiliki fungsi
sendiri-sendiri
z Contoh:
S => bA|c A => dSd|e
Predictive Parsing
z Untuk TBBK yang rekursif kiri
z Dengan melakukan prediksi awal, membentuk
semua kemungkinan parse tree nya
z Contoh: z S => Ab | Bc z A => Df | CA z B => gA | e z C => dC | c z D => h | I
Dengan recursif descent “gchfc”:
Predictive Parsing
z Bila token dimulai dengan h atau i atau c atau d, maka
fungsi S => Ab yang dipilih
z Bila token dimulai dengan g atau e, maka fungsi S =>
Bc, selain itu error!
S Ab Bc Dfb CAb gAc ec … hfb ifb dCAb cAb … …
Semantic Analysis
z
Analisis semantik menganalisis kebenaran
source program.
z
Analisis semantik akan memanfaatkan pohon
sintaks yang dihasilkan oleh proses parsing.
z
Bagian ini berfungsi menentukan makna dari
serangkaian instruksi dari source code.
z
Tujuan: menentukan makna dari serangkaian
Semantic Analysis (2)
z Yang dilakukan oleh analisis semantik:
z Type Checking
Dilakukan pengecekan tipe ekspresi dan variabel.
z Static Checking: pengecekan dilakukan oleh kompiler
Contoh: pengecekan operator dan operand sesuai dengan tipe, flow of control check, uniqueness check (apakah ada duplikasi), name-related check (apakah sudah terdefinisi)
z Dynamic Checking: pengecekan dilakukan oleh target program.
z Type Conversion
z Implicit, dilakukan oleh kompiler z Explicit, dilakukan oleh programmer
Semantic Analysis (3)
z Contoh:z A:=(A+B)*(C+D)
z Pada proses parsing, parser akan menjumpai
ekspresi-ekspresi diatas seperti atas, seperti simbol ‘:=’, ‘+’, dan ‘*’. Namun parser tidak tahu makna yang tersimpan di dalam simbol-simbol tersebut.
z Oleh karena itu Analisis Semantik akan melakukan:
z Apakah variabel yang ada telah didefinisikan sebelumnya. z Apakah variabel tersebut tipenya sama dan benar.
z Apakah operan yang akan dioperasikan ada nilainya. z Menentukan derajat operator
z Untuk dapat menjalankan aksinya, analisis semantik akan
Tabel Simbol
Tabel Simbol berfungsi untuk:
z Menyimpan informasi tentang:
z Nama variabel dan tipe datanya
z Informasi detail untuk record dan array
z Nama prosedur dan fungsi yang ada
z Jumlah, nama, tipe data dan paramter fungsi/prosedur
z Nama label
z Konstanta dan String
z Membantu pemeriksaan kebenaran semantik dari
source code
z Membantu mempermudah dalam pembuatan
Operasi Tabel Simbol
z Jenis operasi yang dilakukan dalam tabel
simbol adalah
z Operasi insert (append/add)
z Operasi search (dengan hashing) z Operasi delete
Tabel Simbol (2)
z Biasanya tabel simbol dibuat pada tahap analisis
lexical dan masing-masing data di dalam tabel simbol diberi indeks tertentu yang bersifat unik.
z Oleh analisis sintaks, tabel simbol digunakan untuk
memeriksa kebenaran sintaks dan membangkitkan pohon sintaks untuk proses parsing.
z Hasilnya akan dianalisa kebenaran semantiksnya
dan digunakan pada tahapan code generation untuk menghasilkan sekumpulan instruksi object code.
Tabel Simbol (4)
z Pada dasarnya tabel simbol berisi daftar dan informasi
indentifier pokok yang terdapat pada source code.
z Tabel ini disebut sebagai tabel pokok.
z Dari tabel pokok ini kemungkinan besar dapat terjadi tidak
semua informasi tercover semuanya. Jadi diperlukan tabel lagi yang berfungsi sebagai tabel pembantu.
z Di dalam tabel utama harus terdapat field yang
menjembatani identifier dari tabel utama ke tabel lain
yang bersesuaian (analogikan dengan konsep basis data atau senarai pointer)
Elemen Tabel Simbol
z Pada umumnya elemen-elemen tabel simbol:
z No urut identifier (ID unik / auto increment) z Nama identifier: berisi nama-nama variabel,
prosedure, fungsi, dan lain-lain yang akan
digunakan untuk referensi pada analisis semantik, intermediate code, dan code generation.
z Tipe identifier: berisi keterangan tipe identifier.
z Object Time Address: berisi address yang mengacu
pada alamat tertentu di memori
z Dimensi (ukuran) dari identifier yang bersangkutan z Nomor baris variabel yang dideklarasikan
Jenis Tabel Simbol
z Beberapa jenis Tabel Simbol:
z Tabel identifier: berisi daftar identifier
z Tabel array: berisi informasi tambahan untuk array z Tabel blok: berisi variabel-variabel dalam lingkup
blok yang sama (lokal)
z Tabel real: berisi elemen tabel bernilai real z Tabel string: berisi informasi string
z Tabel display: berisi blok yang aktif
Tabel Simbol Identifier
z No urut identifier z Nama identifier
z Jenis identifier : prosedur, fungsi, tipe, variabel, konstanta z Tipe identifier: integer, real, char, boolean, string, record
z Level : berupa kedalaman identifier (blok program). Misal main
program = level 0, prosedur dan fungsi dalam main program = level 1. Field ini digunakan pada saat runtime untuk mengetahui current activation record yang bisa diakses.
z Pada identifier, perlu dicatat juga:
z Alamat dari identifier
z Informasi acuan identifier ke tabel identifier lain yang menerangkannya
z Link: menghubungkan identifier ke identifier lainnya, atau yang dideklarasikan pada level yang sama
z Normal: digunakan pada pemanggilan parameter by value dan by reference (berupa variabel boolean)
Contoh Tabel Identifier
z Contoh: Program A; var B : integer; Procedure X(Z:char); var C : integer; begin . . . .z Pada tabel identifier akan muncul:
z 0 A
z 1 B
z 2 X
z 3 Z
Contoh (2)
z Contoh implementasi tabel identifier: TabId : array [0..tabmax] of
Record Name : string; Link : integer; Obj : objek; Tipe : types; Ref : integer; Normal: Boolean; Level : 0..maxlevel; Address: integer; End; z Dimana :
Objek = { konstant, variabel, prosedure, fungsi }
Types = { notipe, int, reals, booleans, chars, arrays, records }
Tabel Array
z
No urut array dalam tabel
z
Tipe dari indeks array yang bersangkutan
zTipe elemen array
z
Alamat Referensi dari elemen array
zIndeks batas atas dan bawah array
zJumlah elemen array
z
Ukuran total array = (atas – bawah + 1) *
Contoh Tabel Array
z
Contoh implementasi:
TabArray: array [1..tabmax] of Record
Indextype, elementype: types; Elemenref, low, high,
tabsize:integer; End;
Tabel Blok
z
No urut blok
z
Batas awal blok
zBatas akhir blok
zUkuran parameter
zUkuran variabel
zLast variabel
Contoh Tabel Blok
TabBlok: array[1..tabmax] of Record
Lastvar, lastpar, parsize, varsize:integer;
Contoh Tabel Blok (2)
z Dengan contoh program di atas maka untuk
program A:
z Last variabel: 2 (lihat dari tabel idenfier, last variable adalah X = 2)
z Variabel size: 2 (integer = 2 byte) z Last parameter: 0 (tanpa paramter)
z Parameter size: 0
z Untuk procedure X:
z Last variabel: 4 (lihat dari tabel idenfier, last variable adalah C = 4)
z Variabel size: 2 (integer = 2 byte)
z Last parameter: 3 (Z = 3)
Tabel Simbol lain
z
Tabel Real dan Tabel String:
z No urut
z Untuk real: nilai real sedangkan untuk string:
karakter-karakter yang ada dalam string
z
Tabel Display:
z Berfungsi mencatat blok yang sedang aktif
z No urut
z Blok yang sedang aktif
Urutan Pemrosesan
z
Urutan pengaksesan: Tabel Dsiplay –
Tabel Blok – Tabel Simbol
z
Pertama, tabel display akan mengetahui
mana bagian yang aktif, maka akan diketahui
identifier-identier yang aktif dalam blok
tersebut.
z
Informasi identifier yang ada mungkin belum
lengkap sehingga diperlukan melihat
Implementasi Tabel Simbol
z
Jelas tidak menggunakan database,
Tapi menggunakan:
z
Linked List
zTree
Hash
z Contoh fungsi hash:
z maxtabel = 9
z h(string) = Σ (ASCII(Ci)) mod (maxtabel+1) z h(“ABC”) = 65+66+67 = 198 mod 10 = 8 z h(“AA”) = 65+65 = 130 mod 10 = 0
z h(“BAC”) = 66+65+67 = 198 mod 10 = 8 terjadi collision
z Maka : z 0 AA z 1 z 2 z 3 z 4 z 5 z 6 z 7 z 8 ABC -> BAC z 9