Sunday 1 March 2015

INFO :: PENGERTIAN AUTOMATA


AUTOMATA
Automata berasal dari bahasa Yunani automatos, yang berarti sesuatu yang bekerja secara otomatis (mesin). Istilah automata merupakan bentuk tunggal, sedangkan bentuk jamaknya adalah automaton. Teori automata adalah teori tentang mesin abstrak yang bekerja secara sekuensial yang menerima dan mengeluarkan output dalam bentuk diskrit.
Pengertian mesin bukan hanya mesin elektronis/mekanis saja melainkan segala sesuatu (termasuk perangkat lunak) yang memenuhi ketiga ciri di atas. Penggunaan automata pada perangkat lunak terutama pada pembuatan kompiler bahasa pemrograman. Secara garis besar ada dua fungsi automata dalam hubungannya dengan bahasa, yaitu :
· fungsi automata sebagai pengenal (RECOGNIZER) string-string dari suatu bahasa, dalam hal ini bahasa sebagai masukan dari automata
· fungsi automata sebagai pembangkit (GENERATOR) string-string dari suatu bahasa, dalam hal ini bahasa sebagai keluaran dari automata
Untuk mengenali string-string dari suatu bahasa, akan dimodelkan sebuah automaton
yang memiliki komponen sebagai berikut :
– pita masukan, yang menyimpan string masukan yang akan dikenali;
– kepala pita (tape head), untuk membaca/menulis ke pita masukan;
– Finite State Controller (FSC), yang berisi status-status dan aturan-aturan yang
mengatur langkah yang dilakukan oleh automaton berdasarkan status setiap saat
dan simbol masukan yang sedang dibaca oleh kepala pita;
– pengingat (memory), untuk tempat penyimpanan dan pemrosesan sementara
Automaton pengenal, setelah membaca string masukan dan melakukan langkahlangkah
pemrosesan yang diperlukan, akan mengeluarkan keputusan apakah
string tersebut dikenali atau tidak.
– Konfigurasi adalah suatu mekanisme untuk menggambarkan keadaan suatu mesin
pengenal , yang terdiri atas :
_ status FSC
_ isi pita masukan dan posisi kepala pita
_ isi pengingat
Mesin pengenal bersifat deterministik bila dalam setiap konfigurasi, hanya ada satu kemungkinan yang dapat dilakukan mesin, jika tidak mesin pengenal bersifat nondeterministik.
Sejarah Otomata dan Teori Bahasa
Otomata bermula sebelum komputer ada pada teori di bidang sistem logika matematika atau formal, ilmuwan David Hilbert telah mencoba menciptakan algoritma umum untuk pembuktian (seluruh) persoalan matematika secara otomatis yaitu mampu menentukan salah benarnya sembarang prosisi matematika.
Tahun 1931, Kurt GÖdel mempublikasikan teori ketidaklengkapan dimana membuktikan prosedur/algoritma yang dikehendaki David Hilbert tersebut tidak akan pernah ada.
GÖdel membangun rumus di kalkulus predikat yang diterapkan pada bilangan bulat yang memiliki pernyataan-pernyataan definisi yang tidak dapat dibuktikan maupun dibantah di dalam sistem logika yang mungkin dibangun manusia.
Formalisasi argumen teorema ketidaklengkapan GÖdel ini berikut penjelasan dan formalisasi selanjutnya dari prosedur efektif secara intuisi merupakan salah satu pencapaian intelektual terbesar abad 20, yaitu abad dimana formalisasi berkembang semarak.
Pengembangan teori otomata, komputasi dan teori bahasa berikutnya difasilitasi perkembangan bidang psyco-linguistic. Bidang psyco-linguistic berupaya menjawab pertanyan-pertanyan berikut:
– Apakah bahasa secara umum?
– Bagaimana manusia mengembangkan bahasa?
– Bagaimana manusia memahami bahasa?
– Bagaimana manusia mengajarkan bahasa ke anak-anaknya?
– Apa gagasan-gagasan yang dapat dinyatakan dan bagaimana caranya?
– Bagaimana manusia membangun kalimat-kalimat dari gagasan-gagasan yang berada di pikirannya?
Sekitar tahun 1950-an, Noam Chomsky menciptakan model matematika sebagai sarana untuk mendeskripsikan bahasa serta menjawab pertanyaan-pertanyaan di atas. Saat ini dimulai pendalaman bidang bahasa komputer.
Perbedaan antara bahasa komputer dan bahasa manusia adalah sampai sekarang belum diketahuinya bagaimana cara manusia mengartikan bahasa, sementara dengan pasti dapat mengartikan bahasa pada komputer.
Noam Chomsky mengemukakan perangkat format disebut grammar untuk memodelkan properti-properti bahasa.
Tata bahasa (grammer) bisa didefinisikan secara, formal sebagai kumpulan dari himpunan?himpunan variabel, simbol?simbol, terminal, simbol awal, yang dibatasi oleh aturan?aturan produksi. Tingkat bahasa dapat digolongkan menjadi empat yaitu :
1.Bahasa : Regular type 3
Mesin otomata : Finite State Otomata (FSA) meliputi deterministic finite automata dan non deterministic finite automata
Batasan aturan produksi : adalah sebuah simbol variabel maksimal memiliki sebuah simbol variabel yang bila terletak di posisi paling kanan.
2.Bahasa : Bebas konteks/context free /type 2
Mesin otomata : Push down automata (PDA)
Batasan aturan produksi : Berupa sebuah simbol variabel.
3.Bahasa : Context sensitive/type 1
Mesin otomata : Linier bounded automata
Batasan aturan produksi :
4.Bahasa : Unrestricted /phase /natural language/type 0
Mesin otomata : Mesin turing
Batasan aturan produksi : Tidak ada batasan
Semua aturan produksi dinyatakan dalam bentuk “” dimana
– : simbol?simbol pada ruas kiri aturan produksi
– : simbol?simbol pada ruas kanan
Simbol?simbol tersebut bisa berupa simbol terminal atau non terminal/ variabel.
Keterangan :
Simbol terminal biasanya dinyatakan dengan huruf kecil, misal ‘a ‘, ‘b’, ‘c’.(tidak bisa diturunkan lagi).
Simbol non terminal dinyatakan dengan huruf besar, misal ‘A’, ‘B’, ‘C’.(masih bisa diturunkan).
Dengan menerapkan aturan produksi, suatu tata bahasa bisa menghasilkan string. Himpunan semua string tersebut adalah bahasa yang didefinisikan oleh tata bahasa tersebut.
Reguler
Pada bahasa reguler, batasannya bertambah dengan ruas kanan maksimal memiliki sebuah simbol variabel yang terletak di paling kanan. Artinya bisa memiliki simbol terminal saja dalam jumlah tidak dibatasi, tetapi bla terdapat simbol variabel tersebut hanya bejumlah satu (1) dan terletak di posisi paling kanan. Misal :
Bentuk normal chomsky / chomsky normal form (CNF ) merupakan salah satu bentuk normal yang sangat berguna untuk tata bahasa bebas konteks ( CFG ). Bentuk normal chomsky dapat di buat dari tata bahasa bebas konteks yang telah mengalami penyederhanaan yaitu penghilangan produksi useless, unit, dan ? . dengan kata lain, suatu tata bahasa bebas konteks dapat dibuat menjadi bentuk normal chomsky dengan syarat :
Tidak memiliki produksi useless
Tidak memiliki produksi unit
Tidak memiliki ?
Langkah?langkah pembentukan bentuk normal chomsky secara umum:
Biarkan aturan produksi yang sudah dalam bentuk normal Chomsky.
Lakukan penggantian aturan produksi yang ruas kanannya mermiat simbol terminal dan panjang ruas kanan > 1
Lakukan penggantian aturan produksi yang ruas kanannya mernuat >2 simbol variabel
Penggantian?penggantian tersebut bisa dilakukan berkali?kali sampai akhirnya semua aturan produksi dalam bentuk normal chomsky
Selama dilakukan penggantian, kemungkinan kita akan memperoleh aturan?aturan produksi baru, dan juga memunculkan simbol?simbol variabel baru.
Free Context
Bahasa bebas konteks menjadi dasar dalam pembentukan suatu proses analisis sintaksis. Pada bahasa bebas konteks, batasannya bertambah lagi dengan ruas kiri haruslah tepat satu symbol variable.
Contoh: B ? CdeFg ; D ? BcDe
Sensiteve Context
Pada bahasa context sensitive, panjang string pada ruas kiri panjang ruas kanan ( )
Contoh : Abc ? Def ; CD ? eF
Batasan context sensitive biasanya turut digunakan dalam proses analitis semantik pada tahapan kompilasi.
Unrestricted /phase /natural language
Bahasa manusia / bahasa alami termasuk ke dalam grammer (tata bahasa) type 0 /unrestricked, di mana tidak ada batasan pada aturan produksinya.
Contoh : Abc ? De
BEBERAPA PENGERTIAN DASAR
· Simbol adalah sebuah entitas abstrak (seperti halnya pengertian titik dalam geometri). Sebuah huruf atau sebuah angka adalah contoh simbol.
· String adalah deretan terbatas (finite) simbol-simbol. Sebagai contoh, jika a, b, dan c adalah tiga buah simbol maka abcb adalah sebuah string yang dibangun dari ketiga simbol tersebut.
· Jika w adalah sebuah string maka panjang string dinyatakan sebagai |w| dan didefinisikan sebagai cacahan (banyaknya) simbol yang menyusun string tersebut. Sebagai contoh, jika w = abcb maka |w|= 4.
· String hampa adalah sebuah string dengan nol buah simbol. String hampa dinyatakan dengan simbol ε (atau ^) sehingga |ε|= 0. String hampa dapat dipandang sebagai simbol hampa karena keduanya tersusun dari nol buah simbol.
· Alfabet adalah hinpunan hingga (finite set) simbol-simbol
OPERASI DASAR STRING
Diberikan dua string : x = abc, dan y = 123
· Prefik string w adalah string yang dihasilkan dari string w dengan menghilangkan nol atau lebih simbol-simbol paling belakang dari string w tersebut.
Contoh : abc, ab, a, dan ε adalah semua Prefix(x)
· ProperPrefix string w adalah string yang dihasilkan dari string w dengan menghilangkan satu atau lebih simbol-simbol paling belakang dari string w tersebut.
Contoh : ab, a, dan ε adalah semua ProperPrefix(x)
· Postfix (atau Sufix) string w adalah string yang dihasilkan dari string w dengan menghilangkan nol atau lebih simbol-simbol paling depan dari string w tersebut.
Contoh : abc, bc, c, dan ε adalah semua Postfix(x)
· ProperPostfix (atau PoperSufix) string w adalah string yang dihasilkan dari string w dengan menghilangkan satu atau lebih simbol-simbol paling depan dari string w tersebut.
Contoh : bc, c, dan ε adalah semua ProperPostfix(x)
· Head string w adalah simbol paling depan dari string w.
Contoh : a adalah Head(x)
· Tail string w adalah string yang dihasilkan dari string w dengan menghilangkan simbol paling depan dari string w tersebut.
Contoh : bc adalah Tail(x)
· Substring string w adalah string yang dihasilkan dari string w dengan menghilangkan nol atau lebih simbol-simbol paling depan dan/atau simbol-simbol paling belakang dari string w tersebut.
Contoh : abc, ab, bc, a, b, c, dan ε adalah semua Substring(x)
· ProperSubstring string w adalah string yang dihasilkan dari string w dengan menghilangkan satu atau lebih simbol-simbol paling depan dan/atau simbolsimbol paling belakang dari string w tersebut.
Contoh : ab, bc, a, b, c, dan ε adalah semua Substring(x)
· Subsequence string w adalah string yang dihasilkan dari string w dengan menghilangkan nol atau lebih simbol-simbol dari string w tersebut.
Contoh : abc, ab, bc, ac, a, b, c, dan ε adalah semua Subsequence(x)
· ProperSubsequence string w adalah string yang dihasilkan dari string w dengan menghilangkan satu atau lebih simbol-simbol dari string w tersebut.
Contoh : ab, bc, ac, a, b, c, dan ε adalah semua Subsequence(x)
· Concatenation adalah penyambungan dua buah string. Operator concatenation adalah concate atau tanpa lambang apapun.
Contoh : concate(xy) = xy = abc123
· Alternation adalah pilihan satu di antara dua buah string. Operator alternation adalah alternate atau | |.
Contoh : alternate(xy) = x|y = abc atau 123
· Kleene Closure : x* = ε|x|xx|xxx|… = ε|x|x 2 |x 3 |…
Positive Closure : x + = x|xx|xxx|… = x|x 2 |x 3 |…
SIFAT OPERASI DASAR STRING
· Tidak selalu berlaku : x = Prefix(x)Postfix(x)
· Selalu berlaku : x = Head(x)Tail(x)
· Tidak selalu berlaku : Prefix(x) = Postfix(x) atau Prefix(x) ≠ Postfix(x)
· Selalu berlaku : ProperPrefix(x) ≠ ProperPostfix(x)
· Selalu berlaku : Head(x) ≠ Tail(x)
· Setiap Prefix(x), ProperPrefix(x), Postfix(x), ProperPostfix(x), Head(x), dan
Tail(x) adalah Substring(x), tetapi tidak sebaliknya
· Setiap Substring(x) adalah Subsequence(x), tetapi tidak sebaliknya
· Dua sifat aljabar concatenation :
♦ Operasi concatenation bersifat asosiatif : x(yz) = (xy)z
♦ Elemen identitas operasi concatenation adalah ε : εx = xε = x
· Tiga sifat aljabar alternation :
♦ Operasi alternation bersifat komutatif : x|y = y|x
♦ Operasi alternation bersifat asosiatif : x|(y|z) = (x|y)|z
♦ Elemen identitas operasi alternation adalah dirinya sendiri : x|x = x
· Sifat distributif concatenation terhadap alternation : x (y|z) = xy|xz
· Beberapa kesamaan :
♦ Kesamaan ke-1 : (x*)* = (x*)
♦ Kesamaan ke-2 : ε|x + = x + |ε = x*
♦ Kesamaan ke-3 : (x|y)* = ε|x|y|xx|yy|xy|yx|… = semua string yang
merupakan concatenation dari nol atau lebih x, y, atau keduanya
TEORI BAHASA
Teori bahasa membicarakan bahasa formal (formal language), terutama untuk kepentingan perancangan kompilator (compiler) dan pemroses naskah (text processor). Bahasa formal adalah kumpulan kalimat. Semua kalimat dalam sebuah bahasa dibangkitkan oleh sebuah tata bahasa (grammar) yang sama. Sebuah bahasa formal bisa dibangkitkan oleh dua atau lebih tata bahasa berbeda. Dikatakan bahasa formal karena grammar diciptakan mendahului pembangkitan setiap kalimatnya. Tata bahasa (grammar) adalah kaidah/aturan pembentukan kata/kalimat. Pada pembahasannya, bahasa formal hanya disebut bahasa saja.
Bahasa dalam bentuk tulisan terdiri atas symbol-simbol satuan yang jika dikombinasikan akan mempunyai arti yang berbeda. Simbol-simbol yang biasa dipergunakan dalam sebuah bahasa terbatas jumlahnya, yang membentuk sebuah himpunan dan disebut sebagai abjad/alphabet. Namun kadangkala digunakan istilah karakter yang artinya sama dengan symbol. Deretan dari karakter atau symbol ini membentuk string. Dan himpunan dari semua string yang dibentuk dari suatu abjad ini didefinisikan sebagai bahasa.
Karena bahasa adalah sebuah himpunan dari string, maka untuk mendefinisikan suatu bahasa bisa dilakukan dengan menuliskan semua string yang menjadi anggotanya. Tata Bahasa G = (T,N,S,P), di mana
• T adalah himpunan berhingga simbol-simbol terminal
• N adalah himpunan berhingga simbol-simbol non terminal
• S adalah simbol awal, S ( N
• P adalah himpunan berhingga aturan produksi yang setiap elemennya berbentuk * + ,,
*, , ( (T U N)+, * harus berisi minimal 1 simbol non terminal
Sentential form adalah semua string yang dapat diturunkan dari simbol awal S dengan
menggunakan aturan produksi P. Kalimat (sentence) adalah sentential form yang tidak
mengandung simbol non terminal. Bahasa yang dihasilkan dari G dinotasikan dengan
L(G), yaitu himpunan kalimat yang dapat diturunkan dari S dengan menggunakan P.

INFO :: Cara Membuat COMPILE C++ Sendiri Dengan NOTEPAD++



COMPILE C++ WITH NOTEPAD++


1) Install Notepad++ silahkan download disini  setelah selesai download install deh, sperti biasa next, netx terus sampai finish.

2)  Install Borland C++ googling aja mas. kalo yang ane pake sih Borland c++ versi 5.02. kita cuma ambil buat compiler doang bro.

3) Kita butuh sebuah plugin its called NppExec silahkan dicek di tab plugins noh ada diatas.


4)  Kalo udah teristall buka tab plugins > NppExec  lalu centang "follow $(CURRENT_DIRECTORY)". that's it..

5) Terakhir kita akan setting compilernya. caranya??
-Buka Notepad++  silahkan bikin program "hello world".. silahkan tulis scriptnya..

#include 
#include 
main 
{
cout<<"hello world";
getch();
}

compile dengan cara klik tab Plugins > NppExec > Execute.. or tekan F6 biar lebih  cepet gtu..
otomatis akan ada printah untuk menyimpan file, simpan file dengan nama "hello.cpp"  INGAT!! ".cpp" jangan sampai lupa!!

selanjutnya akan keluar command for execute isi kan kolom command dengan
bcc32 "$(FULL_CURRENT_PATH)" "$(NAME_PART)"

lalu save dengan nama "c++ compiler" setelah tekan OK maka file ok akan di compile like this..


nah selesai deh di compile... nah selamat mencoba.. :)
jika kalian ingin melihat hasil c++ yang kita compile tadi silah kan ketik di console npp_run "nama_file" kalo dalam kasus tadi berarti kita ketik npp_run hello  like this...
 hasilnya kita lihat


selamat mencoba GOOD LUCK semoga bermanfaat ;).

Sumber : arifazik06

INFO :: Proses Dan Cara Membuat Sebuah Compiler


Berikutnya adalah: bagaimana kalau kita ingin membuat compiler? Interpreter hanya mengeksekusi program, dan tidak menghasilkan output. Compiler perlu mengoutputkan kode dalam bahasa assembly, yang kemudian akan dikompilasi oleh assembler. Mempelajari assembly yang lengkap butuh waktu, apalagi jika kita ingin menargetkan berbagai prosessor, sehingga membuat compiler yang mengoutputkan ke assembly langsung tidaklah mudah.
Karena sulitnya bahasa assembly, dalam tahap-tahap berikutnya, kita tidak akan mengoutputkan bahasa assembly langsung, tapi akan menggunakan bantuan LLVM (Low Level Virtual Machine). Tapi untuk tahap-tahap awal, saya bisa menunjukkan bagaimana output assembly langsung bisa dibuat, apalagi dalam bahasa yang sangat sederhana seperti ini.
Pertama saya akan membahas dulu apa bedanya sebuah compiler dengan interpreter. Sebuah compiler menghasilkan kode assembly dari sebuah program. Compiler tidak menghasilkan file executable. Diberikan program Z dalam bahasa X, compiler membuat versi assembly dari program Z tersebut. Jadi compiler hanya menerjemahkan sebuah bahasa ke ekivalennya dalam bahasa assembly.

compiler.png
Tugas mengubah ke bahasa mesin dilakukan oleh assembler. Assembler mengubah instruksi assembly menjadi bahasa mesin. File yang dihasilkan compiler ini disebut sebagai object code, file ini sudah dalam bahasa mesin, tapi belum bisa dieksekusi.
assembler.png
Mengapa belum bisa? karena masih ada fungsi-fungsi yang belum diketahui definisinya. Misalny, ketika Anda membuat program dalam C, apakah Anda mengimplementasikan sendiri fungsiprintf? biasanya tidak, karena fungsi itu sudah ada di Library. Proses berikutnya adalah menggabungkan library dengan object code untuk membentuk executable. Proses ini dilakukan oleh program linker.
linker.png
Yang paling penting bagi kita bukanlah urutan proses tersebut, tapi apa yang ada dalam sebuah compiler yang membedakannya dari interpreter. Sebagian komponen compiler sama dengan interpreter. Bagian parser sama persis, sehingga kita bisa memakai parser dari tutorial bagian sebelumnya.
compiler detail.png

Algoritma

Algoritma dasar untuk compiler masih sama dengan interpreter. Pada versi interpreter, kita langsung menjalankan program, nah di versi compiler ini, kita menghasilkan teks di setiap langkah (teks bahasa assembly). Kode assembly tidak langsung dituliskan ke file, tapi ditampung dulu dalam sebuah StringBuffer. Untuk memudahkan, saya akan menggunakan pendekatan berbasis stack (stack based) dan bukan register based (akan saya jelaskan nanti alasannya). Jika Anda tertarik, Anda bisa membaca Wikipedia mengenai Stack machine dan Register machine.
Di awal kita perlu membuat sebuah template, yang merupakan kerangka program. Berikutnya, di setiap langkah kita menghasilkan instruksi yang sesuai, misalnya ketika menemui sebuah integer, kita menghasilkan instuksi untuk menaruh integer tersebut di stack. Ketika menemui instruksi untuk menambah dua ekspresi, kita panggil secara rekursif kode program kita untuk menghasilkan assembly bagi operand kiri dan operand kanan, lalu kita hasilkan instruksi untuk menjumlahkan kedua hasilnya.

Memakai Assembly

Kita akan membatasi bahasan kita untuk Intel x86 32 bit saja. Untuk mengimplementasikan compiler dalam bahasa sederhana tersebut, kita hanya perlu 6 instruksi dan 2 register. Instruksi pertama adalah push <reg> atau push <nilai> untuk menaruh nilai ke stack. Lalu pasangannya adalah pop <reg> untuk menaruh isi stack ke register. Berikutnya kita perlu instruksi add untuk menjumlah, sub untuk mengurangi, dan imull untuk mengalikan integer. Kita juga perlu instruksicall untuk memanggil fungsi printf milik library C, serta ret untuk kembali dari fungsi utama ke sistem operasi.
Kita akan menggunakan syntax assembly AT&T, dan saya hanya mengetes ini di Linux. Ada beberapa tutorial assembly untuk Linux, misalnya http://asm.sourceforge.net/howto/Assembly-HOWTO.html, Anda bisa membaca aneka tutorial jika Anda benar-benar blank mengenai assembly. Setiap file output pasti punya kerangka dasar seperti ini:
.section    .rodata
.mytext:
.string "Result %d\n"
.text
.globl main
.type main, @function
main:
/*aneka macam perintah akan diletakkan di sini*/
ret
.size main, .-main
Untuk mengevaluasi ekspresi, kita selalu menggunakan stack. Contohnya begini, Jika kita memiliki (1 * 3) + (4 - 5), kita akan memiliki tree, dengan + sebagai akar (root), anak pertama akan mengandung subtree dengan * di root serta 1 dan 3 di anak, sedangkan anak kedua memiliki subtree dengan - di root serta 4 dan 5 sebagai anak.
example comp 1.jpg
Ketika menemui '+', kita ingin agar ekpresi di sebelah kiri (1 * 3) dievaluasi dulu, lalu sebelah kanan di evaluasi (4-5), dan hasil evaluasi keduanya kita jumlahkan. Pertama, kita evaluasi 1 * 2. Ketika menemui *, kita ingin agar bagian kiri (1) dan (3) dievaluasi, lalu hasilnya baru dikalikan. Ketika mengevaluasi 1, maka hasilnya adalah instuksi assembly untuk menaruh 1 di stack, ketika menemui 3, maka hasilnya juga instruksi assembly untuk menaruh hasilnya di stack. Perhatikan awalan $ di syntax AT&T artinya angka 1 dan 3 merupakan literal:
pushl $1 
ISI STACK:
1
pushl $3
ISI STACK:
1 3
Ketika menemui *, kita pop 2 angka dari stack, lalu kita kalikan kedua angka tersebut, lalu taruh hasilnya di stack:
popl e%ax
ISI STACK:
1
Isi EAX = 3

popl %ebx
ISI STACK:
kosong
Isi EBX = 1

imull %ebx, %eax ; artinya EAX = EAX * EBX
ISI STACK:
kosong
Isi EAX = 3

pushl %eax

ISI STACK:
3
Sekarang kita evaluasi (4-5), langkahnya sama dengan di atas (jika tidak yakin, Anda bisa menjalankan compilernya), di akhir, kita akan mendapati isi stack seperti ini:
ISI STACK:
3 -1
Lalu operasi penjumlahan dilakukan
popl %eax --> ambil dari stack (-1)
popl %ebx --> ambil dari stack (3)
addl %ebx, %eax --> EAX = EAX + EBX
pushl %eax --> masukkan hasilnya ke stack
Di akhir, kita ingin mencetak hasilnya. Untuk mudahnya, kita akan menggunakan library C. Anda juga bisa menggunakan cara khusus sebuah OS, misalnya di DOS Anda bisa menggunakan INT 21 Fungsi 9 dan di Linux Anda bisa memanggil syscall write. Tapi cara-cara tersebut tidak portabel. Library C sudah tersedia di aneka OS berbasis UNIX, jadi demi kesederhanaan artikel, saya akan memakai library C. Di C, mencetak sebuah integer mudah sekali, cukup printf("Result: %d\n", result). Di assembly ini juga tidak sulit, cukup perlu:
pushl  %eax
push $.mytext
call printf
popl %ebx
popl %ebx
Passing parameter dalam assembly dapat dilakukan via register atau stack (tergantung calling convention, dan jumlah parameternya, tapi itu tidak penting sekarang). Dalam kasus printf kita perlu menggunakan stack, parameter untuk printf dalam kasus ini ada dua, yang pertama adalah format string "Result: %d\n", yang saya letakkan di label .mytext, serta nilai integer yang akan kita cetak. Passing dilakukan terbalik, parameter terakhir dipush pertama.
Karena pushl %eax sudah dilakukan di akhir setiap ekspresi, maka kita tidak perlu mengulanginya. Seperti yang Anda lihat di bagian template, isi $.mytext adalah "Result: %d\n". Instruksi calldigunakan untuk memanggil printf. Fungsi printf di C merupakan fungsi khusus (jumlah parameternya bisa banyak), sehingga kita perlu membuang lagi nilai yang dipush dengan popl ke sembarang register (dalam hal ini saya pilih saja %ebx).

Menjalankan compiler

Anda bisa menjalankan compiler ini seperti menjalankan interpreter. Output compiler ini ada dua, yang pertama adalah file assembly .s (misalnya input adalah test.e, maka outputnya adalah test.e.s), dan file executable (file test.e.exe). Jika compiler gcc tidak tersedia di sistem, maka hanya satu saja outputnya (.s). Anda bisa melakukan assembling dan linking dengan:
gcc -m32 namafile.s -o namafile.exe
Secara otomatis program Java akan mencoba menjalankan perintah itu, tapi tidak akan berhasil jika gcc tidak ada di path. Parameter -m32 memaksakan agar kita menggunakan mode 32 bit meski di OS 64 bit (OS yang saya pakai 64 bit, tapi sebagian besar orang masih memakai 32 bit).
Anda bisa mempelajari dan membandingkan dengan output sebuah program dalam bahasa C. Menggunakan compiler GCC, Anda bisa mengoutputkan kode assembly untuk sebuah program dalam bahasa C seperti ini:
gcc -S namafile.c
hasilnya adalah namafile.s. Sebenarnya gcc selalu menghasilkan file assembly .s, tapi file ini dibuat di direktori sementara. Dengan opsi -S kita meminta agar membuat file .s di direktori saat ini dan meminta gcc berhenti setelah membuat file .s (tidak meneruskan tahap assembler dan linker).

Kode Program

Source code compiler lebih panjang dari source code interpreter (83 baris vs 60 baris). Kode-kode berikut ini ada pada file ExprComp.java. Di bagian main kita buat dulu template dasar file assembly yang akan dihasilkan:
        StringBuffer result = new StringBuffer();
result.append(".section .rodata\n");
result.append(".mytext:\n");
result.append(".string \"Result %d\\n\"\n");
result.append(".text\n");
result.append(".globl main\n");
result.append(".type main, @function\n");
result.append("main:\n");
el.compile(result);
result.append("ret\n");
result.append(".size main, .-main\n");
Lalu dibagian evaluasi (method compileExpr), kita perlu menghasilkan assembly yang sesuai, untuk integer:
           if (expr.getType()==ExprLexer.INT) {
result.append("pushl $"+expr.getText()+"\n");
return;
}
Untuk +,-,* semua perlu dua operand, jadi instruksi awalnya pasti sama, yaitu: hasilkan instruksi untuk kiri dan kanan, lalu pop dua operand ke eax dan ebx:
        if (expr.getText().equals("+") || expr.getText().equals("-")
|| expr.getText().equals("*")) {
compileExpr(result, (CommonTree)expr.getChild(0));
compileExpr(result, (CommonTree)expr.getChild(1));
result.append("popl %eax\n");
result.append("popl %ebx\n");
}
Berikutnya mudah, kalau + hasilkan addl, kalau - hasilkan subl, dan kalau * hasilkan imull:
        if (expr.getText().equals("+")) {
result.append("addl %ebx, %eax\n");
}
if (expr.getText().equals("-")) {
result.append("subl %eax, %ebx\n");
}
if (expr.getText().equals("*")) {
result.append("imull %ebx, %eax\n");
}
Hasilnya kita kembalikan ke stack:
            result.append("pushl   %eax\n");
Setelah sebuah ekspresi selesai, kita perlu mencetaknya
    void compileExpression(StringBuffer result, CommonTree expr) {
compileExpr(result, (CommonTree)expr.getChild(0));
result.append("push $.mytext\n");
result.append("call printf\n");
result.append("popl %ebx\n");
result.append("popl %ebx\n");
}
Jadi instruksi yang kita pakai benar-benar amat sedikit.
Program Java akan menyimpan hasil akhir ke file:
        String asmname = argv[0]+".s";
FileWriter fw = new FileWriter(asmname);
PrintWriter pw = new PrintWriter(fw);
pw.println(result.toString());
fw.close();
Lalu hasilnya dikompilasi:
        String command[] = {"gcc", "-m32", asmname, "-o", 
argv[0]+".exe"};
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
Perhatikan bahwa jika kompilasi gagal atau berhasil, tidak akan ada pesan apapun. Anda hanya akan tahu bahwa kompilasi berhasil atau tidak dengan melihat apakah file .exe tercipta atau tidak. Silahkan tambahkan sendiri kode untuk melakukan pemeriksaan tersebut.

Terlalu sederhana

Instruksi yang dihasilkan oleh compiler ini sangat sederhana, namun sangat tidak efisien. Karena semua hanyalah konstanta (kita belum bisa menerima input dari user), maka sebenarnya yang penting hanyalah hasil akhir saja. Meski demikian, latihan ini penting sebelum masuk ke bahasa yang bisa memiliki variabel/identifier.
Ketika kita sudah bisa menerima input dari user, eksekusi berbasis stack kurang efisien. Sebuah prosessor memiliki beberapa register, dan penggunaan stack lebih lambat dari register. Misalnya kita punya 3 variabel, kita bisa meletakkan 3 variabel tersebut di register, tanpa perlu menyentuh stack sama sekali. Tapi masalah muncul ketika jumlah variabel semakin banyak. Jumlah register di prosessor terbatas (biasanya 16-32 register), jadi kita tetap perlu memakai stack ketika jumlah variabel semakin banyak. Kita harus dengan pintar mengatur, variabel apa yang masuk register dan apa yang masuk stack. Masalah ini dinamakan register allocation problem. Anda bisa membaca aneka buku dan paper untuk memahami masalah tersebut.
Kita juga harus memiliki pengetahuan assembly aneka prosessor untuk bisa membuat kode assembly yang baik. Masalahnya terutama adalah masalah optimasi, ada banyak cara untuk melakukan suatu hal (misalnya membagi dua bisa dilakukan dengan shift right satu bit), sebuah compiler yang baik harus bisa memilih instruksi terbaik untuk menghasilkan kode tercepat.
Di masa yang akan datang, saya akan menunjukkan bagaimana menggunakan LLVM, yang akan bisa mengoutputkan kode bahasa mesin, tapi kita sendiri tidak perlu memahami aneka prosessor. LLVM merupakan proyek yang sudah ada sejak 9 tahun yang lalu (tahun 2000), dan sudah didukung oleh banyak perusahaan besar (Adobe, Apple, dsb).

semoga bermanfaat ^_'

sumber : yohan.es

Praktek Pengenalan C#


Selamat Malam Permirsa jufrikablog kali ini saya akan memberi modul praktikum saya di mata kuliah program lanjut :D 


A.    Praktikum
1.       Set path Windows ke compiler. Caranya :
1.1 Klik Start -> my Computer, kemudian click kanan pada my computer pilih menu properties.
1.2 Di kotak dialog System Properties, Klik tab Advanced dan klik
Environment Variables.
1.3 Di bagian System Variables, klik Path dan klik Edit
1.4 Tekan tombol Home dan tekan tombol panah kanan beberapa kali. Cek
jika sudah ada tulisan yang mirip seperti
Microsoft.NET\Framework\vXXXX dimana XXXX adalah angka.
Apabila anda tidak menemukan tulisan tersebut, tekan tombol End, atau
anda menuju bagian akhir tulisan tersebut, tambahkan “;” diikuti path
buat compiler-nya. Di komputer saya seperti ini :
%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\
Wbem;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
1.5 Klik OK di tiap kotak dialog.