Dibuat Oleh :
NPM : 2013.10.225.229
Pendahuluan
Teknik Kompilasi merupakan mata kuliah yang khusus ditujukan kepada mahasiswa
jurusan Teknik Informatika dan Ilmu Komputer. Adapun sejumlah sasaran dari
mempelajari mata kuliah Teknik Kompilasi ini diantaranya adalah :
1. Mahasiswa diharapkan mampu memahami prinsip kerja yang mendasar dari suatu
kompiler.
2. Mengetahui tahapan - tahapan dari suatu proses kompilasi.
3. Mahasiswa juga diharapkan mempunyai bekal mendasar untuk mengembangkan
ilmu pengetahuan yang dimilikinya ke tingkat yang lebih lanjut.
Bahasa Pemrograman
Manusia dapat melakukan interaksi secara efektif dengan menggunakan media
bahasa. Bahasa memungkinkan penyampaian gagasan dan pemikiran, tanpa itu
komunikasi akan sulit terjadi. Dalam lingkungan pemrograman komputer, bahasa
pemrograman bertindak sebagai sarana komunikasi antara manusia dan
permasalahannya dengan komputer yang dipakai untuk membantu memperoleh
pemecahan.
Keuntungan bahasa tingkat tinggi dibandingkan bahasa tingkat rendah adalah sebagai
berikut.
1. Kemudahan untuk dipelajari.
2. Lebih mendekati permasalahan yang akan diselesaikan.
3. Pemrogram tidak perlu mengetahui bagaimana representasi data ke dalam bentuk
internal di memory.
4. Memberikan banyak pilihan struktur kontrol seperti :
Kondisional (IF - THEN - ELSE)
Looping
Struktur Blok (Begin ... End)
Nested Statement
5. kompabilitas dan dokumentasi yang lebih baik dalam pengembangan program.
Translator
Sebuah translator melakukan pengubahan source code / source program (program
sumber) ke dalam target code / object code / object program (program objek). Source
code ditulis dalam bahasa sumber, sedang object code bisa berupa suatu bahasa
pemrograman lain atau bahasa mesin pada suatu komputer. Ada beberapa macam
translator.
1. Assembler
Menerjemahkan langsung dari source code ke object code. Source Code adalah
bahasa assembly sedangkan object code adalah bahasa mesin. Contohnya adalah
TASM.
3
Contoh yang menghasil .Com adalah : Debug, TASM (bila linker dilakukan
dengan perintah Tlink/x/t), emu8086,
Contoh yang menghasilkan .Exe adalah : TASM dengan perintah linker Tlink,
HLA, MASM32, FASM
Khusus TASM terkadang file .Com yang dihasilkan akan lebih baik daripada file .Exe
yang dihasilkan sebagai contoh adalah pada program berikut :
.Model Small
.Code
Org 100h
Main :
Jmp Mulai
Pesan db 'Selamat Datang!','$'
Mulai :
Mov Ah,09H
Mov dx,offset pesan
int 21h
mov ah,4ch
int 21h
end Main
2. Kompilator (Compiler)
Source Code adalah bahasa tingkat tinggi (misal bahasa Pascal), object code
adalah bahasa mesin atau bahasa assembly. Source Code dan data diproses pada
saat yang berbeda. Contohnya : Turbo Pascal, C++.
3. Interpreter
Interpreter tidak membangkitkan Object Code, hasil translasi hanya dalam bentuk Run
Time Code.
Contohnya : Bahasa Basica, Dbase/Foxbase
4
Compiler
1. Menerjemahkan secara keseluruhan sekaligus
2. Dihasilkan objek program
3. Dihasilkan executable program
4. Source program tidak dipergunakan lagi untuk menjalankan program.
Model Kompilator
Pengembangan kompilator untuk sebuah bahasa merupakan pekerjaan yang
kompleks. Kompleksitas kompilator bisa dikurangi bila perancang bahasa
pemrograman mempertimbangkan bermacam - macam faktor perancangan. Karena kita
berhubungan dengan bahasa tingkat tinggi, bagaimanapun suatu model dasar dari
kompilator dapat diformulasikan.
Source Object
Code Code
Analysis Synthesis
Tabel Informasi
Keterangan gambar :
Scanner : memecah program sumber menjadi besaran leksikalnya.
Beberapa kegiatan pada tahap scanner ini diantaranya adalah :
- Menangani kesalahan
Contohnya : A = +B 1
- Membuang Blank
Contohnya : A = B + 1
- Mengenali besaran leksikal
Contohnya di sini adalah mengenali apakah huruf atau angka
- Dan lain - lain
Parser : Memeriksa kebenaran dan urutan kemunculan token
Seperti :
- Samping kiri = pasti variabel
- Samping kanan = pasti ekspresi
- Tiap operator +, -, *, /, tidak boleh double. Contohnya : A = 3++7
6
Mutu Kompilator
Misalkan saja kita pernah menggunakan kompilator untuk bahasa Basic seperti Turbo
Basic dan Quick Basic. Kemudian kita bisa mengatakan bahwa salah satu lebih baik dari
lainnya. Tentu ada beberapa hal yang menjadi pertimbangan kita, dalam hal ini bisa kita
sebut sebagai mutu dari kompilator yang bersangkutan. Mutu sebuah kompilator
bergantung dari beberapa faktor, yaitu :
1. Kecepatan dan waktu proses kompilasi.
Bisa Anda bayangkan misalkan saat Anda menekan F9 (Compile) dalam
kompilator Turbo Pascal untuk melakukan kompilasi suatu program. Berapa lama
7
Anda harus menunggu untuk memperoleh hasil kompilasi itu merupakan waktu
proses kompilasi.
writekar tadi akan diubah ke intterupt 10 atau intterupt 21, akan ikut menentukan
ukuran object code - nya
3. Integrated Environtment
Merupakan fasilitas - fasilitas terintegrasi yang dimiliki oleh kompilator tersebut.
Misalnya untuk melakukan editing, debugging, testing. Biasa disebut juga dengan
IDE (Integrated Development Environtment). Misalkan saja dengan Turbo Pascal
(Turbo.Exe) Anda bisa melakukan penyuntingan sekaligus kompilasi dan debug
dalam satu lingkungan pemrograman. Sementara kalau menggunakan Clipper
(Clipper.Exe) Anda harus melakukan penyuntingan dengan menggunakan suatu
program editor (PE.Exe) ataupun notepad yang terpisah dari kompilatornya.
Pembuatan Kompilator
Pembuatan suatu kompilator dapat dilakukan dengan :
1. Bahasa Mesin
Tingkat kesulitannya sangat tinggi, karena bahasa mesin ini sangat dekat dengan
mesin sehingga sangat tidak manusiawi, dan tingkat ketergantungannya pada
mesin yang tinggi. Pembuatan kompilator dengan bahasa mesin hampir mustahil
dilakukan. Bahasa mesin mungkin digunakan saat membuat assembler. 2.
Bahasa Assembly
Bahasa assembly bisa dan biasa digunakan sebagai tahap awal pada proses
pembuatan sebuah kompilator. Keuntungan penggunaan bahasa assembly adalah
program hasil (object code) yang memiliki ukuran kecil. Kerugiannya
memerlukan usaha yang besar, karena instruksi assembly pendek - pendek (sulit
dimengerti) dan memiliki fasilitas yang terbatas. Sehingga masih terdapat
kesulitan untuk mengembangkan sebuah kompilator yang secara keseluruhan
dibuat dengan bahasa assembly.
3. Bahasa tingkat tinggi
Keuntungannya adalah proses pembuatan kompilator akan lebih mudah, karena
menggunakan bahasa tingkat tinggi yang lebih mudah dimengerti dan fasilitasnya
lebih baik dibandingkan assembly. Kerugiannya kompilator yang dihasilkan akan
memiliki ukuran yang besar. Bisa dibayangkan kalau kita akan mengembangkan
suatu kompilator untuk suatu bahasa dengan menggunakan Turbo Pascal.
9
4. Bootstrap
Gagasan dari Bootstrap adalah kita bisa membangun sesuatu yang besar dengan
lebih dulu membuat bagian intinya. Cara ini diperkenalkan oleh Niklaus Wirth saat
membuat kompilator untuk bahasa Pascal.
P2
P1
P0
Soal :
1. Mengapa kita memerlukan bahasa pemrograman ?
2. Berikan penjelasan dari istilah - istilah berikut :
a. Kompilator
b. Translator
c. Interpreter
d. Assembler
e. Emulator
3. Berikan beberapa contoh produk yang ada dipasaran untuk setiap istilah pada
nomor 2.
4. Apa keuntungan dari penggunaan metode Bootsrap.
Jawab :
1. Alasan pentingnya bahasa pemrograman : Bahasa pemrograman digunakan
sebagai alat untuk berkomunikasi dengan komputer untuk menjalankan suatu
instruksi (program) tertentu, sehingga melalui bahasa pemrograman dapat
dihasilkan suatu sistem yang sederhana hingga sistem yang kompleks.
2. Artinya adalah :
10
3. Usability
Bahasa pemrograman harus mudah dipelajari dan diingat. Sekali seorang
pemrogram familiar dengan bahasa itu, dia tidak harus melihat manual terus -
menerus. Usability berkaitan dengan aspek kenyamanan seorang pemrogram
menggunakan bahasa.
4. Efektifitas pemrograman
Efektifitas pemrograman berkaitan erat dengan kemudahan dalam proses
pembuatan program. Bahasa pemrograman yang case sensitive akan mempunyai
tingkat efektifitas yang lebih rendah dibandingkan dengan bahasa pemrograman
yang non case sensitive
5. Compilability
Pengembangan sebuah kompilator merupakan pekerjaan yang tidak sederhana.
Sebuah bahasa yang terlalu kompleks akan menyulitkan pembuatan kompilator
untuk bahasa tersebut. Kompleksitas tersebut bisa muncul baik pada tahapan
analisis maupun sintaksis. Sebagai contoh yang sederhana adalah penggunaan
buka kurung dan tutup kurung, yang bisa digunakan untuk banyak kegunaan.
1. Untuk membatasi argumen pada pemanggilan prosedur
2. Untuk membatasi parameter pada definisi prosedur
3. Ekspresi logika
4. dll
6. Efisiensi
Efisiensi merupakan bahasan yang penting dalam sejarah pengembangan bahasa
pemrograman. Dalam hal ini perlu diingat bahwa tidak seharusnya user
dikorbankan dengan memaksa mereka mengeluarkan uang untuk peningkatan
perangkat keras.
7. Machine Independent
Sebuah bahasa dikatakan machine independent jika dan hanya jika sebuah
program yang telah sukses dikompilasi dan dieksekusi pada suatu mesin, saat
dipindahkan ke mesin lainnya akan berjalan dengan input dan output yang tepat
sama
8. Kesederhanaan (simpiclicty)
Suatu bahasa pemrograman harus dirancang secara sederhana, seperti menyangkut
pendeklarasian variabel, pemakaian suatu fungsi, ataupun untuk mengakses suatu
13
properti pada suatu bahasa. Bahasa pemrograman visual basic misalnya memiliki
konsep keserhanaan dalam artian untuk pendeklrasian variabel.
Detail Rancangan
Microstructure
Microstructure pada dasarnya mencakup masalah - masalah dalam perancangan
bahasa yang mempengaruhi penampilan bahasa sehingga lebih mudah dimengerti.
Prinsip mendasar dari suatu microstructure adalah arti dari suatu konstruksi, seperti
keyword, harus jelas dari wujudnya. Dengan kata lain, token suatu bahasa harus
mudah dikenali apakah itu dan apa yang dilakukan.
Keyword harus bisa diucapkan, karena akan lebih mudah diingat. Keyword harus
dipilih sedemikian sehingga tidak akan sama dengan identifier yang dibuat user.
Misalkan saja gunakan operator SIZE ketimbang SIZ. Jika mungkin jangan
gunakan dua keyword yang memiliki ejaan yang mirip (misal PROGEND dengan
PROCEND). Terdapat tiga pendekatan bagaimana memisahkan keyword dengan
identifier yang didefinisikan user :
1. Keyword adalah reserved dan tidak boleh digunakan sebagai identifier
Merupakan alternatif terbaik karena sederhana dan jarang menimbulkan masalah.
2. Keyword dibedakan dari identifier berdasarkan konteksnya
Menyulitkan pada tahap parser, karena jumlah keyword pada beberapa
implementasi begitu besar sehingga user tidak dapat menghindarinya.
3. Keyword diawali dengan karakter khusus untuk menandainya
Memerlukan tambahan pengetikan dan membuat program lebih susah dibaca.
Aspek lain dari Microstructure adalah pengaturan komentar. Salah satu pendekatan
dalam yang digunakan adalah dengan menggunakan suatu simbol untuk menandai
awal komentar dan kemudian apapun sampai akhir baris dianggap sebagai komentar.
Pemilihan simbol yang mendahului komentar idealnya :
1. Simbol terdiri dari dua karakter, lebih baik karakter yang sama
2. Simbol yang jarang dipergunakan
3. Terdiri dari karakter berlokasi sama pada keyboard
Contohnya simbol // adalah pilihan yang baik untuk menandai komentar.
14
Struktur Ekspresi
Salah satu topik yang berhubungan dengan ekspresi adalah urutan dari evaluasinya.
Seperti dalam operasi aritmatika memiliki urutan evaluasi :
1. Operator ( dan operator )
2. Operator * dan /
3. Operator + dan -
Struktur Data
Empat aspek dari struktur data adalah :
1. Deklarasi Data
Biasanya kebutuhan bahasa pemrograman berkaitan dengan deklarasi untuk :
a. Konstanta
b. Tipe
c. Variabel
2. Tipe Data
Terdapat tiga pendekatan untuk tipe data dalam bahasa pemrograman :
a. Tidak ada sama sekali. Merupakan karakteristik yang ada pada bahasa
assembly
b. Soft Typing. Ditentukan suatu jenis tipe, di mana setiap variabel boleh
memuat nilai apapun.
c. Hard typing. Ditentukan suatu jenis tipe, di mana setiap variabel hanya boleh
memuat nilai yang menjadi domain dari tipe tersebut. Dari sudut pandang
pemeriksaan kesalahan saat kompilasi hard typing lebih unggul.
Struktur Kontrol
Sering dipakai dengan menggunakan If then else dan juga perintah Case.
Struktur Kompilasi
Struktur kompilasi mencakup aspek dari bahasa yang berkaitan dengan proses
kompilasi, berhubungan dengan operasi pada bahasa yang dikerjakan saat kompilasi dan
bagaimana kompilasi modul yang berbeda dan terpisah dari program. Salah satu fasilitas
adalah untuk menyisipkan suatu file lain (seperti include pada bahasa C ataupun uses
pada bahasa Pascal).
15
Pendahuluan
Teknik Kompilasi merupakan mata kuliah yang khusus ditujukan kepada mahasiswa
jurusan Teknik Informatika dan Ilmu Komputer. Adapun sejumlah sasaran dari
mempelajari mata kuliah Teknik Kompilasi ini diantaranya adalah :
1. Mahasiswa diharapkan mampu memahami prinsip kerja yang mendasar dari suatu
kompiler.
2. Mengetahui tahapan - tahapan dari suatu proses kompilasi.
3. Mahasiswa juga diharapkan mempunyai bekal mendasar untuk mengembangkan
ilmu pengetahuan yang dimilikinya ke tingkat yang lebih lanjut.
Bahasa Pemrograman
Manusia dapat melakukan interaksi secara efektif dengan menggunakan media
bahasa. Bahasa memungkinkan penyampaian gagasan dan pemikiran, tanpa itu
komunikasi akan sulit terjadi. Dalam lingkungan pemrograman komputer, bahasa
pemrograman bertindak sebagai sarana komunikasi antara manusia dan
permasalahannya dengan komputer yang dipakai untuk membantu memperoleh
pemecahan.
Berikut ini adalah program pada Bahasa Pemrograman Visual Basic untuk mengenali
apakah suatu input itu huruf atau tidak.
Private Sub Form_Load()
a = InputBox("Masukkan Input:")
For i = 1 To Len(a)
d = Mid(a, i, 1)
If (d >= "A" And d <= "Z") Or (d >= "a" And d <= "z") Then
Debug.Print "Huruf"
Else
Debug.Print "Bukan Huruf"
End If
Next i
End Sub
End If
Next i
End Sub
if (isalpha(ekspresi[i]))
printf("Adalah huruf\n");
else
printf("Bukan Huruf\n");
}
getch();
}
Versi II :
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main()
{
clrscr();
char ekspresi[100];
int kar;
int i;
printf("Masukkan Ekspresi:");
scanf("%s",&ekspresi);
for(i=0;i<strlen(ekspresi);i++)
{
kar=ekspresi[i];
if (((kar>=65) && (kar<=90)) || ((kar>=97) && (kar<=122)))
printf("Adalah huruf\n");
else
printf("Bukan Huruf\n");
}
getch();
}
Next i
End Sub
Cara lain :
Private Sub Form_Load()
a = InputBox("Masukkan Input:")
For i = 1 To Len(a)
d = Mid(a, i, 1)
If (d >= "0" And d <= "9") Then
Debug.Print "Angka"
Else
Debug.Print "Bukan Angka"
End If
Next i
End Sub
Versi :
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main()
{
clrscr();
char ekspresi[100];
int kar;
int i;
printf("Masukkan Ekspresi:");
scanf("%s",&ekspresi);
for(i=0;i<strlen(ekspresi);i++)
{
kar=ekspresi[i];
if ((kar>=48) && (kar<=57))
printf("Angka\n");
else
21
printf("Bukan Angka\n");
}
getch();
}
Analisis Leksikal
Tugas utama penganalisis leksikal / Scanner adalah mengidentifikasi semua besaran
yang membangun suatu bahasa pada program sumber. Scanner adalah bagian dari
kompilator yang menerima input berupa stream karakter kemudian memilah program
sumber menjadi satuan leksik yang disebut dengan token. Token ini akan menjadi
input bagi parser.
Pekerjaan yang dikerjakannya antara lain :
1. Melakukan pembacaan kode sumber dengan merunut karakter demi karakter. 2.
Mengenali besaran leksik.
3. Membuang komentar : Komentar biasanya ditulis oleh programmer untuk
mempermudah dalam mempelajari program yang dibuat. Dalam setiap bahasa
pemrograman selalu disediakan simbol untuk mengawali / mengakhiri komentar.
Oleh karena itu scanner pada analisis leksikal ini harus dapat mengenali bagian
awal dan akhir setiap komentar supaya dapat dibuang atau tidak ikut dalam proses
kompilasi.
4. Menyeragamkan huruf kapital menjadi huruf kecil atau sebaliknya : Untuk bahasa
bahasa - bahasa pemrograman yang bersifat non - case sensitive, identifier
arraySize dan arraysize dianggap sama. Oleh karena itu, bagian penganalisis
leksikal bertugas menyeragamkan jenis huruf agar identifier semacam itu tidak
dianggap berbeda.
5. Membuang spasi
6. Menangani kesalahan
Besaran Leksik
Besaran pembangun bahasa / leksik meliputi :
1. Identifier
Bisa berupa keywords atau nama. Keywords adalah kata kunci yang sudah
didefinisikan oleh suatu bahasa seperti Begin, End, If, dan Else di dalam Pascal.
Nama dideklarasikan sendiri oleh pemakai seperti nama pada sebuah variabel.
Misal :
22
Var
Nama : Integer;
Suhu : Real;
2. Nilai Konstanta
Adalah suatu konstanta yang terdapat pada program. Bisa berupa konstanta
integer, real, boolean, character, string, dan sebagainya.
Misal :
Const
N := 10;
Kata := Saya
3. Operator dan Delimiter
Operator misalnya +, -, *, dan /.
Menghilangkan Blank
Dalam pengetikan suatu program, terkadang sering terjadi adanya banyak blank yang
tidak diperlukan. Salah satu dari tugas scanner atau lexical analyzer ini adalah untuk
mengabaikan blank yang dimaksud. Sebagai contoh adalah :
C=A + B
Maksud dari pernyataan di atas, adalah C = A + B.
Jika pernyataan semacam itu tidak diantisipasi oleh compiler maka pernyataan ini
tidak akan dapat dieksekusi, karena tidak dimengerti oleh compiler.
Berikut ini adalah program untuk menghilangkan blank.
Private Sub Form_Load()
c = InputBox("Masukkan Ekspresi:")
d = ""
flag = False
For i = 1 To Len(c)
If Mid(c, i, 1) = " " Then
If flag = False Then
d = d + Mid(c, i, 1)
End If
flag = True
Else
d = d + Mid(c, i, 1)
flag = False
End If
23
Next i
Debug.Print d
End Sub
clrscr();
char ekspresi[100];
char kalimat[100];
int kar;
int i;
int hitung;
int flag;
hitung=0;
flag=0;
printf("Masukkan Ekspresi:");
gets(ekspresi);
for(i=0;i<strlen(ekspresi);i++)
{
if (ekspresi[i]==' ')
{
if (flag==0)
{
kalimat[hitung]=ekspresi[i];
hitung=hitung+1;
}
flag=1;
}
else
{
kalimat[hitung]=ekspresi[i];
hitung=hitung+1;
flag=0;
}
}
for(i=0;i<hitung;i++)
printf("%c",kalimat[i]);
getch();
}
Pemakaian Procedure
1. Pada Pascal
Pada Pascal pengiriman parameter dapat dilakukan dengan dua cara yaitu :
a. Pengiriman parameter secara nilai
Jika nilai parameter pada prosedur diubah tidak akan mempengaruhi nilai
parameter nyata.
25
hitung(x,y);
writeln('Nilai variabel x=',x);
readln;
end.
3. Pada Bahasa C
# include <stdio.h>
# include <conio.h>
void hitung(int panjang,int lebar);
void main()
{
int a,b;
clrscr();
printf("Masukkan Panjang :");
27
scanf("%i",&a);
printf("Masukkan Lebar:");
scanf("%i",&b);
hitung(a,b);
getch();
}
Pemakaian Fungsi
Berikut ini adalah contoh pemakaian fungsi pada Turbo Pascal
1. Fungsi Tanpa parameter
uses crt;
Function garis:string;
begin
garis:='----------------';
end;
begin
writeln(garis);
writeln('Pascal');
writeln(garis);
readln;
end.
var
p,l:integer;
begin
clrscr;
28
Berikut ini adalah program untuk Memisahkan suatu input menjadi bagian -
bagiannya :
Dengan menggunakan bahasa pascal :
uses crt;
var
Kalimat:string;
i,n:integer;
pos:array[1..100]of integer;
posisi:integer;
kar:array[1..100] of string;
token:array[1..100] of string;
karb:string;
begin
clrscr;
posisi:=1;
karb:='';
write('Masukkan sebuah kalimat:');
readln(kalimat);
kalimat:=kalimat+' ';
for i:=1 to length(kalimat) do
begin
if kalimat[i]<>' 'then
begin
karb:=karb+kalimat[i];
end
else if (kalimat[i]=' ') then
Begin
30
kar[posisi]:=karb;
karb:='';
posisi:=posisi+1;
end;
end;
for i:=1 to posisi-1 do
begin
write('Kata ke- ',i,' adalah ',kar[i]);
writeln;
end;
readln;
end.
Program untuk mengecek apakah input terdapat di dalam array identifier atau tidak.
Misal identifier itu terdiri dari kata If dan Then
Input yang dimasukkan adalah :
If nama= Anton then lakukan penyeleksian
Maka tampilan hasil program adalah sebagai berikut : If
termasuk identifier
Nama= bukan identifir
Anton bukan identifier
Then termasuk identifier
Lakukan bukan identifier
Penyeleksian bukan identifier.
posisi:=1;
hitung:=1;
karb:='';
write('Masukkan jumlah identifier:');
readln(jiden);
write('Masukkan sebuah kalimat:');
readln(kalimat);
kalimat:=kalimat+' ';
for i:=1 to length(kalimat) do
begin
if kalimat[i]<>' 'then
begin
karb:=karb+kalimat[i];
end
else if (kalimat[i]=' ') then
Begin
kar[posisi]:=karb;
karb:='';
posisi:=posisi+1;
end;
end;
writeln('Posisi=',posisi);
for i:=1 to jiden do
begin
write('Masukkan identifier:');
readln(iden[i]);
end;
for i:=1 to posisi-1 do
begin
for j:=1 to jiden do
begin
if kar[i]<>iden[j] then
begin
if hitung=jiden then
begin
writeln('Kata ',kar[i],' Bukan Termasuk
Identifier');
end;
hitung:=hitung+1;
32
end
else
begin
writeln('Kata ',kar[i],' Termasuk Identifier');
hitung:=1;
j:=jiden;
end;
end;
hitung:=1;
end;
readln;
end.
Pembuatan Unit
Sebelum kita mempelajari penggunaan unit, maka ada baiknya program yang udah
dibuat, kita jadikan menggunakan Function ataupun Procedure.
Pada soal sebelumnya untuk pemisahan suatu kalimat menjadi bagian - bagian
pembentuknya dapat dibuat menjadi sebuah procedure seperti yang tampak pada
program di bawah ini.
uses crt;
procedure pisah(var a:string);
var
i,n,posisi:integer;
kar,token:array[1..20] of string;
karb:string;
begin
posisi:=1;
karb:='';
a:=a+' ';
Begin
kar[posisi]:=karb;
karb:='';
posisi:=posisi+1;
end;
end;
for i:=1 to posisi-1 do
begin
write('Kata ke- ',i,' adalah ',kar[i]);
writeln;
end;
end;
var
Kalimat:string;
begin
clrscr;
write('Masukkan sebuah kalimat:');
readln(kalimat);
pisah(kalimat);
readln;
end.
if a[i]<>' 'then
begin
karb:=karb+a[i];
end
else if (a[i]=' ') then
Begin
kar[posisi]:=karb;
karb:='';
posisi:=posisi+1;
end;
end;
for i:=1 to posisi-1 do
begin
write('Kata ke- ',i,' adalah ',kar[i]);
writeln;
end;
end;
end.
Analisis Sintaks
Sintaks adalah susunan kalimat dan aturan - aturan dalam membentuk kalimat disebut
grammar. Penganalisis sintaks dalam bidang kompilasi sering disebut dengan parser.
Program untuk mengecek bagian paling kiri dari suatu variabel yang harus berupa
huruf.
uses crt;
var
variabel : String;
begin
clrscr;
write('Masukkan variabel:');
readln(variabel);
if ((ord(variabel[1])>=65) and (ord(variabel[1])<=91))
or((ord(variabel[1])>=97) and (ord(variabel[1])<=122)) then
writeln('Variabel Benar')
else
writeln('Karakter pertama harus berupa huruf');
readln;
end.
Program untuk mengecek karakter kedua dan seterusnya dari suatu variabel yang
harus berupa huruf
uses crt;
var
variabel : String;
posisi,i:integer;
flag:boolean;
begin
clrscr;
write('Masukkan variabel:');
readln(variabel);
flag:=true;
for i:=2 to length(variabel) do
begin
if variabel[i]=':' then
posisi:=i;
end;
for i:=2 to posisi-1 do
begin
36
Cara untuk mengetahui apakah tipe data yang kita masukkan merupakan tipe data
yang ada dalam suatu kompiler atau tidak.
uses crt;
var
37
variabel : String;
tdata:string;
tipe:array[1..100] of string;
posisi,i,jlh_tipe:integer;
flag:boolean;
begin
clrscr;
flag:=false;
write('Masukkan variabel:');
readln(variabel);
write('Masukkan tipe data yang dikenali:');
readln(jlh_tipe);
for i:=1 to jlh_tipe do
begin
write('Masukkan tipe data ke-[',i,']:');
readln(tipe[i]);
end;
for i:=1 to length(variabel) do
begin
if variabel[i]=':' then
posisi:=i;
end;
if flag=true then
writeln('Tipe data yang anda masukkan yaitu ',tdata, ' Sudah
terdaftar')
else
writeln('Periksa kembali tipe data Anda yaitu ',tdata);
readln;
end.
38
Untuk perbandingan ada baiknya tipe data Anda terlebih dahulu dikonversi menjadi
huruf besar semua.
uses crt;
var
variabel : String;
tdata,tdatab,tampung,tampungb:string;
tipe,tipeb:array[1..100] of string;
posisi,i,jlh_tipe,j:integer;
flag:boolean;
begin
clrscr;
flag:=false;
write('Masukkan variabel:');
readln(variabel);
write('Masukkan tipe data yang dikenali:');
readln(jlh_tipe);
for i:=1 to jlh_tipe do
begin
write('Masukkan tipe data ke-[',i,']:');
readln(tipe[i]);
end;
for i:=1 to length(variabel) do
begin
if variabel[i]=':' then
posisi:=i;
end;
tampung:='';
tampungb:='';
end;
for i:=1 to jlh_tipe do
begin
writeln(tipeb[i]);
end;
for i:=1 to jlh_tipe do
begin
if tdatab=tipeb[i] then
flag:=true;
end;
if flag=true then
writeln('Tipe data yang anda masukkan yaitu ',tdata, ' Sudah
terdaftar')
else
writeln('Periksa kembali tipe data Anda yaitu ',tdata);
readln;
end.
Penggunaan File
Dalam perancangan suatu kompiler, sering digunakan suatu file untuk menyimpan
source code yang diketikkan oleh user. User mengetikkan program mereka kemudian
barulah program tersebut dikompilasi. Cara yang hampir mirip diterapkan pada
bahasa pemrograman Java. Pada bahasa pemrograman Pascal ada dua tipe teks yaitu :
1. File Teks
2. File Bertipe
Kedua jenis file ini mempunyai cara pemakaian yang berbeda. File bertipe lebih
mudah dipakai, namun kita tidak dapat mengetikkan source program secara langsung
pada suatu teks editor.
File Bertipe
File bertipe untuk memasukkan data :
Uses crt;
Type
Mahasiswa=record
40
Nomor : integer;
Nama: String;
Nilai: String;
End;
Var
FileMahasiswa:File of Mahasiswa;
RecordMahasiswa: Mahasiswa;
I,n:Byte;
Begin
Assign ( FileMahasiswa,'MHS.txt');
Rewrite ( FileMahasiswa );
Clrscr;
Write('Ketikkan Banyak Mahasiswa:');
Readln(n);
For i:= 1 to n do
Begin
Writeln('Mahasiswa ke-',i);
Write('Nomor:');
Readln(RecordMahasiswa.Nomor);
Write('Nama:');
Readln(RecordMahasiswa.Nama);
Write('Nilai:');
Readln(RecordMahasiswa.Nilai);
Write(FileMahasiswa,RecordMahasiswa);
Writeln;
End;
Close ( FileMahasiswa );
End.
RecordMahasiswa : Mahasiswa;
i:integer;
begin
Assign (FileMahasiswa,'Mhs.txt');
reset(FileMahasiswa);
clrscr;
writeln('-----------------------------');
writeln('Nomor ');
writeln('Mhs Nama Mahasiswa Nilai');
writeln('-----------------------------');
while not eof(filemahasiswa) do
begin
read(FileMahasiswa,RecordMahasiswa);
with RecordMahasiswa do
writeln(Nomor:2,Nama:10,Nilai:14);
end;
writeln('------------------------------');
readln;
close(FileMahasiswa);
end.
begin
read(filemahasiswa,recordmahasiswa);
if(recordmahasiswa.nomor=cari) then
begin
ketemu:=true;
writeln('nama Mahasiswa:',recordmahasiswa.nama);
writeln('Nilai Mahasiswa:',recordmahasiswa.nilai);
end;
end;
readln;
end.
File Teks
File Teks untuk memasukkan data:
Uses crt;
Var
BerkasTeks : Text;
KodeBrg : String;
NamaBrg : String;
UnitBrg : string;
HargaBrg:String;
lagi,jawab : char;
sudahada : Boolean;
Begin
Assign ( berkasteks,'Dataku.txt');
sudahada:=(ioresult=0);
if sudahada then
begin
jawab:=' ';
while not((jawab='Y') or (jawab='T')) do
begin
write(chr(7));
write('File sudah pernah ada, tumpangi
!!!!(Y/T) ?');
readln(Jawab);
jawab:=upcase(jawab);
end;
if jawab='T' then halt;
end;
rewrite(BerkasTeks);
43
lagi:='Y';
while upcase(lagi)='Y' do
begin
clrscr;
gotoxy(5,6);
write('Kode Barang :');
gotoxy(5,8);
write('Nama Barang :');
gotoxy(5,10);
write('Unit Barang:');
gotoxy(5,12);
write('Harga Satuan Barang :');
gotoxy(27,6); Readln(KodeBrg);
gotoxy(27,8); Readln(NamaBrg);
gotoxy(27,10); Readln(UnitBrg);
gotoxy(27,12); Readln(HargaBrg);
writeln(BerkasTeks,kodebrg);
writeln(BerkasTeks,namabrg);
writeln(BerkasTeks,unitbrg);
writeln(BerkasTeks,hargabrg);
gotoxy(5,15);
write('Ada Lagi?(Y/T)');
readln(lagi);
end;
close(berkasteks);
end.
End.
UnitBrg :string;
hargabrg:string;
I,n : byte;
Begin
Assign ( berkasteks,'Dataku.txt');
Reset ( berkasteks);
Clrscr;
Writeln('--------------------------------------------');
writeln(' Kode Unit harga
');
writeln(' Brg Nama Barang Akhir
Satuan');
writeln('--------------------------------------------
---------');
While not EOF ( berkasteks ) do
Begin
Readln(
berkasteks,kodebrg,namabrg,unitbrg,hargabrg);
write(kodeBrg,' ',namaBrg,'
',unitbrg,' ',hargabrg);
end;
close ( BerkasTeks );
readln;
end.
reset(berkasteks);
clrscr;
write('Kode Barang dicari ?');
readln(kodecari);
writeln;
while(not eof(berkasteks)) and (kodebrg<>kodecari) do
readln(berkasteks,kodebrg);
readln(berkasteks,namabrg);
readln(berkasteks,unitbrg);
readln(berkasteks,hargabrg);
if kodebrg=kodecari then
begin
writeln('kode barang:',kodeBrg);
writeln('Nama barang:',namaBrg);
writeln('unit barang:',unitBrg);
writeln('harga barang:',hargaBrg);
end
else
writeln('Tidak ada data barang ini !!!');
close(berkasteks);
writeln;
writeln('Ada Lagi data yang akan dicari (Y/T)');
readln(lagi);
end;
readln;
end.
Soal :
Buatlah program untuk memisahkan pendeklarasian variabel yang jumlahnya lebih
dari satu.
Contoh : Panjang,lebar,luas:integer
Dipisahkan menjadi :
Variabel 1 : Panjang
Variabel 2 : Lebar
Variabel 3 : Luas
Jawab :
uses crt;
var
variabel : String;
tdata:string;
posisi,i:integer;
48
pkar:integer;
kar:array[1..100] of string;
karb:string;
begin
clrscr;
write('Masukkan variabel:');
readln(variabel);
tdata:=tdata+',';
pkar:=1;
karb:='';
end;
for i:=1 to pkar-1 do
begin
write('variabel ke- ',i,' adalah ',kar[i]);
writeln;
end;
49
readln;
end.
Pemakaian Procedure
uses crt;
procedure cek(tdata:string);
var
i:integer;
pkar:integer;
kar:array[1..20] of string;
karb:string;
begin
tdata:=tdata+',';
pkar:=1;
karb:='';
end;
for i:=1 to pkar-1 do
begin
write('variabel ke- ',i,' adalah ',kar[i]);
writeln;
end;
end;
var
variabel : String;
i,posisi:integer;
tdata:string;
50
begin
clrscr;
write('Masukkan variabel:');
readln(variabel);
for i:=1 to length(variabel) do
begin
if variabel[i]=':' then
posisi:=i;
end;
Pemakaian Unit
Unit kompilasi.pas
unit kompilasi;
interface
procedure cek(tdata:string);
implementation
uses crt;
procedure cek(tdata:string);
var
i:integer;
pkar:integer;
kar:array[1..20] of string;
karb:string;
begin
tdata:=tdata+',';
pkar:=1;
karb:='';
end
else if (tdata[i]=',') then
Begin
kar[pkar]:=karb;
karb:='';
pkar:=pkar+1;
end;
end;
for i:=1 to pkar-1 do
begin
write('variabel ke- ',i,' adalah ',kar[i]);
writeln;
end;
end;
end.
Program Cek.pas
uses kompilasi,crt;
var
variabel : String;
i,posisi:integer;
tdata:string;
begin
clrscr;
write('Masukkan variabel:');
readln(variabel);
for i:=1 to length(variabel) do
begin
if variabel[i]=':' then
posisi:=i;
end;
nkonstanta:string;
posisi,i:integer;
flag:boolean;
begin
clrscr;
write('Masukkan deklarasi konstanta:');
readln(kons);
uses crt;
var
kons : String;
nkonstanta:string;
constan:string;
posisi,i:integer;
flag:boolean;
str:boolean;
begin
clrscr;
flag:=true;
constan:='';
write('Masukkan deklarasi konstanta:');
readln(kons);
55
if str=true then
begin
writeln('Nilai konstanta adalah :',constan);
if ((ord(nkonstanta[1])=39) and
(ord(nkonstanta[length(nkonstanta)])=39)) then
flag:=true
else
flag:=false;
end;
if flag=false then
writeln('konstanta salah')
else
writeln('konstanta sudah benar');
readln;
56
end.
Type Checking
Kompiler harus memeriksa apakah source program mengikuti konvensi sintaksis atau
semantik dari source language. Pemeriksaan ini disebut static checking, untuk
meyakinkan bahwa kesalahan programming akan dideteksi dan dilaporkan.
Intermediate
Token Syntax
Parser Type Code
Checker Generator
Misalkan pada kompiler yang kita rancang mempunyai kemampuan untuk mengenali
tipe data :
1. Char
2. String
3. Integer dengan jangkauan dari -32768 s/d 32767
4. LongInt dengan jangkauan dari -2147483648 s/d 2147483647
5. Real untuk bilangan desimal
Berikut ini adalah contoh penggunaan dari file untuk menyimpan tipe data yang kita
kenali pada suatu file. Langkah - langkahnya adalah sebagai berikut.
57
1. Buat program untuk membentuk file dengan nama tdata.dat untuk menyimpan tipe
data yang kita kenali
2. Buat program untuk menyimpan tipe data beserta dengan jangkauannya ke dalam
file tdata.dat yang telah kita buat sebelumnya.
while upcase(lagi)='Y' do
begin
clrscr;
gotoxy(5,6);
write('Tipe Data :');
gotoxy(5,8);
write('Jangkauan :');
gotoxy(27,6); Readln(tipe);
58
gotoxy(27,8); Readln(jangkauan);
writeln(BerkasTeks,tipeb);
writeln(BerkasTeks,jangkauan);
tipeb:=;
gotoxy(5,15);
write('Ada Lagi?(Y/T)');
readln(lagi);
end;
close(berkasteks);
end.
pendeklarasian variabel, dan lain - lain. Oleh karena itu, juga ada baiknya kalau kata
tercadang itu disimpan di dalam suatu file yang digunakan khusus untuk menampung
reserved word, misalkan nama file yang dimaksud adalah cadang.dat.
while upcase(lagi)='Y' do
begin
clrscr;
gotoxy(5,6);
write('Reserved Word :');
gotoxy(27,6); Readln(cadang);
writeln(BerkasTeks,cadangb);
cadangb:='';
60
gotoxy(5,15);
write('Ada Lagi?(Y/T)');
readln(lagi);
end;
close(berkasteks);
end.
Menyimpan variabel
Variabel di dalam perancangan suatu kompiler sering dianggap sebagai bagian di
dalam suatu program, atau dengan kata lain tidak diperlukan upaya untuk menyimpan
variabel tersebut ke dalam suatu file. Namun, untuk efisiensi di dalam program, ada
baiknya variabel tersebut di tempatkan ke dalam suatu file sehingga upaya untuk
mengeceknya dapat menjadi lebih mudah, terutama apabila variabel tersebut sering
digunakan di dalam program.
Berikut ini adalah contoh program untuk membuat file variabel.dat untuk menyimpan
nama variabel.
Uses crt;
Var
VF:text;
Begin
Assign ( VF,'C:\variabel.dat');
Rewrite ( VF );
Close ( VF );
End.
a. Cek tipe data yang ada apakah sudah sesuai dengan tipe data yang dikenali
pada program atau tidak
b. Cek apakah pada pengetikan deklarasi variabel sudah ada titik koma ( ; ) atau
tidak
c. Cek pengetikan variabel dengan kriteria :
- karakter pertama pada nama variabel harus berupa huruf
- nama variabel tidak boleh sama dengan reserved word
- panjang karakter maksimal adalah 32 karakter
- huruf kedua dan selanjutnya pada nama variabel harus berupa huruf
ataupun angka.
Berikut ini adalah program untuk menampilkan kembali isi source code yang telah
diketikkan dalam suatu array.
Uses Crt;
Var
BerkasTeks : Text;
kode:string;
arkode : array [1..100] of string; I,n
: byte;
Begin
n:=1;
i:=1;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
writeln(kode);
arkode[i]:=kode;
n:=n+1;
i:=i+1;
end;
close ( BerkasTeks );
Program untuk mengecek apakah pendeklarasian variabel terdapat keyword vari dan
tanda ; atau tidak.
Uses Crt;
Var
BerkasTeks : Text;
kode:string; {untuk menampung kode}
kodeb:string; {untuk menampung huruf besar dari kode}
arkode : array [1..100] of string; {untuk menampung kode dalam
{huruf besar}
I,n,j,posisi1,posisi2 : byte;
possalah:byte;
cekvar:string;
flag:boolean; {menampung status ;}
Begin
n:=1;
i:=1;
flag:=true;
possalah:=0;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
arkode[i]:=kodeb;
n:=n+1;
i:=i+1;
kodeb:='';
end;
close ( BerkasTeks );
63
Berikut ini adalah program untuk memisahkan variabel yang sudah kita definisikan di
dalam file.
Uses Crt;
Var
BerkasTeks : Text;
kode,tvari,karb:string; {untuk menampung kode}
kodeb:string; {untuk menampung huruf besar dari kode}
arkode : array [1..100] of string; {untuk menampung kode dalam
{huruf besar}
l,I,o,n,j,posisi1,posisi2,pkar,k : byte;
cekvar:string;
variabel1:string; {untuk menampung bagian dklarasi variabel}
posisi:integer;
64
arvari:array[1..25] of string;
kar:array[1..25] of string;
vari:array[1..25] of string;
Begin
n:=1;
i:=1;
k:=1;
o:=1;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
arkode[i]:=kodeb;
n:=n+1;
i:=i+1;
kodeb:='';
end;
close ( BerkasTeks );
variabel1:=variabel1+cekvar[j];
arvari[o]:=variabel1;
variabel1:='';
o:=o+1;
end;
pkar:=1;
karb:='';
l:=1;
for i:=1 to o-1 do
begin
tvari:=tvari+arvari[i];
tvari:=tvari+',';
end;
writeln(tvari);
readln;
end.
66
Berikut ini adalah program untuk mengecek apakah variabel yang digunakan oleh user
sudah dideklarasikan atau belum.
Uses Crt;
Var
BerkasTeks : Text;
kode,tvari,karb:string; {untuk menampung kode}
kodeb:string; {untuk menampung huruf besar dari kode}
arkode : array [1..100] of string; {untuk menampung kode dalam
{huruf besar}
l,I,o,n,j,posisi1,posisi2,pkar,k : byte;
cekvar:string;
variabel1:string; {untuk menampung bagian dklarasi variabel}
posisi:integer;
arvari:array[1..25] of string;
kar:array[1..25] of string;
vari:array[1..25] of string;
flag:boolean;
Begin
n:=1;
i:=1;
k:=1;
flag:=true;
o:=1;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
arkode[i]:=kodeb;
n:=n+1;
i:=i+1;
kodeb:='';
end;
close ( BerkasTeks );
67
pkar:=1;
karb:='';
l:=1;
for i:=1 to o-1 do
begin
tvari:=tvari+arvari[i];
tvari:=tvari+',';
end;
writeln(tvari);
kar[pkar]:=karb;
karb:='';
pkar:=pkar+1;
end;
end;
end;
if o=((posisi2-1)-(posisi1+1)+1) then
writeln('semua variabel dikenal')
else
writeln('Ada variabel yang tidak dikenal');
readln;
end.
69
Berikut ini adalah program untuk mengecek apakah nama suatu variabel sama dengan
Reserved Word atau tidak.
Uses Crt;
Var
BerkasTeks : Text;
kode,tvari,karb:string; {untuk menampung kode}
kodeb:string; {untuk menampung huruf besar dari kode}
arkode : array [1..100] of string; {untuk menampung kode dalam
{huruf besar}
l,I,o,n,j,posisi1,posisi2,pkar,k : byte;
cekvar:string;
variabel1:string; {untuk menampung bagian dklarasi variabel}
posisi:integer;
arvari:array[1..25] of string;
kar:array[1..25] of string;
vari:array[1..25] of string;
flag:boolean;
Begin
n:=1;
i:=1;
k:=1;
o:=1;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
arkode[i]:=kodeb;
n:=n+1;
i:=i+1;
kodeb:='';
end;
close ( BerkasTeks );
begin
if arkode[i]='VARI' then
posisi1:=i;
if arkode[i]='END VARI' then
posisi2:=i;
end;
for I:=posisi1+1 to posisi2-1 do
begin
cekvar:=arkode[i];
for j:=1 to length(cekvar) do
begin
if cekvar[j]=':' then
posisi:=j;
end;
pkar:=1;
karb:='';
l:=1;
for i:=1 to o-1 do
begin
tvari:=tvari+arvari[i];
tvari:=tvari+',';
end;
writeln(tvari);
karb:='';
pkar:=pkar+1;
end;
end;
readln;
end.
Berikut ini adalah perancangan compiler untuk mengecek keberadaan komentar pada
suatu program (untuk yang lebih 1 baris).
Uses Crt;
Var
BerkasTeks : Text;
kode:string; {untuk menampung kode}
72
close ( BerkasTeks );
readln;
end.
Pada compiler yang kita rancang nantinya, maka apabila telah dibuat tanda {, harus
diakhiri dengan tanda }, karena jika tidak akan ditampilkan pesan kesalahan seperti yang
tampak pada contoh berikut.
Berikut ini adalah program untuk mengecek kesalahan akibat kurangnya tanda tutup
kurung kurawal (}).
Uses Crt;
Var
BerkasTeks : Text;
kode:string; {untuk menampung kode}
kodeb:string; {untuk menampung huruf besar dari kode}
arkode : array [1..100] of string; {untuk menampung kode dalam
{huruf besar}
I,n,j,posisi1,posisi2 : byte;
possalah:byte;
cekvar:string;
flag:boolean; {menampung status ;}
Begin
posisi1:=0;
posisi2:=0;
n:=1;
i:=1;
flag:=true;
possalah:=0;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
arkode[i]:=kodeb;
n:=n+1;
i:=i+1;
kodeb:='';
end;
74
close ( BerkasTeks );
Berikut ini adalah program untuk mengecek komentar yang hanya 1 baris (bisa
melekat pada source code). Dalam hal ini ditandai dengan *
Uses Crt;
Var
BerkasTeks : Text;
kode:string; {untuk menampung kode}
kodeb:string; {untuk menampung huruf besar dari kode}
arkode : array [1..100] of string; {untuk menampung kode dalam
{huruf besar}
I,n,j,posisi1,posisi2 : byte;
possalah:byte;
cekvar:string;
flag:boolean; {menampung status ;}
Begin
n:=1;
75
i:=1;
flag:=true;
possalah:=0;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
arkode[i]:=kodeb;
n:=n+1;
i:=i+1;
kodeb:='';
end;
kodeb:='';
posisi1:=1;
posisi2:=1;
for i:=1 to n-1 do
begin
kodeb:=arkode[i];
for j:=1 to length(kodeb) do
begin
if kodeb[j]='*' then
begin
posisi1:=j;
posisi2:=i;
end;
end;
end;
kodeb:='';
kodeb:=arkode[posisi2];
write('Isi komentar anda adalah: ');
for i:=posisi1+1 to length(kodeb) do
write(kodeb[i]);
readln;
end.
76
Berikut ini adalah program untuk menghilangkan spasi kosong pada bagian sebelah kiri
program.
Uses Crt;
Var
BerkasTeks : Text;
kode:string;
arkode : array [1..100] of string;
I,n,k,posisi: byte;
tampung:string;
kode1:string;
arkode1:array[1..100] of string;
flag:boolean;
Begin
n:=1;
i:=1;
flag:=false;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
arkode[i]:=kode;
n:=n+1;
i:=i+1;
end;
for i:=1 to n-1 do
begin
kode1:=arkode[i];
if kode1[1]=' 'then
begin
for k:=1 to length(kode1) do
begin
if ((kode1[k]<>' ') and (flag=false))
then
begin
posisi:=k;
flag:=true;
end;
end;
77
flag:=false;
for k:=posisi to length(kode1) do
begin
tampung:=tampung+kode1[k];
end;
end
else
begin
for k:=1 to length(kode1) do
begin
tampung:=tampung+kode1[k];
end;
end;
arkode1[i]:=tampung;
tampung:='';
kode1:='';
end;
for i:=1 to n-1 do
begin
writeln('isi kode baris ke -',i, ' adalah : ',arkode1[i]);
end;
close ( BerkasTeks );
readln;
end.
Selain proses penghilangan spasi di bagian kiri, terkadang ada bagian tertentu di
dalam program yang tidak mengizinkan adanya spasi, seperti bagian program yang ada
di dalam blok Vari dan End Vari.
Berikut ini adalah program untuk menghilangkan keseluruhan spasi yang ada di dalam
blok Vari dan End Vari.
Tabel Informasi
Tabel infromasi atau tabel simbol dibuat guna mempermudah pembuatan dan
implementasi dari semantyc analyzer. Tabel simbol ini mempunyai dua fungsi penting
dalam proses translasi, yaitu :
1. Untuk membantu pemeriksaaan kebenaran semantik dari program sumber.
2. Untuk membantu dan mempermudah dalam pembuatan intermediate code dan
proses pembangkitan kode.
78
Hal tersebut dilakukan dengan menambah dan mengambil atribut variabel yang
dipergunakan pada program dari tabel. Atribut tersebut, seperti nama, tipe, ukuran
variabel bisa ditemukan secara eksplisit pada deklarasi, atau secara implisit
berdasarkan konteks kemunculan nama variabel pada program.
Berikut ini adalah contoh untuk mengisikan suatu variabel ke dalam tabel Identifier.
(Catatan : dalam implementasi pengisian tabel identifier bisa diisikan gabung, apakah itu
variabel, konstanta, dll, ataupun diisikan pisah, seperti tabel identifier khusus untuk
variabel, konstanta, dll)
Uses Crt;
Var
BerkasTeks : Text;
teks:text;
kode,tvari,karb:string; {untuk menampung kode}
kodeb:string; {untuk menampung huruf besar dari kode}
arkode : array [1..100] of string; {untuk menampung kode dalam
{huruf besar}
l,I,o,n,j,posisi1,posisi2,pkar,k : byte;
cekvar:string;
variabel1:string; {untuk menampung bagian dklarasi variabel}
posisi:integer;
arvari:array[1..25] of string;
kar:array[1..25] of string;
vari:array[1..25] of string;
Begin
n:=1;
i:=1;
k:=1;
o:=1;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
arkode[i]:=kodeb;
n:=n+1;
i:=i+1;
kodeb:='';
end;
80
close ( BerkasTeks );
pkar:=1;
karb:='';
l:=1;
for i:=1 to o-1 do
begin
tvari:=tvari+arvari[i];
tvari:=tvari+',';
end;
writeln(tvari);
Teknik Optimasi
Tahapan optimasi kode bertujuan untuk menghasilkan kode program yang berukuran
lebih kecil dan lebih cepat eksekusinya. Berdasarkan ketergantungannya pada mesin,
optimasi dibagi menjadi :
1. Machine Dependent Optimizer
Kode dioptimasi sehingga lebih efisien pada mesin tertentu. Optimasi ini
memerlukan informasi mengenai feature yang ada pada mesin tujuan dan
mengambil keuntungan darinya untuk menghasilkan kode yang lebih pendek atau
dieksekusi lebih cepat.
2. Machine Independent Optimizer
Strategi optimasi yang bisa diaplikasikan tanpa tergantung pada mesin tujuan
tempat kode yang dihasilkan akan disekusi nantinya. Bagian ini selanjutnya akan
82
Optimasai Lokal
Optimasi lokal adalah optimasi yang dilakukan hanya pada suatu blok dari source
code, cara - caranya adalah :
1. Folding
Mengganti konstanta atau ekspresi yang bisa dievaluasi pada saat Compile Time
dengan nilai komputasinya. Misalkan instruksi :
A := 2 + 3 + B
Bisa diganti menjadi :
A := 5 + B
Di situ 5 menggantikan ekspresi 2+3
2. Redundant - Subexpression Elimination
Sebuah ekspresi yang sudah pernah dikomputasi, digunakan lagi hasilnya,
ketimbang melakukan komputasi ulang. Misalkan terdapat urutan instruksi :
A := B + C
X := Y + B + C
Kemunculan kedua dari B+C yang redundan bisa diatasi dengan memanfaatkan
hasil komputasinya yang sudah ada pada instruksi sebelumnya. Perhatikan, hal ini
bisa dilakukan dengan catatan belum ada perubahan pada variabel yang berkaitan. 3.
Optimasi dalam sebuah iterasi
Loop Unrolling : Menggantikan suatu loop dengan menulis statement dalam
loop beberapa kali. Hal ini didasari pemikiran, sebuah iterasi pada
implementasi level rendah akan memerlukan operasi :
Inisialisasi / pemberian nilai awal pada variabel loop. Dilakukan sekali
pada saat permulaan eksekusi loop.
Pengetesan, apakah variabel loop telah mencapai kondisi terminasi
Adjustment, yaitu penambahan atau pengurangan nilai pada variabel loop
dengan jumlah tertentu.
Operasi yang terjadi pada tubuh perulangan (Loop Body).
For I := 1 to 2 do
A [I] := 0;
Terdapat instruksi untuk inisialisasi I menjadi 1. Serta operasi penambahan
nilai / Increment 1 dan pengecekan nilai pada variabel I pada setiap
perulangan. Sehingga untuk perulangan saja memerlukan empat instruksi,
ditambah dengan instruksi assignment pada tubuh perkukangan.
Dapat dioptimasikan menjadi :
A[1]:=0;
A[2]:=0;
Kita lihat tidak terjadi perubahan / manipulasi pada variabel X di dalam iterasi,
karena itu kita bisa mengeluarkan instruksi tersebut ke luar iterasi, menjadi :
X := 5;
For I := 1 to 10 do
Begin
A:=A+I;
End;
4. Strength Reduction
Penggantian suatu operasi dengan jenis operasi lain yang lebih cepat dieksekusi.
Misalkan pada beberapa komputer operasi perkalian memerlukan waktu lebih
banyak untuk dieksekusi dari pada operasi penjumlahan, maka penghematan
waktu bisa dilakukan dengan mengganti operasi perkalian tertentu dengan
penjumlahan. Contoh lain, instruksi :
A := A+1;
Dapat digantikan dengan :
84
Inc (A);
Optimasi Global
Di sini hanya akan diterangkan sekilas mengenai optimasi global. Optimasi global
biasanya dilakukan dengan analisis Flow, yaitu suatu graph berarah yang
menunjukkan jaluar yang mungkin selama eksekusi program.
Kegunaannya :
a. Bagi pemrogram menginformasikan :
Unreachable / Dead Code : Kode yang tidak akan pernah dieksekusi.
Misalnya terdapat pada urutan instruksi :
X := 5;
If X = 0 Then
A:= A+1;
Instruksi A := A+1 tidak akan pernah dieksekusi
Unuser Parameter pada prosedur : Parameter yang tidak pernah digunakan di
dalam prosedur. Contohnya :
Procedure Jumlah (a,b,c:Integer);
Var X : Integer
Begin
X:=a+b;
End;
Kita lihat parameter c tidak pernah digunakan di dalam prosedur, sehingga
seharusnya tidak perlu diikutsertakan.
Unuser Variabel : Variabel yang tidak pernah dipakai dalam program.
Contohnya :
Program pendek;
Var a,b : Integer;
Begin
A:=5;
End;
Variabel yang dipakai tanpa nilai awal. Contohnya :
Program Awal;
Var a,b : Integer;
Begin
a:=5;
a:=a+b;
85
end;
Kita lihat variabel b digunakan tanpa memiliki nilai awal / belum di-assign
b. Bagi kompilator :
Meningkatkan efisiensi eksekusi program
Menghilangkan useless code / kode yang tidak terpakai.
Latihan :
1. Lakukan optimisasi lokal yang diperlukan pada potongan program berikut, dan
jelaskan optimasi apa saja yang diterapkan :
A := B + 10 * 4
C := B + D;
F := B + D - G;
For I := 1 to 100 do
Begin
X := X+I;
A := A+X;
B := 7;
End;
2. Apakah kita dapat melakukan optimasi Redundant Sub Expression Elimination
pada statement berikut, mengapa ?
a.
A := B + C;
A := X + Y;
F := B + C + G + H;
b.
A := B + C;
B := X + Y;
F := B + C + G + H;
3. Bisakah kita melakukan optimasi frequency reduction pada loop berikut :
10 For I := 1 to 10 do
20 A := I+1;
30
Mengapa kita tidak dapat melakukan optimasi pada instruksi baris ke 20 ? 4.
Lakukan optimasi global sederhana pada program berikut.
Program Test;
Var A, B, C : Integer;
Begin
B := 5;
86
While B < 3 do
B := B+1;
C := 10+B;
End.
Jawaban :
1.
A := B + 10 * 4 A := B + 40 (Folding)
C := B + D; C := B + D
F := B + D - G; F := C - G (Redundant Sub Expression
Elimination)
For I := 1 to 100 do B := 7;
Begin For I := 1 to 100 do
X := X+I; Begin
A := A+X; X := X + I;
B := 7; A := A + X;
End; End; (Frequency Reduction)
2.
a. Tidak bisa karena A sudah bukan B + C lagi (X + Y)
b. Tidak bisa karena nilai B sudah berubah
3.
Tidak bisa karena nilai A selalu berubah seiring berubahnya nilai I
4.
Hilangkan saja variabel A, karena variabel A tidak pernah digunakan.
2. Apakah fungsi yang ada merupakan fungsi yang dikenali atau tidak dalam suatu
compiler. Oleh karena itu, biasanya dilakukan pengecekan terhadap file reserved
word yang ada di dalam suatu compiler.
3. Berdasarkan hasil pengecekan tersebut kemudian akan dilakukan pengecekan
terhadap fungsi instruksi yang dimaksud.
arvari:array[1..25] of string;
kar:array[1..25] of string;
vari:array[1..25] of string;
flag:boolean;
Begin
n:=1;
i:=1;
k:=1;
o:=1;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
arkode[i]:=kodeb;
n:=n+1;
i:=i+1;
88
kodeb:='';
end;
close ( BerkasTeks );
begin
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
if arvari[i]=kodeb then
posisi:=posisi1;
kodeb:='';
end;
posisi1:=posisi1+1;
end;
if posisi=4 then
writeln('Ini adalah fungsi untuk mencetak tulisan');
readln;
end.
Respon - respon di atas merupakan tingkatan terendah, dan bisa muncul pada
kompilator yang dirancang tanpa mempertimbangkan kemungkinan kompilator
memproses source code yang mengandung kesalahan.
2. Reaksi yang benar tetapi kurang dapat diterima dan kurang bermanfaat
Kompilator menemukan kesalahan pertama, melaporkannya, lalu berhenti (halt).
Ini bisa muncul bila pembuat kompilator menganggap jarang terjadi kemunculan
error dalam program. Sehingga kemampuan kompilator untuk mendeteksi dan
melaporkan kesalahan hanya satu untuk setiap kali kompilasi. Pemrogram akan
membuang waktu untuk melakukan pengulangan kompilasi setiap kali terdapat
sebuah error.
3. Reaksi - reaksi yang dapat diterima
Reaksi yang dapat diterima adalah bila setelah kompilator menemukan kesalahan
melaporkan baris ke berapa kesalahan tersebut terjadi, memperbaikinya, dan
kemudian melanjutkan lagi pemeriksaan ke baris yang berikutnya.
Contoh program berikut akan menambahkan karakter ; pada bagian program yang
tidak memiliki ;
Jawab :
Uses Crt;
Var
BerkasTeks : Text;
teks:text;
kode:string; {untuk menampung kode}
kodeb:string; {untuk menampung huruf besar dari kode}
arkode : array [1..100] of string; {untuk menampung kode dalam
{huruf besar}
I,n,j,posisi1,posisi2 : byte;
possalah:byte;
93
cekvar:string;
flag:boolean; {menampung status ;}
Begin
n:=1;
i:=1;
flag:=true;
possalah:=0;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
arkode[i]:=kodeb;
n:=n+1;
i:=i+1;
kodeb:='';
end;
close ( BerkasTeks );
end;
if flag=true then
writeln('ada titik koma')
else
writeln('tidak ada titik koma pada baris ke-',possalah);
arkode[possalah]:=arkode[possalah]+';';
kodeb:='';
Assign ( teks,'C:\variabel.dat');
rewrite(teks);
writeln('Kode program setelah diperbaiki adalah :'); for
i:=1 to n do
writeln(arkode[i]);
for i:=1 to 3 do
begin
kodeb:=arkode[i];
writeln(teks,arkode[i]);
kodeb:='';
end;
close(teks);
readln;
end.
Berikut ini adalah contoh program untuk memperbaiki kesalahan pengetikan pada
suatu nama identifier (Misal While - Do), dengan format penulisan yang benar
adalah:
While
Do
95
Jawab :
Uses Crt;
Var
BerkasTeks : Text;
teks:text;
kode:string; {untuk menampung kode}
kodeb:string; {untuk menampung huruf besar dari kode}
arkode : array [1..100] of string; {untuk menampung kode dalam
{huruf besar}
I,n,j,posisi1,posisi2 : byte;
possalah:byte;
cekvar:string;
jawab:char;
flag:boolean; {menampung status ;}
Begin
clrscr;
n:=1;
i:=1;
j:=1;
flag:=true;
possalah:=0;
Assign ( berkasteks,'c:\variabel.dat');
Reset ( berkasteks);
Clrscr;
While not EOF ( berkasteks ) do
Begin
Readln( berkasteks,kode);
for j:=1 to length(kode) do
kodeb:=kodeb+upcase(kode[j]);
arkode[i]:=kodeb;
n:=n+1;
i:=i+1;
kodeb:='';
end;
close ( BerkasTeks );
if arkode[i]='DO' then
posisi2:=i;
end;
If posisi2=posisi1+2 then
flag:=true
else
flag:=false;
writeln('Kode anda adalah :');
for i:=1 to n-1 do
writeln(arkode[i]);
if flag=false then
begin
writeln('Kode Anda tidak ada Do :');
Writeln('Seharusnya pada baris: ',posisi1+2,' adalah do');
Writeln('Apakah Anda mau timpa?(Y/T)');
readln(jawab);
end;
Kerugian dari kode antara, dengan melakukan dua kali translasi, maka butuh waktu
yang relatif lebih lama.
Notasi Postfix
Sehari - hari kita biasa menggunakan operasi dalam notasi infix (letak operator di
tengah). Pada notasi Postfix operator diletakkan paling akhir maka disebut juga
dengan notasi Sufix atau reverse polish. Sintax notasi Postfix :
<Operand> <Operand> <Operator>
Misalkan ekspresi :
A+b
Kalau kita nyatakan dalam postfix :
Ab+
Adapun prioritas pengerjaan suatu operator adalah sebagai berikut.
1. ( atau )
2. * atau :
3. + atau -
Untuk mengubah dari suatu notasi infix menjadi suatu notasi postfix dapat kita
lakukan dengan menggunakan suatu tumpukan, yang memiliki aturan :
1. Jika ada operator yang masuk ke dalam stack maka operand yang ada harus
dikeluarkan.
98
2. Jika operator yang masuk ke dalam stack lebih kecil atau sama dengan operator
yang ada di dalam stack maka operator yang ada di dalam stack harus dikeluarkan.
3. Operator buka kurung tidak pernah dikenai operasi stack.
4. Jika tanda tutup kurung masuk, maka semua operator maupun operand yang
masuk akan dikeluarkan sebatas tanda buka kurung ke atas.
B
A + A + A
Contoh lain :
A+B*C
B
A + A + A
C ABC*+
*
+ AB
Contoh lain :
(A+B) * C
99
A +
( ( (
A
Soal :
Ubahlah bentuk berikut ke dalam bentuk notasi Postfix
1.
A*(B+C)
2. (A+(B+C)*D-E)
3. (A-C) +((B+D)*E)
Dalam implementasi ke kode antara, label bisa berupa nomor baris intruksi. Untuk
lebih jelasnya bisa dilihat contoh berikut.
IF a>b Then
C:=d
Else
C:=e
Contoh lain :
a:=1
While A<5 do
A:=a+1
Diubah ke Postfix :
10 a
11 1
12 :=
13 a
14 5
15 <
16 26
17 BZ
18 a
19 a
20 1
21 +
22 :=
23
24 13
25 br
26
Contoh lain :
a:=1
Repeat
B:=b+a
Until A<5
Diubah Ke Postfix :
10 a
11 1
12 :=
13 b
14 b
15 a
16 +
17 :=
18
19 a
102
20 a
21 1
22 +
23 :=
24
25 a
26 5
27 <
28 32
29 BZ
30 13
31 BR
32
Contoh lain :
For i := 1 to 5 do
a:=a+1
Diubah ke postfix :
10 i
11 1
12 :=
13 i
14 5
15 <=
16 32
17 BZ
18 a
19 a
20 1
21 +
22 :=
23
24 i
25 i
26 1
27 +
28 :=
29
30 13
31 BR
32
103
Notasi N - Tuple
Bila pada Postfix setiap baris intruksi hanya terdiri dari satu tupel, pada notasi N -
Tuple setiap baris bisa terdiri dari beberapa tupel. Format umum dari notasi N - Tuple
adalah :
Operator N - 1 Operand
Selanjutnya akan dibahas notasi 3 tupel dan 4 tupel
Triples Notation
Notasi tripel memiliki format
<Operator> <Operand> <Operand>
Contoh, instruksi :
A := D * C + B / E
Bila dibuat kode antara tripel :
1. *, D, C
2. /, B, E
3. +, (1), (2)
4. :=, A, (3)
Perlu diperhatikan presedensi dari operator, yaitu operator perkalian dan pembagian
mendapat prioritas dibanding penjumlahan dan pengurangan
Contoh lain :
IF X > Y then
X:= a - b
Else
X:= a + b
Kode antara tripelnya :
1. >, X, Y
2. BZ, (1), (7)
3. -, a, b
4. :=, X, (3)
5.
104
6. BR, , (10)
7. +,a, b
8. :=, x, (7)
9.
10.
Contoh lain :
Ubahlah instruksi berikut ke dalam bentuk triples notation : A
:= B + C * D / E
F:=C*D
Bila dibuat ke dalam bentuk triples notation :
1. *, C, D
2. /, (1), E
3. +, B, (2)
4. :=, A, (3)
5.
6. :=, F, (1)
7.
Contoh lain :
a:=1
While A<5 do
A:=a+1
Diubah ke Triples Notation :
1. :=,a, 1
2. <, a, 5
3. BZ,(2),(8)
4. +,a,1
5. :=,a,(4)
6.
7. BR,,(2)
8.
Contoh lain :
105
a:=1
Repeat
B:=b+a
Until A<5
Diubah Ke triples notation :
1. :=,a,1
2. +,b,a
3. :=,b,(2)
4.
5. +,a,1
6. :=,a,(5)
7.
8. <,a,5
9. BZ,(8),(11)
10. BR, ,(3)
11.
Contoh lain :
For i := 1 to 5 do
a:=a+1
Diubah ke Triples Notation :
1. :=,i,1
2. <=,i,5
3. BZ,(2),(9)
4. +,a,1
5. :=,a,(4)
6. +,i,1
7. :=,i,(6)
8. BR, ,(2)
Quadruples Notation
Format notasi Quadruples
<Operator> <Operand> <Operand> <Hasil>
Contoh instruksi :
A := D * C + B / E
Bila dibuat ke dalam bentuk quadruples notation :
106
1. *, D, C, T1
2. /, B, E, T2
3. +, T1, T2, A
Contoh lain :
a:=1
While A<5 do
A:=a+1
Bila dibuat ke dalam bentuk quadruples notation :
1. :=,a,1,T1
2. <,a,5,T2
3. BZ,T2,(6),T3
4. +,a,1,A
5. BR,,T2,T4