4. ANALISIS LEKSIKAL
• Analisis leksikal (scanner) sering juga disebut sebagai analisis linier atau pembacaan sekilas (scanning).
• Analisis leksikal bekerja dengan cara membaca program sumber setiap
karakter demi karakter.
• Dalam proses ini deretan karakter pada program sumber dibaca dari kiri
ke kanan dan dikelompokkan menjadi token yaitu barisan karakter yang dalam suatu kesatuan mempunyai arti tersendiri.
• Scanner merupakan antarmuka antara program sumber dan analisis
sintaktik (parser). Scanner melakukan pemeriksaan karakter per
karakter pada teks masukan, memecah program sumber menjadi bagian-bagian terkecil yang disebut Token.
• Scanner mengerjakan pengelompokan karakter untuk menghasilkan suatu Token Leksikal menjadi beberapa komponen pokok, yaitu:
- identifier,
• Model dasar untuk membentuk suatu Analisis Leksikal adalah
Finite-State Automata atau Automata Hingga.
• 2 aspek penting pembuatan Analisis Leksikal adalah:
∗ Menentukan token-token bahasa.
∗ Mengenali token-token bahasa dari program sumber.
• Analisis Leksikal mengirim token ke parser. Untuk mengirim token,
scanner harus mengisolasi barisan karakter pada teks sumber yang merupakan 1 token valid. Scanner juga menyingkirkan informasi seperti komentar, blank, batas-batas baris dan lain-lain yang tidak penting (tidak mempunyai arti) bagi parsing dan Code Generator.
• Scanner juga harus dapat mengidentifikasi token secara lengkap dan membedakan keyword dan identifier.
• Untuk itu scanner memerlukan tabel simbol. Scanner memasukkan
• Scanner merupakan komponen kompilasi independen yang
berkomunikasi dengan parser lewat antarmuka yang terdefinisi,
sehingga perubahan-perubahan pada scanner tidak berdampak pada
pengubahan kompilator secara keseluruhan.
• Pada analisis leksikal yang dituntun tabel (table-driven lexical
analyzer), maka satu-satunya yang berubah adalah tabel itu sendiri.
• Interaksi analisis leksikal dan analisis sintaktik lebih kompleks. Analisis leksikal harus dapat menganggap string sebagai token bertipe, bukan identifier.
• Scanner dapat memasukkan string ke tabel simbol, mengidentifikasi sebagai Type atau typedef, sehingga analisis leksikal dapat memeriksa
tabel simbol untuk menentukan apakah lexeme adalah token.
• Tugas-tugas Analisis leksikal:
1. Konversi Program Sumber Menjadi Barisan Token
Mengubah program sumber yang dipandang sebagai barisan byte/karakter menjadi token
2. Menangani Kerumitan Sistem Masukkan/Keluaran. Karena analisis
leksikal berhubungan langsung dengan kode sumber, maka analisis leksikal juga bertindak sebagai benteng untuk komponen lain di kompilator dalam mengatasi keanehan-keanehan sistem masukkan/ keluaran, sistem operasi dan sistem komputer.
• Optimasi perlu dilakukan agar analisis leksikal membaca karakter
dengan sekaligus membaca sejumlah besar bagian file.
• Perangkat masukkan/keluaran benar-benar diisolasi agar tidak terlihat
oleh parser dan komponen-komponen kompilator yang lain.
• Tugas-tugas tambahan Analisis Leksikal:
1. Penghilangan baris komentar dan whitespace (tab, spasi, dll.).
Tindakan housekeeping dilakukan scanner sehingga mengisolasikan
dari parser dan komponen-komponen kompilator lain.
Scanner juga mencatat nomor baris saat itu, sehingga penanganan kesalahan dapat mengirim pesan kesalahan dengan lebih akurat.
2. Konversi literal/konstanta numerik menjadi tipe data tertentu.
Tahap Pelaksanaan Analisis Leksikal
¾ Pada single one pass
Terjadi interaksi antara scanner dan parser. Scanner dipanggil saat
parser memerlukan token berikutnya. Pendekatan ini lebih baik karena bentuk internal program sumber yang lengkap tidak perlu dibangun dan disimpan di memori sebelum parsing dimulai.
¾ Pada separate pass
Scanner memproses secara terpisah, dilakukan sebelum parsing. Hasil
scanner disimpan dalam file. Dari file tersebut, parsing melakukan kegiatannya.
• Scanner mengirim nilai-nilai integer yang mempresentasikan bentuk internal token, bukan nilai-nilai string.
• Keunggulan cara ini adalah ukurannya kecil dan tetap. Parser sangat
lebih efisien bekerja dengan nilai integer yang mempresentasikan simbol daripada string nyata dengan panjang variabel.
Implementasi Analisis Leksikal
1. Pengenalan Token
o Scanner harus dapat mengenali token
o Terlebih dahulu dideskripsikan token-token yang harus dikenali
2. Pendeskripsian Token
o Menggunakan reguler grammar. Menspesifikasikan aturan-aturan
pembangkit token-token dengan kelemahan reguler grammar
menspesifikasikan token berbentuk pembangkit, sedang scanner
perlu bentuk pengenalan.
o Menggunakan ekspresi grammar. Menspesifikasikan token-token
dengan ekspresi reguler.
o Model matematis yang dapat memodelkan pengenalan adalah
finite-state acceptor (FSA) atau finite automata.
3. Implementasi Analisis Leksikal sebagai Finite Automata
Pada model analisis leksikal sebagai pengenal yang menerapkan finite automata, analisis leksikal tidak hanya mengatakan YA atau TIDAK. Analisis leksikal dapat dibangun dengan menumpangkan pada konsep pengenal yang berupa finite automata dengan cara menspesifikasikan rutin-rutin (aksi-aksi) tertentu terhadap string yang sedang dikenali.
Hanya sedikit kesalahan yang diidentifikasi di analisis leksikal secara mandiri karena analisis leksikal benar-benar merupakan pandangan sangat lokal terhadap program sumber.
Bila ditemui situasi dimana analisis leksikal tidak mampu melanjutkan proses karena tidak ada pola token yang cocok, maka terdapat beragam alternatif pemulihan.
Alternatif pemulihan tersebut adalah:
o "Panic mode" dengan menghapus karakter-karakter berikutnya sampai analisis leksikal menemukan token yang terdefinisi bagus
o Menyisipkan karakter yang hilang
o Mengganti karakter yang salah dengan karakter yang benar
o Mentransposisikan 2 karakter yang bersebelahan.
Salah satu cara untuk menemukan kesalahan pada program adalah menghitung jumlah transformasi kesalahan minimum yang diperlukan untuk mentransformasikan program yang salah menjadi program yag secara sintaks benar.
Input Buffering
Perancangan analisis leksikal seharusnya dapat membuat buffering masukkan yang membantu mempercepat proses pembacaan dari file serta mempunyai fleksibelitas yang tinggi agar analisis leksikal tidak bergantung platform sehingga mempunyai portabilitas yang tinggi.
C
ara umum untuk membentuk suatu penganalisis leksikal adalah• dengan membuat suatu diagram yang menggambarkan struktur token
dari suatu bahasa sumber, dan
• kemudian menerjemahkan diagram tersebut secara manual ke dalam
program untuk mencari token tersebut.
PERAN PENGANALISIS LEKSIKAL
•
P
enganalisis leksikal merupakan fase pertama pada sebuah kompilator.Fungsi penganalisis leksikal adalah :
membaca program sumber karakter demi karakter, menerjemahkannya
menjadi deretan token sebagaimana dispesifikasikan dalam spesifikasi leksikal bahasa sumber.
karakter spasi, tabulasi dan baris baru dari program sumber.
menghubungkan antara pesan-pesan kesalahan (error messages) yang
diperoleh oleh kompilator dengan program sumber.
Dengan kata lain, tugas penganalisis leksikal adalah membaca
karakter input dan memproduksi barisan dari token yang digunakan oleh
suatu pengurai untuk melakukan analisis sintaks.
Interaksi antara penganalisis leksikal dengan penganalisis sintaks ditunjukkan pada gambar berikut.
Secara umum tugas penganalisis leksikal dapat dibagi menjadi tiga kelompok tugas sebagai berikut :
- membaca program dan membaginya ke dalam token,
- membuang dari program sumber semua komentar, ruang kosong seperti karakter spasi, tabulasi dan baris baru,
- menghubungkan antara pesan-pesan kesalahan yang diperoleh oleh kompilator dengan program sumber.
Ada beberapa istilah yang perlu dipahami dalam penganalisis leksikal;
• token,
• pola, dan
• lexeme.
Token adalah satuan terkecil dari bahasa sumber yaitu deretan karakter terpendek yang mengandung arti.
Token dikelompokkan menjadi beberapa jenis sbb.: - identifier
- keyword - label
- operator aritmetika dan assignment - operator relasional
- tanda baca, dan sebagainya.
Masing-masing token diberikan nomor penyajian internal atau sering disebut nomor token, misalnya sebagai berikut :
Source
program analyzerLexical parser
Symbol table token
nama variabel 1
konstanta 2
label 3
keyword 4
operator penambahan 5
operator pemberian (assignment) 6
operator pengurangan 7
Pola dari suatu token adalah aturan yang menerangkan sejumlah lexeme
yang dapat menyatakan suatu token dalam suatu program sumber.
Pola tersebut akan cocok dengan setiap rangkaian karakter dalam himpunan karakter tersebut.
Lexeme adalah barisan karakter dalam program sumber yang dicocokkan oleh pola untuk menentukan suatu token.
Contoh token, lexeme dan pola dapat digambarkan sebagai berikut :
Token Sample Lexemes Informal Description of Pattern
const const const
if if if
relation <, <=, =, <>, >, >= < or <= or = or <> or > or >=
id pi, count, D2 letter followed by letters and digits
num 3.1416, 0, 6.02E23 any numeric constant
literal "core dumped" any characters between " and " except "
Misalkan perintah Pascal berikut ini:
Const pi = 3.1416;
rangkaian karakter bagian dari pi adalah lexeme untuk token identifier.
Atribut untuk token
• Bila lebih dari satu pola cocok dengan suatu lexeme, maka penganalisis
• Suatu token biasanya hanya mempunyai satu atribut saja, yaitu petunjuk pada entri tabel simbol di mana informasi dari token tersebut disimpan.
• Petunjuk (pointer) menjadi satu-satunya atribut dari token.
Contoh:
Token dan nilai atribut yang diperoleh untuk perintah FORTRAN berikut; E = M * C ** 2
dituliskan dalam barisan pasangan berikut ini:
<id, pointer pada entri tabel simbol untuk E> <assign_op>
<id, pointer pada entri tabel simbol untuk M> <mult_op>
<id, pointer pada entri tabel simbol untuk C> <exp_op>
<num, bilangan bernilai 2>
Kesalahan pada tingkat penganalisis leksikal
Sebagai contoh kalimat program berikut
fi ( a = f(x)) ...
Penganalisis leksikal tidak dapat mengatakan apakah fi ini merupakan kesalahan penulisan dari kata-kunci if atau suatu identifier yang belum didefinisikan.
Hal lain yang juga mungkin terjadi adalah suatu keadaan di mana penganalisis leksikal tidak dapat melanjutkan proses karena tidak satupun pola untuk token yang cocok dengan bagian awal input yang berikutnya. "Kemungkinan" untuk mengembalikan proses dari suatu kesalahan adalah:
1. Menghapus karakter yang berlebihan
2. Memasukkan karakter yang hilang
3. Mengganti karakter yang salah dengan karakter yang benar
4. Menukar letak dari dua karakter yang berdekatan.
Contoh program dengan bahasa C untuk menerjemahkan ekspresi infix ke dalam postfix.
*include <ctype.h> /* loads file with predicate is digit */ int lookahead;
{
lookahead = getchar(); expr();
putchar('\n'); /* adds trailing newline }
PENYANGGA INPUT
A
da tiga cara pendekatan umum yang dapat digunakan untukmengimplementasikan suatu penganalisis leksikal:
1. Menggunakan perangkat bantu pembentuk penganalisis leksikal. Misal, LEX yang merupakan bagian dari sistem operasi UNIX.
Perangkat ini dapat digunakan untuk membentuk suatu penganalisis leksikal berdasarkan suatu ekspresi-beraturan yang diberikan.
2. Menuliskan program untuk penganalisis leksikal dengan menggunakan suatu bahasa pemrograman yang biasa digunakan dengan memanfaatkan I/O dari bahasa tersebut untuk membaca input
PENGENALAN TOKEN
Salah satu untuk mengenali sebuah token, yaitu dengan metode
Automata Hingga (Finite Automata) atau Finite State Acceptor yang
disajikan berupa diagram atau graf berarah yang disebut Diagram Transisi
atau Graf Transisi atau Digraph.
¾
A
utomata Hingga dapat dibayangkan sebagai sebuah Mesin yang terdiridari Kepala Baca (Read Head), dan Kotak Kontrol Stata Hingga.
¾ Mesin ini membaca sebuah pita (tape), satu persatu karakter, dari kiri ke kanan, seperti gambar berikut:
¾ Pada saat Automata Hingga mulai membaca pita, ia harus selalu mulai
dari stata yang ditunjuk sebagai Stata Awal.
¾ Beberapa stata dapat ditunjuk sebagai Stata Akhir, atau Stata Penerima.
¾ Bila pembacaan dimulai dari Stata Awal, dan berjalan sesuai dengan
jalur hingga ke Stata Akhir, maka untai (deretan karakter) yang dibaca pada pita tersebut dikatakan diterima oleh Automata Hingga.
¾ Diagram Automata Hingga atau Diagram Transisi berbentuk Graf
Berarah (tanda anak panah), dengan tambahan beberapa notasi khusus.
Sebagai contoh adalah diagram berikut:
¾ Digraf Automata Hingga pada gambar tersebut menerima bilangan
Real, yang mempunyai paling sedikit satu digit sesudah titik desimal. Simpul dari Digraph tersebut menyatakan stata dari Automata Hingga.
¾ Stata pada Automata tersebut adalah Stata S, A dan B. Busur Digraph
menghubungkan satu stata ke stata lain, karakter yang tertera di atas atau di samping busur tersebut menunjukkan simbol/label input (simbol dari karakter input) yang menyebabkan terjadinya transisi stata.
¾ Jika terdapat busur mengarah dari Simpul P ke Simpul Q, dengan label
a, berarti bahwa terjadi transisi Stata P ke Stata Q bila terbaca a pada karakter pita (apabila memperoleh input karakter a).
¾ Anak panah berlabel "start" mengarah ke suatu Stata, menandakan
bahwa Stata tersebut merupakan Stata Awal. Dalam gambar di atas
Stata Awal adalah S, Stata Peralihan adalah A dan Stata Akhir adalah B yang disajikan berupa lingkaran ganda.
∗ Misalkan pita berisikan untaian karakter 112.75 (seratus dua belas koma
tuju lima). Automata Hingga mulai bekerja dari Stata S, yakni Stata Awal, dan tetap berada di Stata S ini saat bilangan di depan titik desimal dibaca. Ketika tanda titik (titik desimal) dibaca, Stata berpindah ke Stata A, dan kemudian berpindah lagi ke Stata B ketika digit pertama sesudah titik desimal (dalam contoh ini adalah digit 7) dibaca. Automata Hingga kemudian membaca digit berikutnya, yakni 5, dan tetap berada di Stata B. Sekarang akhir dari pembacaan Pita sudah tercapai. Penelusuran token berakhir di Stata B, yang adalah Stata Penerima atau Stata Akhir.
Ini berarti Automata Hingga menerima bilangan desimal yang
diberikan, yakni 112.75, sebagai sebuah token.
S A B
Start
digit
∗ Jika penelusuran tidak sampai pada Stata B saat sesudah untai selesai
dibaca seluruhnya, maka untai tersebut ditolak. Misalnya untai 112,
untai ini termasuk kasus yang ditolak karena tidak mencapai ke Stata Penerima (Stata Akhir). Penolakan dapat pula terjadi apabila Transisi Stata tidak dapat dilakukan untuk suatu karakter yang dibaca. Misalnya di antara digit tersebut terdapat huruf. Sebagai contoh untai yang ditolak adalah sbb.: X15.25 ataupun 112.H75.
∗ Automata Hingga yang digunakan dalam contoh di atas disebut
Deterministic Finite State Acceptor, atau Deterministic Finite State Automata, atau Automata Hingga Deterministik (AHD).
Berikut ini adalah contoh sebuah Automata Hingga Deterministik dengan 2 (dua) simbol input dan 3 (tiga) Stata.
VT = (a,b), himpunan simbol input
K = (q0, q1, q2) himpunan Stata
Z = (q0, q1), himpunan Stata penerima atau Stata akhir
Stata Awal adalah q0
Fungsi next-state f : K x VT Î K,
didefinisikan sebagai tabel berikut :
f a b
Stata Awal q0. Stata Akhir disajikan dengan lingkaran ganda.
Bila f(qi, aj) = qk, maka terdapat busur/anak panah dari qi ke qk
dengan label a.
Perlu dicatat bahwa Stata Awal dapat merangkap sebagai simpul penerima. Digraph pada contoh tersebut adalah sebagai berikut :
Misalkan, w = a1, a2,..., an adalah untai simbol input dari Automata M. Kita
dapatkan barisan Stata S0, S1, ..., Sn dengan S0 adalah Stata Awal, dan Si =
f(Si-1, ai) untuk i > 0.
Automata M dikatakan dapat menerima atau mengenal untai w tersebut,
jika Stata terakhir Sn merupakan Stata Penerima. Himpunan semua untai
Sebagai contoh, Automata di atas dapat menerima untai aabababa, aaa, baab
dan lain-lain untai lagi.
Sedangkan untai yang ditolak adalah untai yang mengandung 2 buah b berturutan sbb.:
bbaaaaaa, aabaabb, babbaa dan lain-lain.
Sebagai contoh lain dari Automata Hingga adalah sbb.
• Automata berisikan dua Stata, yakni Stata S dan A. Stata S adalah Stata
Awal dan Stata A merupakan Stata Akhir. Di sini terlihat bahwa kita akan tetap berada di Stata A saat Automata membaca sesuatu karakter atau digit ataupun karakter khusus pada himpunan {#, @, $, _}.
• Contoh lain yang lebih kompleks adalah pada gambar berikut. Contoh
ini juga berbentuk Diagram Stata Hingga yang menggambarkan Diagram Transisi untuk sebuah Bahasa yang terdiri dari Token <, <=, =, >=, >, ( ), (, ), +, -, *, /, :=, identifier, ; , keyword, konstanta, literal (yang diapit oleh apostrof).
• Komentar, yang dimulai dengan /* dan diakhiri dengan */, dan blank,
diabaikan, dan diartikan semata-mata sebagai pemisah Token.
• Busur berlabel "NOT" mendahului sebuah karakter, menunjukkan
bahwa semua karakter input selain dari karakter tadi, akan mengikuti transisi. Busur berlabel "ERROR" menunjukkan bahwa suatu karakter adalah invalid (tidak berlaku), yang ditemukan dalam program sumber. Karakter ini bukan merupakan suatu Token yang manapun, kecuali jika ia terdapat di dalam komentar, atau dalam lateral.
• Stata 5, 6, dan 7 digunakan untuk mengenali Token <, <=, dan <>. Jika bukan karakter = atau > mengikuti karakter <, maka Akseptor akan berakhir pada Stata Akhir 5, ini menunjukkan bahwa Token < telah terkenali. Dalam hal ini Token <= atau <> akan dikenali juga. Token <= bila Akseptor berakhir di Stata 6, atau Token <> bila berakhir di Stata 7.
• Dengan cara yang sama, masing-masing Stata 2, 3, dan 4 digunakan
komentar. Komentar tidak akan dikirim sebagai Token. Dan selanjutnya kembali ke Stata Awal.
• Stata 19 dan 22 digunakan berturut-turut untuk mengenali identifier dan
konstanta integer. Identifier dimulai dengan sebuah huruf dan diikuti sejumlah karakter alfanumerik. Konstanta merupakan sebarisan digit, yang dianggap satu Token sampai suatu karakter non numerik terbaca.
• Stata 20 dan 21 mengidentifikasi untai literal. Literal dimulai dan
diakhiri dengan tanda apostrof ( ' ), dengan Stata Akhir 21 menunjukkan akhir dari literal.
• Dua tanda apostrof yang berturutan dapat digunakan untuk menyatakan
Pertanyaan dan Soal Latihan
1. Sebutkan tugas utama dari penganalisis leksikal, dan jelaskan
interaksinya dengan bagian kompilasi yang lain.
2. Apa yang dimaksudkan dengan Token, Pola dan Lexeme. Jelaskan
dengan memberikan contoh.
3. Penganalisis leksikal juga berfungsi untuk menghilangkan baris
komentar yang ada dalam program. Jelaskan bagaimana mekanismenya.
4. Tuliskan subprogram scanner dari Digraf Automata Hingga di atas ini
untuk mengenali Token. Subprogram dapat berbentuk procedure
ataupun function yang ditulis menggunakan bahasa pemrograman
Pascal atau C. Token apa saja yang dikenal oleh Digraf tersebut.