Anda di halaman 1dari 22

Teknik Kompilasi

1) Bahasa Pemrograman

Untuk menyampaikan sesuatu hal misalnya pendapat kepada seseorang ,


tentunya kita memerlukan suatu bahasa yang dimengerti oleh satu sama lain.
Kita semua tahu bahwa bahasa merupakan suatu alat komunikasi yang
digunakan untuk menyatakan berbagai macam ekspresi, ungkapan , maupun
gagasan atau ide.

Dalam berkomunikasi dengan komputer tentunya memerlukan sebuah


teknik yang relatif yang sedikit berbeda jikalau dibandingkan dengan sesama
manusia sendiri. Karena komputer tidak memahami bahasa manusia , maka
dibutuhkan suatu bahasa yang mampu menjembatani antara pikiran manusia
yang biasanya tidak terstruktur dengan ketepatan yang dituntut dalam
pemanfaatan serta pelaksanaan kerja komputer.

Suatu program akan lebih mudah dan alami untuk kita peroleh jika
bahasa pemrograman yang digunakan cukup sesuai dengan tipe masalah yang
kita hadapi. Di dalam bahasa pemrograman ini harus mengandung susunan serta
struktur yang mencerminkan terminologi elemen yang digunakan dalam
penyajian masalah.

Berikut ini adalah hirarki atau tingkatan dari bahasa pemrograman


berdasarkan apda peningkatan kebebasan mesin adalah sebagai berikut :

1) Bahasa mesin (Machine-level Languages) merupakan bentuk


terendah dari bahasa komputer. Instruksi direpresentasikan dalam
kode numerik , seperti bits, register dan sangat primitif karena tidak
lebih dari urutan bit-bit 0 dan 1.

Instruksi dalam bahasa mesin bisa saja dibentuk menjadi micro-code,


semacam prosedur dalam bahasa mesin. Bahasa ini tergantung dari
jenis mesin komputer yang digunakan. Jika jenis komputer
mengalami perubahan maka dapat dipastikan bahwa user harus
mempelajari lagi bahasa mesin yang dibuat untuk jenis yang baru
teresebut.

2) Bahasa rakitan (Assembly Languages) merupakan bentuk simbolik


dari bahasa mesin. Kode misalnya ADD , MUL , MOV dsb.

3) Bahasa tingkat tinggi (High level languages / user oriented


languages) lebih mudah dikenali oleh manusia karena kebanyakan
menggunakan statement dalam bahasa inggris .

Banyak memberikan suatu fungsi kontrol program , perulangan ,


block , dan prosedur. Bahasa tingkat tinggi tidak tergantung pada
salah satu jenis mesin komputer dan biasanya masih membutuhkan
suatu translator baik berupa interpreter maupun compiler.

4) Bahasa berorientasi masalah (Problem-oriented languages) sering


juga dimasukan sebagai bahasa tingkat tinggi , misalnya : SQL ,
Myob, dsb.

2) Translator

Suatu input dari sebuah penerjemah atau translator dari suatu program
disebut dengan program sumber atau source program. Selanjutnya program
sumber ini diterjemahkan ke dalam sebuah program objek atau program target.
Program sumber ini ditulis kedalam suatu bahasa sumber (source language) dan
program objek dalam suatu bahasa objek (object language).

Jika bahasa sumber adalah bahasa rakitan dan program objek yang
bersangkutan merupakan program dalam bahasa mesin , maka penerjemah /
translator tersebut dinamakan assembler. Bahasa rakitan menyerupai bahasa
mesin. Di dalam bahasa mesin elementer , banyak diantara instruksinya
merupakan suatu simbol simbolik dari instruksi bahasa mesin yang bersesuaian.
Setiap instruksi bahasa rakitan terdiri dari sebuah himpunan terurut(ordered set)
dari suatu field. Misalnya field pertama harus mewakili suatu label yang diikuti
suatu field operasi.

Suatu bahasa tingkat tinggi mampu membentuk statement pemilihan


(case / if) , statement bersarang(nested) dan blok yang tidak biasanya tidak
terdapat di dalam suatu bahasa rakitan.

Suatu translator / penerjemah yang mengubah suatu bahasa tingkat tinggi


, seperti pascal , c/ c++ , fortran , dsb ke dalam bahasa mesin komputer atau ke
dalam bahasa rakitan , disebut dengan kompiler. Waktu yang digunakan dalam
mengkonversi suatu program ke program objek di sebut dengan waktu kompilasi
atau compile time.

Berikut ini adalah beberapa jenis translator untuk menerjemahkan suatu source
sumber agar dikenali oleh mesin diantaranya :

1) Assembler
Source code adalah bahasa assembly, object code adalah bahasa mesin.

2) Compiler

Source code nya adalah bahasa tingkat tinggi , object code adalah bahasa
mesin atau bahasa assembly.

3) Interpreter

Interpreter ini tidak menghasilkan bentuk object code, tetapi hasil


translasinya hanya dalam bentuk internal, dimana program induk harus
selalu ada / berbeda dengan compiler.

3) Model Kompilator

Pekerjaan untuk membuat sebuah kompilator untuk suatu bahasa sumber adalah
sangat sulit. Kerumitan serta sifat dari suatu proses kompilasi tergantung pada
tingkat keluasan dari bahasa sumber. Kerumitan kompilator dapat dikurangi jika
perancang bahasa pemrograman mempertimbangkan bermaca-macam faktor dalam
perancangan.

Suatu kompilator harus melaksanakan dua tugas utama yaitu tugas analisis
terhadap program sumber dan tugas sintesis memadukan menjadi program objek
yang ekivalen. Tugas analisis berhubungan dengan pemisahan bagian dari program
sumber menjadi bagian-bagian dasar dan menggunakan bagian-bagian ini dalam
tugas sintesis dalam membangun modul program objek yang ekivalen.

Suatu program sumber adalah suatu untai atau string dari symbol yang
umumnya berupa huruf, angka atau symbol khusus seperti + , - , * dsb.

Suatu program sumber berisi bentuk dasar bahasa seperti :

- Nama variable
- Label
- Konstanta
- Kata kunci (reserved word) maupun operator
-

Pembuatan compiler

Kompiler yang bagus adalah yang dapat bekerja dengan baik pada mesin-mesin
komputer dan tidak membutuhkan proses yang lama

Ada beberapa cara dalam membuat suatu penerjemah dalam hal ini misalnya compiler,
dan bahasa yang digunakan untuk membuat compiler pun dapat beragam misalnya :

Bahasa mesin :

- Sangat sukar dan sangat sedikit kemugnkinan untuk membuat


compiler dengan bahasa ini , Karena manusia mempelajari bahasa
mesin.
- Sangat tergantung pada mesin
- Bahasa mesin kemungkinan digunakan pada saat pembuatan
assembler.

Assembly :

- Hasil dari program mempunyai ukuran yang relatif kecil


- Sulit dimengerti karena statement/ perintahnya singkat, butuh usaha
yang besar untuk membuat compiler dengan bahasa ini
- Fasilitas yang dimiliki terbatas

Bahasa Tingkat Tinggi :

- Lebih mudah dipelajari


- Fasilitas yang dimiliki lebih baik (banyak)
- Memiliki ukuran yang relatif besar, missal membuat compiler pascal
dengan menggunakan bahasa C
- Untuk mesin yang berbeda perlu dikembangkan tahapan-tahapan
tambahan . Misalnya membuat compiler C pada DOS berdasarkan
compiler C pada UNIX.

Bootstrap

- Untuk membangun sesuatu yang besar, dibangun/ dibuat dulu bagian


intinya
- PO dibuat dengan assembly , P1 dibuat dari P0, dan P2 dibuat dari
P1, jadi compiler untuk bahasa P dapat dibuat tidak harus
menggunakan assembly secara keseluruhan.
Hubungan konsep Teori Kompilasi dengan Teori Bahasa Automata :

- Teknik kompilasi merupakan kelanjutan dari konsep-konsep dari


teori bahasa automata yang telah dipelajari sebelumnya.
- Tata bahasa (grammar) adalah sekumpulan dari himpunan variable-
variable symbol-simbol terminal, symbol non terminal , symbol awal
yang dibatasi oleh aturan-aturan produksi
- Noam Chomsky menggolongkan tingkatan bahasa dalam 4 kelas
yang lebih dikenal dengan Hirarki Chomsky.
- Pada tahun 1959 Backus memperkenalkan notasi formal baru untuk
syntax bahasa yang lebih spesifik
- Peter Nour (1960) merevisi metode dari syntax yang dikenal dengan
BNF (Backus Nour Form).

Hirarki Chomsky
Keterangan :

Tipe 0 / Bahasa Natural : Tidak ada batasan aturan produksi Contoh : Abc → De

Tipe 1 / Context Sensitive : Panjang string ruas kiri harus lebih kecil atau sama dengan
ruas kanan. Contoh : Ab → DeF , CD → eF

Tipe 2 / Context Free Grammar : Ruas kiri haruslah tepat satu symbol variable .
Contoh B→CDeFG

Tipe 3/ Regular : Ruas Kanan hanya memiliki maksimal satu symbol non terminal
yang diletakan di paling kanan sendiri. Contoh :

A →e

A → efg

A → efgH

Aturan Produksi
Aturan produksi digunakan agar penerapan pada pembuatan tata bahasa
dikomputer dapat lebih mudah dan menghasilkan suatu penerjemah yang dapat
diandalkan.

- Aturan produksi dinyatakan dalam bentuk : α → β , α menghasilkan


/ menurunkan β
- Α symbol-simbol untuk ruas kiri dan β symbol-simbol untuk ruas
kanan
- Simbol-simbol bisa berupa terminal dan Non-terminal , dimana Non-
terminal masih bisa diturunkan menjadi symbol yang lainnya.
- Umumnya symbol terminal di simbolkan dengan huruf kecil (a,b,c
dst). Sedangkan untuk symbol non-terminal disimbolkan dengan
huruf capital (A,B,C,dst)
- Contoh aturan produksi :

T → a, T menghasilkan a

E → T | Ta, E menghasilkan T atau E menghasilkan Ta.

Diagram state

Bagi pembuat penerjemah yaitu manusia harus sering menguji tata bahasa yang
dibuat , salah satu ilustrasi pengujian agar yang diinginkan sesuai dengan yang diharap
kan maka, digunakan suatu gambar yaitu dinamakan dengan diagram state.

3.1) Analisis Leksikal


Program sumber merupakan input dari penganalisis leksikal atau
scanner. Analisis leksikal mempunyai tujuan untk memisahkan naskah
program sumber yang masuk , menjadi bagian leksikografis terkecil atau
Token seperti misalnya konstanta , nama variable , kata kunci (seperti DO ,
IF , REPEAT, DLL) dan operator. Pada hakikatnya , inti tugas penganalisis
leksikal adalah melaksanakan analisis sintaks tingkat rendah.

Untuk alas an efiesiensi , kepada setiap kelas dari token diberikan suatu
bilangan yang mewakili harga internalnya , secara unik . Sebagai contoh
suatu nama varibel mungkin disajikan atau diwakili oleh suatu bilangan 1,
suatu konstanta disajikan dengan bilangan 2, suatu label dengan bilangan 3 ,
operator penjumlahan dengan bilangan 4 dsb.

Misalnya statemen dalam penggalan program berikut ini :

TEST : IF A > B THEN X = Y;

Statement ini dapat diubah oleh penganalisis leksikal ke dalam deretan


token , dan masing-masingnya disajikan / diwakili oleh bilangan berikut :
Sebagai catatan dalam pelacakan statemen sumber dan pembentukan bilangan
penyajian dari setiap token , ada kemungkinan dihasilkan blank atau spasi (white
spaces) dalam suatu statement. Penganilisis leksikal harus dapat mengenali adanya
spasi dan komentar. Kedua kelas item jenis ini, meskipun adalah merupakan bagian dari
program tidak akan dilaksanakan , dan akan diabaikan.

Bahasa pemrograman tertentu mengizinkan adanya statement baris jamak .


Penganalisis leksikal harus dapat melakukan proses input seperti statement baris jamak
ini . Beberapa scanner menempatkan konstanta label dan nama variable pada tabel-tabel
yang sesuai . Isi suatu tabel dapat berupa tipe variable (misalnya INTEGER, FLOAT,
BOOLEAN, dsb), alamat program objek , harga dan di mana varibel tersebut di
deklarasikan .

Penganalisis Leksikal mengirimkan Token kepada penganalisis Sintaks. Token


ini dapat berbentuk beberapa potong item. Item pertama memberikan alamat/lokasi dari
Token dalam beberapa tabel symbol. Item kedua adalah bilangan yang mewakili token.

Hal ini merupakan suatu pendekantan yang menguntungkan karena semua token
diwakili oleh panjang informasi yang tetapi , yang terdiri dari suatu alamat (atau
pointer) dan suatu bilangan bulat.

Gambar : Komponen sebuah kompilator


Jadi secara umum tugas dari Analisis Leksikal adalah sebagai berikut :

- Mengidentifikasikan semua besaran yang membangun suatu bahasa


- Mentransformasikan ke token-token
- Menentukan jenis dari token-token
- Menangani kesalahan
- Menangani tabel symbol
- Scanner di design untuk mengenali – keyword , operator , identifier
- Token : memisahkan karakter dari source language ke dalam grup
yang secara logical tergabung.
- Misalnya : konstanta , nama variable ataupun operator dan delimiter
(atau sering disebut menjadi besaran lexical)

Contoh : Besaran Leksikal

- Identifier dapat berupa keyword atau nama kunci , seperti IF..else

BEGIN … END (pada pascal), INTEGER (pascal) , INT , FLOAT


(C/C++)

- Konstanta : Besaran yang dapat berupa bilangan bulat (integer),


bilangan pecahan (float/real), Boolean(true/false), karakter, string dsb
- Operator : aritmatika misalnya ‘*’,’+’,’-‘,’/’ operator logika : ‘ = ‘ ,
‘>=’ , ‘<=’ dsb
- Delimiter : Berguna sebagai pemisah / pembatas , seperti kurung-
buka, kurung-tutup, titik, koma, titik-dua, titik-koma, white-space
- White Space . Pemisah yang diabaikan oleh program seperti : enter,
spasi , ganti baris , akhir file
-

3.2) Analisis Sintaks

Penganalisis sintaks lebih rumit dibandingkan dengan penganalisis leksikal .


Fungsinya adalah menerima program sumber (dalam bentuk barisan token) dari
penganalisis leksikal, dan selanjutnya penganalisis sintaks ini akan menentukan
struktur secara keseluruhan dari progam sumber, Proses terakhir ini analog dengan
menentukan struktur dari suatu kalimat dalam suatu bahasa. Misalnya kalimat di
identifikasikan ke dalam kelas tertentu seperti subjek, predikat, kata kerja , kata
benda, dan kata sifat.

Dalam melakukan analisis sintaks, kita memandang kelompok Token sebagai


kelas sintaks yang lebih besar seperti ekspresi, statement dan prosedur.
Penganalisis sintaks, yang disebut dengan parser, akan menghasilkan suatu pohon
(tree) sintaks. Di sini simpul daun merupakan token dan setiap simpul yang bukan
daun mewakili suatu tipe kelas sintaks (yang lebih dikenal dnegan symbol non
terminal atau variable). Sebagai contoh adalah analisis dari statemen sumber :

(A+B)*(C+D)

Pohon sintaks yang dihasilkan oleh parser kemudian digunakan oleh


penganalisis semantak. Fungsi dari penganalisis semantic adalah memberi arti atau
Semantik dari program sumber. Meskipun secara konsep kita memisahkan sintaks
program sumber terhadap semantik, penganalisis sintaks dan semantic pada
hakikatnya bekerja bersama secara sangat dekat. Walaupun demikian dalam sebuah
kompilator, proses analisis semantik merupakan suatu proses yang berdiri sendiri
dan unik.

Untuk ekspresi (A+B)*(C+D) dari contoh , penganalisis semantic harus


menentukan aksi apa yang dilakukan oleh operator aritmetika penambahan dan
perkalian terserbut. Ketika parser mengenali sebuah operator ‘+’ atau ‘*’, parser
memanggil rutin SEMANTIC-ROUTINE yang akan menggolongkan aksi yang
akan dikerjakan .

Rutin ini mungkin memerikasa apakah kedua operand yang ditambahkan sudah
dideklarasikan , serta apakah mempunyai tipe yang sama (jika tidak , bisa saja rutin
tersebut menjadi sama) dan apakah kedua operand mempunyai nilai . Penganalisi
semantic sering berinteraksi dengan berbagai tabel dari kompilator dalam
menjalankan tugasnya .
Aksi Penganalis semantic mungkin mengandung bentuk intermediate dari kode
sumber. Untuk ekspresi (A+B)*(C+) , bentuk intermediate dari kode sumber
mungkin berbentuk seperti :

(+, A,B,T1) : Menambahkan A dengan B dan menempatkan hasil sementara di


T1

(+,C,D,T2) : Menambahkan C dengan D dan menempatkan hasil sementara di


T2

(*,T1,T2,T3) : Mengalikan T1 dengan T2 dan menempatkan hasilnya di T3

Bentuk yang tepat dari bahasa sumber intermediate ke bentuk intermediate yang
disebut dengan Notasi Polish. Sebuah ekspresi infix (A+B)*(C+D) dapat
dikonversikan sehingga ekivalen dengan suffix-polish(Postfix-polish) AB+CD+*.
Ekspresi yang terakhir ini mengandung operator aritmetika dalam urutan
sebagaimana ia dilaksanakan . Jenis lain dari bentuk ini dapat berupa sebuah pohon
sintaks yang menyatakan hasil uraian atau parse dari program sumber.

Output dari penganalisis semantic dikirim kepada pembentuk kode(code)


generator . Pada saat itu bentuk intermediate program sumber . biasanya
diterjemahkan ke dalam bahasa rakitan(assembly language), ataupun ke dalam
bahasa mesin (machine language). Sebagai contoh penerjemahan dari ketiga
kuadruple di atas, dapat menghasilkan barisan alamat-tunggal (single address),
instruksi akumulator-tunggal bahasa rakitan (single-akumulator assembly language).

Gambar : Kelas yang dihasilkan dari analisis sintaks ke dalam bentuk pohon(tree)
Syntax Tree

- Pohon sintaks /pohon penurunan (syntax tree/parse tree) berguna


untuk menggambarkan bagaimana memperoleh suatu string dengan
cara menurunkan symbol-simbol variable menjadi symbol-simbol
terminal.
-

Bagian kedua dari compiler yaitu Analisis sintaks secara umum bertugas memeriksa
kebenaran dan urutan dari token-token yang terbentuk oleh lexical analysis. Dimana
tugasnya adalah :
- Pengelompokan token-token de dalam class syntax (bentuk syntax)
seperti procedure, statement, dan expression.

- Grammar : sekumpulan aturan-aturan untuk mendefiniskan bahasa


sumber.

- Grammar dipakai oleh syntax analyser untuk menentukan struktur


dari program sumber.

- Proses pendeteksiannya (pengenalan token) disebut dengan parsing


oleh karena itu Analisis sintaks sering disebut dengan parser.

- Pohon sintaks yang dihasilkan digunakan untuk semantic analyzer


yang bertugas menentukan ‘maksud’ dari program sumber, misalnya
operator penjumlahan maka semantic analyzer akan mengambil aksi
apa yang harus dilakukan .

Parsing atau Proses Penurunan

Parsing dapat dilakukan dengan cara :

- Penurunan terkiri (leftmost derivation : symbol variable yang paling kiri diturunkan
(tuntas) dahulu

- Penurunan terkanan (rightmost derivation : symbol variable yang paling kanan


diturunkan (tuntas) dahulu

Misalkan : ingin dihasilkan string aabbaa dari :

Bahasa bebas konteks( context free language) :

S -> a AS | a,

A -> SbA | ba

- Penurunan kiri :

S => aAS
 aSbAS

 aabAS

 aaabbaS

 aabbaa

- Penurunan Kanan

S => aAS

 aAa

 aSbAa

 aSbbaa

 aabbaa

Dalam pemilihan metode parsing perlu diperhatikan 3 hal berikut :

- Waktu eksekusi

- Penanganan kesalahan

- Penanganan Kode

Parsing digolongkan menjadi

- Top-down : penulusuran dari root ke leaf atau dari symbol awal ke symbol
terminal metode ini meliputi :

o Backtrack / backup : Brute Force

o No Backtrack : Recursive Descent Parser


- Bottom-Up

Metode ini melakukan penelusuran dari leaf ke root

Parsing : Brute Force

- Memilih aturan produksi mulai dari kiri

- Mengexpand symbol non terminal sampai pada symbol terminal

- Bila terjadi kesalahan (string tidak sesuai) maka dilakukan backtrack

- Algoritma ini membuat pohon parsing secara top-down , yaitu


dengan cara mencoba segala kemungkinan untuk setiap symbol non-
terminal

Contoh suatu bahasa dengan aturan produksi sebagai berikut :

S → aAD | aB

A →b | c

B → ccd | ddc

Misal ingin dilakukan parsing untuk string ‘addc’


Terjadi kegagalan (iii) dilakukan backtrack :

Terjadi kegagalan lagi (iv) dilakukan backtrack.

Kelemahan metode Brute Force :

- Mencoba untuk semua aturan produksi yang ada sehingga menjadi


lambat (waktu eksekusi)

- Mengalami kesukaran untuk melakukan pembetulan kesalahan

- Banyak memakan memori, karena membuat backup lokasi backtrack;

- Grammar yang memiliki rekursi kiri tidak bisa diperiksa sehingga


harus diubah dulu sehingga tidak rekursif kiri, karena rekursif kiri
akan mengalami Loop yang terus menerus (infinite loop).

Aturan produksi rekursif

Aturan produksi yang rekursif memiliki ruas kanan(hasil produksi) yang


memuat symbol variable pada ruas kiri.

Sebuah produksi dalam bentuk


merupakan produksi rekursif kanan

β = berupa kumpulan symbol variable dan terminal.

Contoh :

S → dS

B → adB

Bentuk produksi yang rekursif kiri

A → Aβ merupakan produksi rekursif kiri

Contoh :

S → Sd

B → B ad

Produksi yang rekursif kanan akan menyebabkan penurunan tumbuh ke kanan,


sedangkan produksi yang rekursif kiri akan menyebabkan penurunan tumbuh ke kiri.

Parsing : Recursive Descent Parser

Parsing dengan recursive descent parser

- Salah satu cara mengaplikasikan bahasa context free

- Symbol terminal maupun symbol variablenya sudah bukan sebuah


karekter

- Besaran leksikal sebagai symbol terminalnya , besaran syntax


sebagai symbol variable / non terminalnya.
- Dengan cara penurunan secara rekursif untuk semua variable dari
awal sampai ketemu terminal

- Tidak pernah mengambil token secara mundur (backtracking)

- Beda dengan turing yang selalu maju dan mundur dalam melakukan
parsing

Anda mungkin juga menyukai