Anda di halaman 1dari 89

BAB I

PENGENALAN

Bahasa

Menurut kamus dewan,

1. Kaedah bagi menyampaikan pendapat, perasaan dan hasrat melalui sistem


lambang-lambang bunyi.
2. Bentuk bahasa yang digunakan oleh sesuatu bangsa
3. Cara menggunakan kata-kata
4. Kata-kata yang digunakan oleh sesuatu golongan orang; istilah legal bahasa
undang-undang

Bahasa Pengaturcaraan

Bahasa pengaturcaraan merupakan bahasa yang digunakan untuk mengarahkan


komputer menyelesaikan masalah.

Ia terbahagi kepada bahasa paras tinggi dan bahasa paras rendah.

Bahasa paras rendah atau bahasa mesin merupakan bahasa pengaturcaraan yang mula
digunakan oleh manusia untuk menyelesaikan masalah khususnya masalah dalam
bidang matematik. Ia adalah satu bahasa yang sukar difahami oleh manusia kerana
arahan dan pernyataan bahasa menggunakan sistem pernomboran binari iaitu
gabungan nombor 0 dan 1. Pada masa itu, bahasa ini sentiasa diubah suai supaya
manusia mudah menggunakannya. Maka, dalam perkembangannya, wujudlah bahasa
perhimpunan yang menggunakan istilah bahasa Inggeris yang mudah untuk arahan-
arahan seperti add, mul dan div.

Namun penggunaan arahan yang mudah masih lagi tidak memenuhi kemampuan
manusia untuk menguasai bahasa pengaturcaraan dengan mudah. Oleh kerana itu,
terciptalah bahasa pengaturcaraan yang menggunakan arahan bahasa tabii iaitu
bahasa Inggeris. Bahasa ini dinamakan sebagai bahasa paras tinggi kerana ia berada
di atas iaitu pada pandangan pengguna. Penggunaan bahasa ini mudah difahami oleh
manusia tetapi bahasa ini memerlukan mekanisma untuk menukarkan arahannya
kepada bahasa mesin semula kerana komputer hanya memahami bahasa mesin untuk
melaksanakan arahan tersebut. Mekanisma yang digunakan sebagai orang tengah
diantara bahasa mesin dengan bahasa pengaturcaraan paras tinggi dinamakan sebagai
pengkompil.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 1


Bahasa Pengaturcaraan Paras Tinggi

Aturcara Paras Tinggi adalah sesuatu bahasa yang berorientasikan-masalah (problem-


oriented).

Aturcara terbahagi kepada empat bahagian iaitu :

1. Bahasa Imperatif seperti Algol 60, Algol 68, Fotran, COBOL, Pascal dan C.
Bahasa ini mempunyai perlaksanaan mengikut struktur komputer von Neumann
yang mempunyai CPU, ingatan dan bas.

2. Bahasa fungsian seperti LISP dan HOPE. Bahasa ini mempunyai kategori seperti
berikut :
 Tiada perbezaan antara statements dan operasis.
 Nama digunakan sebagai hanya untuk mengenalpasti operasi dan
functions; tidak digunakan untuk mengenalpasti lokasi ingatan.

 Perlaksanaan bahasa ini adalah reduction; ia dinilai dengan menggantikan


operasis dengan suatu expresssion yang lebih mudah sehingga form yang
biasa dijumpai.

3. Bahasa Logik seperti Prolog. Bahasa ini adalah berasaskan kepada pandangan
operasi dan jangkaan kalkulus. Mekanisma resolution digunakan iaitu satu
tatacara untuk membaiki implikasi dalam first-order jangkaan kalkulus.

4. Bahasa Object-oriented seperti JAVA, C++.

Pembangunan Bahasa Pengaturcaraan

Penterjemah

Satu bahasa, L.
Input kepada penterjemah, IL adalah aturcara L iaitu PL dan input kepada PL pula
adalah e. Dalam masa yang sama IL perlu menghasilkan output, katakan e.

Pengkompil

Kaedah untuk menukarkan bahasa pengaturcaraan kepada bahasa mesin memerlukan


teknik yang baik dalam Sains Komputer supaya proses penterjemahan berkesan.
Istilah yang biasa digunakan adalah precomputation, partial evaluation atau mixed
computation.

Dua kaedah yang diguna-pakai sejak dahulu adalah penterjemah (interpreter) dan
pengkompil (compiler). Kedua-dua kaedah ini merupakan perisian yang menerima

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 2


aturcara yang ditulis oleh pengguna sebagai input. Oleh kerana itu, lain Bahasa
pengaturcaraan mempunyai penterjemah atau pengkompil yang berbeza.

Perterjemah terima input, proses dan laksankan input tersebut pada masa yang sama.
Pengkompil pula mempunyai beberapa peringkat pemprosesan sebelum melaksana
input tersebut. Input dianalisa tanpa melibatkan input data kepada aturcara pengguna
dan kemudian ditukarkan kepada bentuk objek untuk menjadikan perlaksanaan
aturcara yang lebih berkesan. Objek ini akan digunakan untuk perlaksanaan aturcara
sebenar yang akan melibatkan data input kepada aturcara tersebut.
Proses pengkompilasi melibatkan aktiviti :

Menterjemah aturcara sumber (kompil), PL kepada bahasa mesin atau pengkompil, M


Masa pengkompilasi ini dinamakan sebagai compile time dan aturcara yang
diperolehi, Pm yang bergantung kepada PL dinamakan sebagai aturcara objek.

Aturcara objek, PM dilaksanakan dengan input aturcara, e selepas compile time


dinamakan sebagai run time. Biasanya ia mudah menghasilkan keputusan kerana ralat
telah dijumpai pada masa kompil. Maka IL (PL, e) = a. a adalah output aturcara.

Analisis Aturcara Sumber

Dalam pengkompil, analisis terbahagi kepada tiga fasa, iaitu :

1. Analisis Linear : jujukan karakter yang membina aturcara sumber, dibaca


daripada kiri ke kanan untuk dikumpulkan kepada satu kumpulan yang
dinamakan token. Token adalah kumpulan karakter yang mempunyai
maksudnya sendiri.

2. Analisis Hirarki : Karakter atau token-token dikumpul secara hiraki kepada


satu koleksi tersarang dengan makna yang tersendiri.

3. Analisis semantik, beberapa semakan dilakukan untuk memastikan


komponen-komponen aturcara boleh digabungkan untuk menjadi sesuatu
yang bermakna.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 3


Fasa-fasa Pengkompilasi
Gambarajah 2.1 menunjukkan fasa-fasa dalam pengkompilasi.
Aturcara Sumber

Penganalisa Leksikal

Penganlisa Sintaksis

Penganalisa Semantik

Pengendali
Pengurus Ralat
Jadual Penjana Kod Pertengahan
Simbol

Pengoptimum

Penjana Kod

Analisis Leksikal

Dalam pengkompil, analisis linear ini dipanggil sebagai analisis leksikal atau
scanning (pengimbas). Sebagai contoh, dalam analisis leksikal karakter dalam
pernyataan umpukkan :

A = B + Kadar * 50;

Pengimbas akan mengumpul karakter kepada token-token :

1. Pencam A
2. Simbol umpukkan =
3. Pencam B
4. Tanda tambah
5. Pencam Kadar
6. Tanda darab
7. Nombor 50

Ruang kosong antara karakter biasanya diabaikan pada masa analisis ini.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 4


Analisis Sintaks

Analisis hirarki dipanggil parsing atau analisis sintaks. Ia melibatkan proses


mengumpulkan token-token daripada aturcara sumber kepada frasa nahu yang
digunakan oleh pengkompil untuk menghasilkan output yang dengan binaan yang
sah. Biasanya frasa nahu diwakilkan dengan satu pokok nahu seperti yang
ditunjukkan dalam rajah di bawah :

Dalam operasi B + Kadar * 50, frasa Kadar * 50 adalah unit logikal kerana dalam
peraturan arithmetik, operasi pendaraban dilakukan dahulu sebelum penambahan.
Oleh kerana operasi B + Kadar diikuti dengan tanda *, maka oleh kerana itu, ia tidak
dikumpulkan dalam satu frasa.

Dalam struktur hirarki suatu aturcara, aturcara selalunya dinyatakan oleh peraturan
rekursif. Sebagai contoh,

1. Sebarang pencam adalah satu operasi


2. Sebarang nombor adalah satu operasi
3. Jika operasi1 dan operasi2 adalah operasi, maka,
Operasi1 + operasi2
dan
Operasi1 * operasi2
Juga adalah operasi

Peraturan (1) dan (2) adalah peraturan nonrekursif. Manakala (3) mendefinisikan
operasi dalam keadaan tanda operator digunakan pada operasi lain. Dengan peraturan
(2), 50 adalah operasi dan peraturan (3), Kadar * 50 adalah operasi maka akhirnya B
+ Kadar * 50 adalah satu operasi.

Analisis Semantik

Analisis ini menyemak aturcara sumber untuk ralat semantik (logik). Ia akan
mengumpul jenis maklumat dalam aturcara untuk analisis yang seterusnya iaitu
penjana kod pertengahan. Ia mempunyai 2 rutin iaitu :

1. Menyemak semantik statik bagi satu binaan (struktur daripada analisis semantik)
iaitu ia menguji sama ada sesuatu binaan itu sah dan bererti.
2. Melakukan terjemahan sebenar bagi binaan tersebut.

Contoh,

Ungkapan X = Y + Z

Semantik melaksanakan aktiviti berikut :


1. Pastikan semua pembolehubah telah diistiharkan
2. Pastikan Y dan Z mempunyai jenis yang sama dengan X.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 5


Penjana Kod Pertengahan

Ia adalah rutin untuk mencipta aliran kod pertengahan iaitu kod yang menghampiri
bahasa mesin. Biasanya ia menggunakan arahan dengan satu operator dan beberapa
operan.

Contoh :

Tambah X Y atau ADD X Y

Setara dengan { X  X + Y }

Arahan di atas sama dengan arahan Bahasa Perhimpunan seperti berikut :

MUAT X {AKU  X }
TAMBAH Y {AKU  AKU + Y }
STOR X {X  AKU}

Perbezaan utama antara kod pertengahan dengan kod perhimpunan adalah kod
pertengahan tidak perlu menyebut daftar-daftar yang digunakan untuk setiap operasi.

Daftar adalah lokasi ingatan dalam CPU. Daftar akumulator digunakan untuk operasi
arithmetik dalam CPU.

PENGOPTIMUMAN KOD

Ia adalah fasa untuk membaiki kod pertengahan supaya untuk mendapatkan kod yang
lebih berkesan supaya masa larian yang lebih cepat.

Fasa ini tidak digunakan oleh semua pengkompil.

PENJANA KOD

Fasa ini menjanakan kod objek iaitu kod bahasa mesin.

Ia memberikan lokasi bagi data, memilih kod untuk mencapai setiap data dari lokasi
dan memilih daftar tertentu untuk setiap operasi yang dilaksanakan.

Contoh perlaksanaan lengkap satu pengkompil :

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 6


A = B + Kadar * 50;

Analisis leksikal

id1 = id2 + id3 * 50

Penganalisis sintaks

=
+
id1 id2 *

id3 60

Analisis semantik

=
+

id1 id2 *
inttofloat
id3 60

Penjana kod pertengahan

temp1 = inttofloat (60)


temp2 = id3 * temp1
temp3 = id2 + temp2
id1 = temp3

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 7


Pengoptimuman kod

temp1 = id3 * 60.0


Id1 = id2 + temp1

Penjana kod

MULF id3, R2
MULF #60.0, R2
MOVF id2, R1
ADDF R2, R1
MOVF R1, id1

Penggunaan operan dua kod ini iaitu kod yang pertama dan yang kedua, setiap arahan
bermaksud sumber dan destinasi.

Lain-lain Perisian-perisian Pengkompil

1. Pra-pemproses
2. Penghimpun
3. Penghimpun dua pas
4. Pemuat dan pemaut

Contoh pengkompil satu laluan

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 8


BAB II

Pemproses Bahasa Pengaturcaraan (Pengkompil) Mudah

Pengenalan

Dalam bahagian ini kita melihat bagaimana satu pengkompil melaksanakan tugasnya
memproses bahasa pengaturcaraan. Kita juga menganalisis secara ringkas bagaimana
sintaks bahasa pengaturcaraan dibangunkan mengikut Rumus Nahu Bebas-Konteks
(Context Free Grammar (CFG)) atau BNF (Backus-Naur Form).

Oleh kerana tugas utama dalam memproses bahasa adalah untuk menterjemah bahasa,
maka dalam bahagian ini kita akan menggunakan kaedah menterjemah bahasa
berpandukan kepada sintaks iaitu, CFG.

Definisi Sintaks

Satu nahu menghuraikan struktur hiarki bahasa pengaturcaraan. Sebagai contoh


pernyataan if-else dalam C mempunyai pembentukkan :

if (ungkapan) pernyataan else pernyataan

Dalam pembentukkan if-else, pernyataan disambung daripada katakunci if, diikuti


dengan buka kurungan, ungkapan, tutup kurungan, pernyataan dan katakunci else
diikuti dengan pernyataan lain.

Sintaks ini boleh diwakili dengan perwakilan :

pern  if (ungkp) pern else pern

Anak panah mewakili perkataan “mengeluarkan”. Bentuk sintaks yang ditunjukkan


dipanggil pengeluaran. Dalam pengeluaran, elemen leksikal seperti katakunci if dan
kurungan dipanggil sebagai token.

Penbolehubah seperti ungkp dan pern mewakili token-token yang dipanggil non-
terminal.

Dalam suatu pengeluaran, elemen leksikal seperti katakunci if dan kurungan


dipanggil sebagai token. Pembolehubah seperti unkp dan pern memwakili jujukan
token-token yang dipanggil sebagai nonterminal.

Nahu bebas-konteks mempunyai empat komponen :

1. Set token yang dikenali sebagai simbol terminal


2. Set nonterminal

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 9


3. Set pengeluaran iaitu setiap pengeluaran mengandungi satu nonterminal di
sebelah kiri pengeluaran , anak panah dan jujukan token bersama-sama
nonterminal atau mungkin token sahaja.
4. Satu nonterminal sebagai simbol mula.

Contoh :

senarai  senarai + digit


senarai  senarai – digit
senarai  digit
digit  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

(nahu 1)

tiga pengeluaran yang paling atas boleh disatukan menjadi

senarai  senarai + digit | senarai – digit | digit

Berdasarkan kepada pengeluaran di atas, token untuk nahu di atas adalah

+-0123456789

dan nonterminal adalah senarai dan digit.

Pengeluaran untuk nonterminal wujud jika nonterminal muncul pada sebelah kiri
pengeluaran. Satu string mengandungi sifar token, yang ditulis sebagai , dipanggil
sebagai string nol.

Satu nahu mengeluarkan string dengan dimulai oleh simbol mula dan berterusan
dengan menggantikan nonterminal pada sebelah kanan pengeluaran untuk
nonterminal tersebut. Token string yang boleh dikeluarkan daripada simbol mula
membentuk bahasa yang didefinisikan oleh nahu.

Contoh:

Bahasa yang dinyatakan dalam rumus nahu 1 adalah bahasa yang mengandungi
senarai digit yang diasingkan dengan tanda tambah dan tolak. Kita uji 9-5+2 dengan
nahu tersebut untuk menentukan ia adalah bahasa yang sah atau tidak mengikut
rumus nahu ini.

1. 9 adalah senarai mengikut pengeluaran senarai  digit


digit  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

2. 9 - 5 adalah senarai mengikut pengeluaransenarai  senarai - digit


senarai  digit
digit  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 10


2. 9-5+2 adalah senarai mengikut pengeluaran, senarai  senarai – digit
senarai  senarai + digit
senarai  digit
digit  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
|9

Huraian ini boleh digambarkan seperti dalam gambarajah pokok dalam rajah 2.0 di
bawah. Setiap nod pada pokok dilabelkan oleh simbol nahu.

senarai

senarai digit

senarai digit

digit

9 - 5 + 2

Rajah 2.0

Pokok di atas merupakan sejenis pokok penghurai. Daripada rajah didapati bahawa
senarai sebagai akar mempunyai anak kiri iaitu senarai dan anak kanan digit. Anak
kiri pula mempunyai anak kiri dan anak kanan iaitu senarai dan digit. Pokok ini
dibincangkan dengan lebih lanjut dengan contoh berikut :

blok_atur  { pern_pilihan }
pern_pilih  senarai_pern | 
senarai_pern  senarai_pern ; pern | pern

(nahu 2)

Nahu 2 adalah contoh pembinaan mudah bahasa pengaturcaraan C. Perhatikan


bahawa pilihan yang mungkin pada sebelah kanan pernyataan pilihan (pern_pilihan)
adalah  (nul).

POKOK SINTAKS

Pokok penghurai menggambarkan bagaimana simbol mula satu nahu menghasilkan


string dalam satu Bahasa. Jika satu nonterminal A mempunyai pengeluaran A 
XYZ, maka satu pokok sintaks mempunyai nod dalaman yang dilabelkan dengan A
bersama tiga anak yang dilabel sebagai X, Y dan Z daripada kiri ke kanan.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 11


A

X Y X

Secara formal, nahu bebas konteks mempunyai pokok sintaks dengan ciri-ciri yang
berikut :

1. akar dilabel oleh simbol mula


2. setiap daun dilabel dengan satu token atau dengan 
3. setiap nod dalaman dilabelkan dengan nonterminal.
4. Jika A adalah satu nonterminal yang melabel beberapa nod dalaman dengan X1,
X2, ….Xn adalah label untuk anak nod dari kiri ke kanan, maka A  X1X2…Xn
adalah satu pengeluaran. Ini bermakna X1, X2, …, Xn mewakili sama ada simbol
terminal atau simbol nonterminal. Jika A   maka satu nod dilabel sebagai A
boleh mempunyai anak tunggal yang dilabel sebagai .

Dalam rajah pokok di atas, akar pokok dilabelkan sebagai senarai, iaitu simbol mula
nahu. Anak dilabel daripada kiri ke kanan, senarai, + dan digit. Pokok sintaks akan
membantu pengkompil mengenal pasti SEMANTIK bahasa pengaturcaraan.

Ambiguiti

Satu nahu boleh mempunyai lebih daripada satu pokok huraian. Nahu ini dikatakan
sebagai nahu berambiguiti. Untuk menunjukkan sesuatu nahu itu berambiguiti, kita
perlu uji nahu tersebut dengan pokok huraian.

Contoh :

ren  ren + ren | ren –ren | 0 |1 | 2| 3| 4| 5| 6| 7| 8| 9

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 12


Pokok Penghurai untuk ungkapan 9-5+2 :

ren dan ren

ren + ren ren - ren

ren - ren 2 9 ren + ren

9 5 5 2

Contoh Pengkompil

Diberi pengeluaran :

unkp  unkp + term | unkp – term | term


term  term * faktor | term / faktor | faktor
faktor  pencam | pemalar | (unkp)

Jika input pengkompil adalah pernyataan : b*b – 4*a*c, maka hasil daripada operasi
leksikal adalah :

[pencam,b] * [pencam,b]-[pencam,4]*[pencam,a]*[pencam,a]

Kemudian pokok penghurai yang diperolehi adalah :

unkp

unkp - term

term term * faktor

term * faktor term * faktor pencam

faktor pencam faktor pencam c

pencam b pencam a

b 4

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 13


Kesatuan Operator

Oleh kerana dengan lebih daripada satu pokok huraian akan menghasilkan lebih
daripada satu maksud, maka, pengkompil perlu merekabentuk satu nahu yang tidak
berambiguiti.

Ini dilakukan dengan peraturan seperti kesatuan operator dan keutamaan operator.
Kesatuan operator bermaksud perlaksanaan adalah mengikut daripada kiri ke kanan.

Dalam pengaturcaraan, perlaksaan arithmetik adalah daripada kiri ke kanan


sementara umpukkan adalah daripada kanan ke kiri. Terdapat empat operator
arithmetik dalam pengaturcaraan yang kesatuan ke kiri, iaitu, tambah, tolak, darab
dan bahagi. Operator umpukkan dalam C adalah kesatuan ke kanan. Sebagai contoh :

Ungkapan a = b = c adalah sama seperti a = ( b = c )

Perbezaan antara operator kesatuan kanan dengan operator kesatuan kiri ditunjukkan
dalam rajah pokok penghurai berikut :

sen kanan

sen + digit huruf = kanan

sen - digit 2 a huruf = kanan

digit 5 b c

Keutamaan Operator

Keutamaan operator menentukan pernyataan yang mana perlu diselesaikan terlebih


dahulu.

Sebagai contoh jika 9 + 10 * 5, kesatuan + dan * tidak menyelesaikan masalah


ambiguiti. Aturcara perlu menyelesaikan 10*5 dahulu dan hasilnya akan ditambah
dengan 9.

Dengan ini, kita perlu tahu keutamaan operator. Operator ‘*’ dikatakan mempunyai
keutamaan yang lebih tinggi daripada operator ‘+’.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 14


Ungkapan Sintaks

Nahu untuk satu ungkapan arithmetik boleh dibina daripada jadual keutamaan dan
kesatuan operator-operator. Berikut adalah adalah susunan operator yang mempunyai
sama keutamaan dan kesatuan :

Kesatuan kiri : + -
Kesatuan kiri : * /

Kita bina non-terminal unkp dan term untuk dua paras keutamaan dan tambahan non-
terminal faktor untuk menjana unit asas dalam ungkapan.

faktor  digit | ( unkp )

Kita anggap operator ‘*’ dan ‘/’ mempunyai keutamaan paling tinggi,

term  term * faktor | term/faktor | faktor

Dan,

unkp  unkp + term | unkp – term | term

Peraturan-peraturan di atas akan menjana nahu,

unkp  unkp + term | unkp – term | term


term  term * faktor | term / faktor | faktor
faktor  digit | ( unkp )

ANALISIS SEMANTIK

Tujuan adalah untuk menguji maksud dan kesahihan binaan bahasa.

Pokok Sintaks

Pokok sintaks merupakan satu struktur data yang menunjukkan dengan jelas
bagaimana satu segmen aturcara boleh dilihat dari sudut NAHU. Menggunakan
pengeluaran bahasa di atas, dengan input pengkompil : b*b – 4*a*c, maka hasil
daripada operasi semantik kita perolehi satu pokok sintaks seperti berikut :

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 15


-

* *

b b * b

4 a

Jenis : float
Lok : daftar 1
-

* Jenis : float * Jenis : float


Lok : daftar 1 Lok : daftar 2

b b c jenis: float
Jenis : float Jenis : float * lok : sp + 24
Lok : sp + 16 Lok : sp + 16 jenis : float
lok : daftar 2
4 a
jenis : float jenis : float
lok : pemalar lok : pemalar

Penterjemahan berpandukan sintaks

Dalam bahagian ini, kita akan cuba untuk menterjemah bahasa mengikut
petunjuk/petua Nahu Bebas Sintaks.

Untuk menterjemah satu binaan bahasa pengaturcaraan, satu pengkompil perlu untuk
menjejaki beberapa perkara selain daripada penjanaan kod. Sebagai contoh,
pengkompil perlu tahu 3 elemen iaitu :

1. jenis binaan, atau


2. lokasi arahan pertama dalam kod sasaran, ataupun
3. bilangan arahan yang dijana.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 16


Tiga contoh elemen ini dinamakan sebagai atribut yang berkaitan dengan pembinaan.
Satu atribut mewakili kuantiti seperti jenis, string, lokasi ingatan dan sebagainya. Kita
uji penterjemahan ini untuk menterjemah ungkapan infix kepada notasi postfix.

Notasi Postfix

Satu notasi postfix untuk ungkapan E boleh didefinisikan seperti berikut :

1. Jika E adalah satu pembolehubah atau pemalar, maka notasi postfix baginya
adalah E sendiri.
2. Jika E adalah ungkapan dalam bentuk E1 op E2, dimana op adalah operator
binari, maka notasi postfix untuk E adalah E1’E2’op, dimana E1 dan E2 adalah
notasi postfix untuk E.
3. Jika E adalah ungkapan dalam bentuk (E1), maka notasi postfix untuk E1 adalah
juga postfix untuk E.

Kurungan tidak diperlukan dalam notasi postfix kerana kedudukan operator


menunjukkan perlaksaan ungkapan. Sebagai contoh, (9-5) + 2 adalah 95-2+ dan 9 –
(5+2) adalah 952+-

Definisi

Perterjemahan berpandukan sintaks menggunakan nahu bebas konteks adalah


bertujuan untuk menguji struktur semantik suatu input pengkompil. Dengan setiap
simbol nahu, ia adalah bersekutu dengan set atribut, dan dengan setiap pengeluaran,
set peraturan semantik untuk nilai aktiviti komputer adalah berkaitan dengan simbol-
simbol yang berada pada pengeluaran. Nahu dan peraturan semantik menghasilkan
sintak.

Satu penterjemahan adalah suatau pemetaan input-output. Output untuk setiap input x
dihasilkan dengan beberapa langkah berikut :

Bina satu pokok huraian untuk x.


Andaikan a sebagai nod n dalam pokok penghurai dilabelkan oleh nahu
simbol X.
Ia akan ditulis sebagai X.a untuk mewakilkan nilai untuk atribut a daripada X
pada nod tersebut.
Nilai untuk X.a pada n, diproses menggunakan peraturan semantik untuk
atrribut a yang bersekutu dengan pengeluaran X yang digunakan di nod n.
Pokok penghurai akan menunjukkan nilai atribut pada setiap nod yang
dipanggil sebagai satu pokok huraian penerangan.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 17


Pememprosesan (Synthesized)

Satu atribut dikatakan akan disynthesized jika nilainya pada nod pokok huraian
dikenalpasti daripada nilai atribut pada anak nod tersebut. Proses ini mempunyai
keupayaan untuk dinilai pada masa penjelajahan bawah-atas pokok huraian. Sebagai
contoh :

Satu definisi sintaks untuk menterjemah ungkapan yang mengandungi digit yang
dipisahkan oleh tanda tambah(campur) atau tanda kurang(tolak) kepada notasi
postfix.
Ini ditunjukkan dalam rajah di bawah :

Pengeluaran Peraturan semantik


unkp  unkp1 + term unkp.t = unkp1.t || term.t || “+”
unkp  unkp1 – term unkp.t = unkp1.t || term.t || “-”
unkp  term unkp.t = term.t
term  0 term.t = ‘0’
: :
term  9 term.t = ‘9’

Daripada rajah didapati bahawa atribut t digunakan untuk mewakilkan notasi postfix
untuk ungkapan yang dijana oleh nonterminal dalam pokok huraian.

Postfix yang terbentuk daripada digit adalah digit itu sendiri. Sebagai contoh,
peraturan semantik yang bersekutu dengan pengeluaran term  9 mendefinisikan
term.t menjadi 9 dimana sahaja pengeluaran tersebut berada dalam pokok.

Bila pengeluaran unkp  term digunakan, nilai untuk term.t menjadi nilai untuk
unkp.t.

Pengeluaran unkp  unkp1 + term menghasilkan satu ungkapan yang mengandungi


satu operator tambah. Pada sebelah kiri operan operator tambah adalah unkp1 dan
pada sebelah kanan operan adalah term.

Peraturan semantik menjadi :

unkp.t = unkp1.t || term.t || “+”

Peraturan ini berkaitan dengan pengeluaran yang menyatakan nilai atribut unkp.t
yang bercantum dengan bentuk postfix unkp1.t dan term.t pada sebelah kiri dan
kanan operan-operan. Operator || dalam peraturan semantik mewakili string
concatenation (cantum).

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 18


Gambarajah di bawah menunjukkan satu pokok huraian (penjelasan) yang berkenaan
dengan pokok.

unkp.t = 95-2+

unkp.t = 95- term.t = 2

unkp.t = 9 term.t = 5

term.t = 9

9 - 5 + 2

Jelajah dalam dahulu

Satu definisi sintaks-berpandu tidak semestinya mempunyai satu cara yang tetap
untuk menilai atribut pada satu pokok huraian.

Secara am, kita perlu menilai atribut pada masa nod pertama ditemui atau setelah
semua anak dijelajah atau pada satu titik antara anak dan nod, iaitu pada masa
penjelajahan pokok.

Perterjemahan dalam kursus ini boleh dilakukan dengan menilai peraturan semantik
untuk semua atribut dalam pokok huraian menggunakan langkah pra-jangkaan.

Satu jelajah pokok bermula di akar dan ia akan melawat semua nod dalam pokok
dalam langkah yang tertentu.

Alkhawarizmi untuk penjelajahan ini ditunjukkan berikut :

void visit( nod n)


{
for (setiap nod, daripada kiri ke kanan)
visit(m);
nilai peraturan semantik di nod n;
}

Alkhawarizmi ini menunjukkan bahawa ia bermula di root dan secara rekursif


melawat anak pada setiap nod secara kiri ke kanan. Peraturan semantik pada nod

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 19


dinilai setelah semua nod-nod sebelumnya telah dilawati. Ini dipanggil “kedalaman
dahulu” kerana ia melawat anak-anak yang paling jauh daripada akar selagi ia belum
dilawati.

Skema Penterjemahan

Skema ini adalah satu spesifikasi untuk mendefinisikan penterjemahan. Ia adalah satu
nahu bebas konteks dimana satu fragment aturcara yang dipanggil sebagai tindakan
semantik berada di sebelah kanan pengeluaran.

Ia bertindak seperti sintaks-berpandu, kecuali jujukan penilaian untuk peraturan


semantik ditunjukkan dengan jelas. Kedudukan satu tindakan untuk dilaksanakan
ditunjukkan dalam kurungan dan ditulis pada sebelah kanan pengeluaran seperti
berikut :

rest  + term { print(‘+’) } rest1

Skema penterjemahan menjana output untuk setiap ayat x yang dijana oleh nahu yang
dinyatakan dengan melaksanakan tindakan mengikut jujukan yang diperolehi pada
masa penjelajahan kedalaman dahulu untuk satu pokok huraian x.

Sebagai contoh, andaikan satu pokok huraian yang dilabel rest mewakili satu
pengeluaran. Tindakan {print(‘+’)} akan dilaksanakan setelah anak pokok term
dijelajah tetapi sebelum anak untuk rest1 dilawati.

Mencetak Hasil Penterjemahan

Hasil ini adalah untuk menulis ouput penterjemahan ke dalam satu fail, iaitu string
atau karakter. Sebagai contoh, untuk menterjemah 9-5+2 kepada 95-2+ dengan
mencetak setiap karakter dalam 9-5+2 tanpa menggunakan ruang ingatan untuk
melakukannya. Apabila bilangan output yang dicetak bertambah, kedudukan atau
susunan karakter yang dicetak amat penting untuk memastikan maknanya.

Seperti mana yang telah dinyatakan dalam definsi sintaks-berpandu, satu string
mewakili penterjemahan satu nonterminal pada sebelah kiri setiap pengeluaran
dicantum oleh penterjemahan nonterminal pada sebelah kanan.

Lihat contoh pengeluaran dan peraturan semantik yang telah dinyatakan sebelum ini :

Pengeluaran Peraturan semantik


unkp  unkp1 + term unkp.t = unkp1.t || term.t || ‘+’

Daripada contoh di atas, dapat dilihat bahawa penterjemahan unkp.t dicantum dengan
penterjemahan unkp1 dan term, diikuti dengan simbol +. Didapati bahawa unkp1
muncul sebelum term pada sebelah kanan pengeluaran.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 20


Satu string tambahan muncul diantara term.t dan rest1.t dalam

Pengeluaran Peraturan semantik


rest  + term rest1 rest.t = term.t || ‘+’ || rest1.t

Namun, nonterminal term tetap muncul sebelum rest1 pada sebelah kanan.

Cara paling mudah untuk mengimplementasikan penterjemahan adalah dengan


menambah tindakan print dalam tertib. Sebagai contoh :

unkp  unkp1 + term1 { print(‘+’) }


rest  + term {print (‘+’) } rest1

Berikut adalah skema penterjemahan yang dihasilkan daripada definisi yang telah
dinyatakan dalam rajah di atas. Ia adalah berasaskan kepada pengeluaran :

unkp  unkp + term { print(‘+’) }


unkp  unkp – term { print(‘-’) }
unkp  term
term  0 { print(‘0’) }

term  9 { print(‘9’) }

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 21


Berikut pula adalah pokok sintaks dengan tindakan untuk 9-5+2.

unkp {print(‘+’)}

unkp {print(‘-’)} term

unkp term

term

{print(‘9’)} {print(‘5’)} {print(‘2’)}


9 - 5 + 2

Aturcara Pengkompil Mudah

Diberi pengeluaran berikut :

unkp  digit | ( unkp op unkp )


op  + | *
digit  0 | 1 | 2 | 3 | ….| 9

Nahu ini membenarkan pernyataan seperti (5 + 8) , dan (2 * ( 5 * 5 ) + 17)).

#include “parser.h”
#include “backend.h”
#include “error.h”

int main(void) {
AST_node *icode;

if (!parse_program(&icode)) Error(“No top-level


expresion”);
process(icode);
return 0;

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 22


Fail untuk lex.h

//Define class pemalar


// Nilai 0-255 di rezabkan untuk aksara ASCII)

#define EOF 256


#define DIGIT 257
typedef struct {
int class;
char repr;
} Token_type;

extern Token_type Token;


extern void get_next_token(void);

Aturcara untuk Analisis Leksikal :

#include “lex.h”

static int Layout_char(int ch) {


switch (ch) {
case ‘ ‘ :
case ‘\t’;
case ‘\n’:
return 1;
default: return 0;
}
}

Token_type Token;

void get_next_token(void) {
int ch;
do {
ch = getchar();
if (ch < 0)
Token.class = EOF;
Token.repr = ‘#’;
Return;
}
} while (Layout_char(ch));

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 23


if (‘0’ <= ch && ch <= ‘9’)
{
Token.class = DIGIT;
} else {
Token.class = ch;
}
Token.repr = ch;

Rutin Penghurai (Analisis Sintaks)

static int Parse_operator(Operator * oper) {


if (Token.class = = ‘+’) {
*oper = ‘+’;
get_next_token();
return 1;
}
if (Token.class = = ‘*’) {
*oper = ‘*’ ;
get_next_token();
return 1;
}
return 0;

static Parse_expression(Expression **expr_p)


{
Expression *expr = *expr_p = new_expression();
if (Token.class = = DIGIT) {
expr  type = ‘D’;
expr  value = Token.repr – ‘0’;
get_next_token();
return 1;
}

if (Token.class = = ‘(‘ ) {
expr  type = ‘P’;
get_next_token();
if (!Parse_expression(&exprleft)) {
Error(“Missing Expression”);
}

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 24


if (!Parse_operator(&expr oper)) {
Error(“Missing operator”);
}
if (!Parse_expression(&exprright)) {
Error(“Missing Expression”);
}
if (Token.class != ‘)’) {
Error(“Missing )”);
}

get_next_token()
return 1;
}
//percubaan gagal

free_expression (expr);
return 0;
}

Aturcara Panggilan Rutin Penghurai :

#include “lex.h”
#include “error.h”
#include “parser.h”

static Expression *new_expression(void)


{
return (Expression *) malloc (sizeof (Expression));
}

static void free_expression(Expression *expr)


{
free ((void *) expr);
}

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 25


static int Parse_operator(Operator *oper_p);
static int Parse_expression(Expression **expr_p);

int Parse_program(AST_node **icode_p) {


Expression *expr;

get_next_token();
if (Parse_expression(&expr))
{
if (Token.class != EOF ) {
Error(“Garbage after end of program”);
}
*icode_p = expr;
return 1;
}
return 0;
}

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 26


BAB III

Analisis Leksikal

Teknik yang digunakan untuk mengimplementasikan penganalisis leksikal boleh juga


digunakan dalam bidang seperti bahasa pertanyaan (query language) dan sistem
capaian maklumat (information retrieval).

Corak ini diterangkan menggunakan oleh simbol yang dinamakan ungkapan regular.
Satu cara yang paling mudah untuk membangunkan penganalisa Leksikal adalah
dengan membangunkan rajah yang menggambarkan struktur token. Bahasa AWK
menggunakan ungkapan regular untuk memilih baris input dan sistem shell UNIX
membenarkan pengguna untuk merujuk kepada nama fail dalam direktorinya
menggunakan ungkapan regular. Arahan rm *.o sebagai contoh digunakan untuk
menghapuskan semua fail yang mempunyai sambungan .o

Tugas Penganalisa Leksikal

Penganalisa leksikal merupakan fasa yang pertama dalam proses kompilasi. Tugasnya
yang paling utama ialah membaca aksara input dan menghasilkan jujukan token yang
digunakan oleh penghurai untuk melakukan analisis sintaks.

Model analisis leksikal dalam pengkompil ditunjukkan seperti berikut :

token

Aturcara Penganalisa penghurai


sumber Leksikal

Token
seterusnya

Jadual
Simbol

Penganalisa boleh boleh dibahagikan kepada dua fasa iaitu pengimbas dan analisis
leksikal.

Aktiviti Dalam Analisis Leksikal

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 27


Terdapat beberapa perkara yang menyebabkan pengkompil membahagikan proses
kepada dua fasa. Ini disebabkan :

1. Pemisahan proses kepada sub-proses untuk kemudahan kefahaman. Pemisahan


analisis leksikal dengan analisis sintaks membenarkan kefahaman yang lebih.
Sebagai contoh, Satu penghurai tidak memahami komen dan ruangan kosong
dalam aturcara. Tanda tersebut perlu dihapuskan oleh penganalisa leksikal.

2. Keberkesanan pengkompil dapat dipastikan. Pemisahan membenarkan pembinaan


aturcara yang menumpu kepada satu aktiviti yang khusus sahaja. Masa yang lama
diperlukan untuk membaca aturcara sumber dan menukarkannya kepada bentuk
token. Penumpuan terhadap teknik penyimpanan apabila membaca dan
mengenalpasti token boleh meningkatkan lagi masa pemprosesan pengkompil.

3. Pengkompil memerlukan perubahan jika terdapat penambahan peraturan bahasa.


Aksara input adalah terhad kepada peraturan penganalisa lekasikal. Jika aksara
ditambah dalam penggunaan bahasa, maka ini akan menyebabkan masa untuk
pembinaan pengkompil juga memakan masa.

Token, Corak dan Lexeme

Dengan analisis leksikal kita menggunakan istilah “token”, “corak” dan “lexeme”
dengan maksud yang khusus. Ini ditunjukkan dalam jadual berikut :

Token Lexeme Penerangan corak


pemalar Pemalar pemalar
if If if
hubungan <, <=, = =, !=, > , >= < atau <= atau = = atau != atau > atau >=
id i, pi, nmax aksara diikuti oleh aksara atau digit
num 3.14, 5, 6.02e23 pemalar numerik
literal “core dumped” sebarang aksara antara “dan” kecuali “

Corak merupakan peraturan string yang boleh ada dalam aturcara. Lexeme adalah
jujukan aksara dalam aturcara sumber yang padan dengan corak suatu token. Contoh :

#define pi 3.143

*** A lexeme is a unit of linguistic analysis. It belongs to a particular


syntactic category and has a particular meaning ( semantic value).
Lexemes may be simple words, phrasal and compound words and
shortened forms. A lexicon consists of lexemes.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 28


String #dikenali sebagai token tanda khas, define sebagai token katakunci, pi dikenali
sebagai token pencam dan 3.143 sebagai token num.

Token diterima dalam pengkompil sebagai simbol terminal dalam nahu. Lexeme
yang pada dengan corak untuk perwakilan token mewakili aksara-aksara dalam
aturcara sumber.

Dalam kebanyakkan bahasa pengaturcaraan, token-token yang wujud adalah tanda


khas, operator, pencam khas, pencam pembolehubah, pemalar numerik dan string
literal. Dalam contoh yang menggunakan pi di atas, penganalisa akan menghantar
pencam pembolehubah iaitu id.

Kebanyakkan bahasa pengaturcaraan menggunakan ruangan kosong untuk


membezakan token-token dalam aturcara sumber. Sebagai contoh, berikut adalah
pernyataan dalam Fortran :

DO 5 I = 1.25

Dalam pernyataan di atas, kita tidak boleh menyatakan bahawa DO bukan pencam
kata khas sehingga kita mengetahui bahawa wujud pemalar titik apung dihujungnya.
Sebaliknya kita boleh apabila wujud string DO5I

Format yang betul dalam Fortran adalah

DO 5 I = 1, 25

Dalam pernyataan di atas, token-token yang terbina adalah pencam khas DO, pemalar
5, pencam I, operator = 1, tanda khas , dan pemalar 25. Dalam kes ini DO adalah
pencam khas hanya apabila koma dijumpai.

Oleh kerana terdapat pencam khas, penganalisa leksikal perlu membezakan antara
pencam khas dengan pencam pembolehubah.

Atribut Token

Apabila terdapat lebih daripada satu corak yang sepadan dengan lexeme, penganalisa
leksikal perlu maklumat tambahan untuk lexeme tertentu yang sepadan.

Penganalisa leksikal mengambil maklumat mengenai token berserta dengan


atributnya. Ini disebabkan token akan mempengaruhi keputusan penghurai; atribut
pula mempengaruhi terjemahan token.

Secara parktikal, satu token akan mempunyai satu atribut sahaja iaitu penunjuk
kepada jadual simbol dimana maklumat mengenai token disimpan. Untuk tujuan
penilaian, pengkompil memerlukan lexeme untuk pencam dan baris dimana ia
dijumpai. Kedua-dua maklumat ini boleh disimpan dalam jadual simbol.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 29


Contoh :

Token dan atributnya untuk satu pernyataan E = M * C + 2 ditulis sebagai

< id, penunjuk kepada E>


<op_umpuk, >
<id, penunjuk kepada M >
<op_darab, >
< id, penunjuk kepada C>
<op_tambah, >
<2, nilai 2>
Terdapat pasangan yang tidak memerlukan nilai atribut.

Ralat Leksikal

Apabila string fi ditemui dalam pernyataan C berikut :

fi ( a = = 2)

Penganalisa leksikal tidak boleh memberikan ralat fi adalah pencam khas salah ejaan
atau satu pembolehubah yang tidak diistiharkan. Sebaliknya penganlisa leksikal akan
mengembalikan token pencam dan membiarkan fasa seterusnya untuk menunjukkan
ia adalah ralat.

Ralat yang ditemui di fasa analisis ini adalah ralat yang wujud apabila string yang
dijumpai tidak memenuhi corak token. Apabila satu aksara yang dibaca tidak
memenuhi syarat aksara yang sebelumnya, penganalisa leksikal boleh melakukan :

1. buang aksara tersebut


2. selit aksara yang sesuai
3. ganti aksara yang salah dengan aksara yang betul
4. tukar kedudukkan aksara.

Aktiviti di atas dilakukan dalam persekitaran komputer interaktif.

Aliran Input

Terdapat tiga pendekatan untuk implementasikan penganalisa leksikal :

1. Menggunakan penjana penganalisa leksikal, seperti pengkompil Lex. Penjana


ini dibina daripada spesifikasi ungkapan regular. Penjana menyediakan rutin
untuk membaca dan membentuk aliran input.
2. Menulis penganalisa leksikal dengan pengaturcaraan sistem menggunakan
kemudahan I/O untuk membaca input.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 30


3. Menulis penganalisa leksikal dengan bahasa perhimpunan dengan tugas
khusus untuk membaca input.

Pasangan Penimbal

PL sentiasa perlu kepada pendekatan “pandang depan” untuk mengenalpasti token.


Jika bilangan token yang perlu dikenalpasti adalah banyak, maka ia akan
menggunakan masa yang panjang untuk pemprosesan. Oleh itu, teknik-teknik
(penimbal) buffering yang baik perlu dibangunkan.

Sebagai contoh, satu teknik memisahkan penimbal kepada 2 bahagian N-aksara. N


adalah bilangan aksara dalam satu blok disk.

: : E: :=:M:*: C :* :* :2:eof : :

Permulaan bergerak

Simbol eof digunakan untuk menandakan penghujung penimbal, jika terdapat lagi
ruangan kosong di hadapan buffer kedua. Penggunaan dua penunjuk perlu untuk
proses pengenalpastian token. Contoh, pernyataan :

DECLARE(ARG1, ARG2, …., ARGn) dalam bahasa PL/1, pernyataan DECLARE


tidak dapat dikenalpasti sebagai kata kuci selagi hujung kurungan dikenalpasti.

Alkhawarizmi untuk menggerakkan bergerak:

if bergerak at end of first half then begin


reload second half
bergerak ++
end
else if bergerak at end of second half then begin
reload first half
move bergerak to beginning of first half
end
else bergerak++

SPESIFIKASI TOKEN

Ungkapan Regular adalah notasi penting untuk menyatakan corak token. Istilah
aksara mewakilkan set simbol terhingga biasanya huruf dan karakter. Set {0, 1}
adalah aksara perduaan. ASCII dan EBCDIC merupakan aksara komputer.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 31


String dan Bahasa

String adalah simbol yang terhasil daripada jujukkan aksara. Dalam teori bahasa, ayat
atau perkataan adalah bersamaan dengan istilah string yang kita gunakan. Panjang
untuk satu string ditulis dengan cara | s |. String nol diwakilkan dengan .

Jika x dan y adalah string maka percantuman x dan y ditulis sebagai xy. Sebagai
contoh jika x = kucing dan y adalah harimau, maka xy menjadi kucingharimau.

String nul sentiasa berada sebagai percantuman satu string seperti berikut :

s = s = s

Jika S0 adalah , dan I > 0, maka Si menjadi S I –1


S. Oleh kerana S adalah S1 = S,
maka S2 = SS, S3 = SSS dan seterusnya.

String mempunyai prefix, suffix, substring dan subsequence.

Operasi Bahasa

Jadual berikut menunjukkan operasi bagi bahasa :

Operasi Definisi
Kesatuan L dan M ditulis sebagai L  M L  M = { s | s dalam L atau s dalam M }
Percantuman L dan M ditulis sebagai LM LM = {st | s dalam L dan t dalam m}
Tutupan Kleene ditulis L * L* =
L* mewakili kosong atau lebih cantuman L
Tutupan tambah ditulis L+ L+
L+ mewakili satu atau lebih cantuman L

Contoh :

Biarkan L adalah set {A, B, …., Z, a, b,…., z} dan D adalah set {0, 1,.., 9)

L adalah alphabet mengandungi aksara huruf besar dan huruf kecil. D pula
merupakan alphabet mengandungi set sepuluh digit decimal.

Berikut adalah bahasa yang boleh dijana daripada L dan D.

1. L  D adalah set huruf dan digit


2. LD adalah set string yang mengandungi satu huruf dan diikuti dengan satu
digit
3. L4 adalah set dengan 4 huruf sahaja.
4. L* adalah set rentetan huruf termasuk .

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 32


5. L (L  D)* adalah set rentetan huruf dan digit yang perlu bermula dengan
satu huruf.
6. D+ adalah set string dengan sekurang-kurangnya satu dan lebih digit.

Ungkapan Regular

Ungkapan ini telah diperkenalkan oleh Warren McCulloch dan Walter Pitts, kedua-
duanya adalah ahli neuro-physiologists. Ia menunjukkan satu cara untuk
menunjukkan rangkaian neural menggunakan matematik. Pada tahun 1956, seorang
ahli matematik Amerika yang bernama Stephen Kleene, telah membina aturcara
menggunakan ungkapan ini. Beliau telah menerbitkan satu kertas kerja yang bertajuk
Representation of Events in Nerve Nets.

Ungkapan regular merupakan cara untuk menerangkan sesuatu yang dipanggil "the
algebra of regular sets". (Daripada istilah tersebut wujud nama"regular expression." ).
Penggunaan ungkapan ini menjadi pencetus kepada usaha-usaha awal dalam
pembangunan alkhawarizmi pencarian secara berkomputer yang digunakan oleh Ken
Thomson, pengasas Unix. Aplikasi yang pertama menggunakan ungkapan regular
yang dipratikkan dinamakan sebagai qed, digunakan dalam editor Unix.

Dalam C, pencam adalah satu huruf yang diikuti dengan kosong atau lebih sama ada
huruf atau digit atau aksara underscore. Kita menggunakan notasi yang dinamakan
sebagai ungkapan regular untuk menunjukkan perwakilan token. Dalam definisi
pencam C, ungkapan nalar yang kita perolehi adalah :

huruf( huruf | digit | underscore) *

Bar menegak ‘|’ bermaksud atau, dan kurungan pula digunakan untuk mengumpulkan
sub-ungkapan. Ungkapan regular dibina menggunakan definisi set peraturan yang
dicipta. Setiap ungkapan regular r mewakilkan satu bahasa L( r ). Ia menunjukkan
peraturan L( r ) dari segi pembentukkan bahasanya dalam pelbagai bentuk mengikut
definisi.

Berikut adalah peraturan yang menunjukkan hubungan ungkapan regular dengan


alphabet .

1.  adalah satu ungkapan regular yang mewakilkan {}. Ia menunjukkan set yang
mengandungi string nol.
2. Jika a adalah simbol dalam , maka a adalah ungkapan regular yang boleh
diwakilkan dengan{a}, iaitu set mengandungi a.
3. r dan s adalah ungkapan regular yang mewakilkan bahasa L(r) dan L(s), maka,

a) (r) | (s) adalah satu ungkapan regular mewakilkan L(r)  L (s).


b) (r) | (s) adalah ungkapan regular mewakilkan L(r)L(s)
c) (r)* adalah ungkapan regular mewakilkan (L(r))*
d) (r) adalah ungkapan regular mewakilkan L(r)2

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 33


p/s: (a) | ((b)* (c)) adalah sama dengan a | b* c

Contoh :
Biarkan  = {a,b}

1. ungkapan regular a | b mewakili set {a ,b}


2. ungkapan regular (a | b)(a | b) mewakili set {aa, ab, ba, bb } . Ungkapan regular
lain yang boleh digunakan adalah aa | ab | ba | bb
3. ungkapan regular a* mewakilkan set string kosong atau lebih a. Contoh { , a, aa,
aaa, …}
4. ungkapan regular (a|b)* mewakilkan set string kosong atau lebih sama ada a atau
b. Ungkapan regular lain yang boleh digunakan adalah (a*b*)*
5. ungkapan regular a | a*b mewakilkan sama ada set string mengandungi a sahaja
atau a yang diikuti dengan nul atau dan diakhiri dengan b.

p/s : (a | b) = (b | a)

Definisi Regular

Jika  adalah alphabet dengan simbol-simbol asas, definsi regular adalah jujukan
definisi pembentukkan :

d1  r1
d2  r2
:
dn  rn

di adalah nama dan setiap ri adalah ungkapan regular untuk simbol   { d1, d2, … di-
1}
Kita boleh menggunakan ungkapan regular yang telah diberikan nama untuk
pembentukkan ungkapan regular yang lain.

Contoh,

Kita telah mengetahui peraturan untuk string pencam dalam C. Kita gunakan
ungkapan regular untuk mewakilkan peraturan tersebut :

huruf  A | B | …| Z| a | b | ….|z
digit  0 | 1 | …|9
unscore _
id  huruf ( huruf | digit | unscore ) *

Contoh ungkapan regular pencam pemalar nombor seperti 1250, 39.37, 6.45E4 atau
2.75E-4 adalah seperti berikut :

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 34


digit  0 | 1 | .. | 9
digit  digit digit*
digit_apung  .digit | 
digit_exponen  (E ( + | - | ) digit) | 
num  digit digit_apung digit exponen

Notasi Ringkas

Oleh kerana beberapa pengeluaran berlaku berulang kali dalam ungkapam regular,
maka, aktiviti ini amat mudah dibangunkan menggunakan notasi yang diringkaskan
seperti berikut :

1. Satu atau lebih. Operator +bermaksud satu atau lebih. Jika r adalah ungkapan
regular yang mewakili bahasa L(r ), maka r + merupakan ungkapan regular
yang mewakili (L(r)) +. Oleh itu, ungkapan regular a+ mewakili set untuk
semua string yang mengandungi satu atau lebih a. Operator + ini mempunyai
persamaan dengan operator , iaitu r* = r+ |  dan r+ = rr*.

2. Kosong atau satu. Operator ? bermaksud “kosong atau lebih”. Notatsi r?


merupakan ringkasan untuk r| . Jika r merupakan ungkapan regular, maka
(r)? mewakili bahasa L(r )  {.} Sebagai contoh, menggunakan operator +
dan ?, kita boleh menulis semula definisi regular untuk num seperti berikut :

digit  0 | 1 | .. | 9
digit  digit+
digit_apung  (.digit)?
digit_exponen  (E ( + | -)? digit)?
num  digit digit_apung digit exponen

3. Kelas aksara. Notasi [abc] dimana a, b dan c adalah simbol alphabet yang
mewakili ungkapan regular a | b | c. Ringkasan [a-z] mewakili ungkapan
regular a | b | …|z. Menggunakan ungkapan yang dinyatakan, kita boleh
menghuraikan pencam string menggunakan ungkapan regular [A-Za-z][A-Za-
z0-9]*.

Set non-Regular

Ada bahasa yang tidak boleh dihuraikan menggunakan ungkapan regular. Untuk
menggambarkan keadaan ini, berikut adalah contoh yang dinyatakan. Mencari tutup
kurungan untuk pembuka kurungan. Masalah ini boleh diselesaikan menggunakan
Nahu Bebas Konteks atau Context Free Grammar (CFG).

Selain dari itu, pengulangan string tidak dapat diwakilkan menggunakan ungkapan
regular. { wcw | w adalah string a dan b }.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 35


PENGECAMAN TOKEN

Berikut adalah satu nahu :

pern  if ( unkp ) pern


| if ( unkp ) pern else pern
|

unkp  term ophub term


| term
term  id
| num

Terminal if, then, else, ophub, id dan num menjana set string yang diberikan oleh
definisi regular berikut :

if  if
((
))
else  else
ophub  < | <= | = = | != | > | >=
huruf  A | B | …| Z| a | b | ….|z
digit  0 | 1 | …|9
unscore  _
id  huruf (huruf | digit | unscore) *
num  digit+ (. digit+) |  (E ( + | - ) |  digit +

Untuk bahasa ini, penganalisa leksikal akan mengenalpasti pencam khas


if dan else serta ophub, id dan num.

Matlamat untuk membina penganalisa leksikal adalah untuk mengasingkan token-


token dalam lexeme. Ini akan menghasilkan output pasangan token dengan
atributnya. Ini ditunjukkan dalam jadual berikut :

Ungkapan Regular Token Atribut-nilai


if if -
( ( BK
) ) TK
else else -
id id Penunjuk kepada jadual simbol
num num Penunjuk kepada jadual simbol
< ophub LK
<= ophub KS
== ophub SD
!= ophub TS
> ophub LB

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 36


>= ophub BS

P/S: Token tanda khas diberikan simbol khas iaitu BK, TK, LK, SD, TS, LB, BS

Gambarajah Peralihan

Pembangunan penganalisa leksikal perlu mempunyai fasa penjanaan carta-aliran


khusus yang dinamakan gambarajah peralihan. Gambarajah ini menunjukkan
tindakan yang perlu diambil oleh penganalisa apabila ia dipanggil oleh pengimbas
untuk mendapatkan token.

Gambarajah ini digunakan untuk menjejaki maklumat aksara yang dijumpai. Ini
dilakukan dengan menggerakkan posisi gambarajah.

Posisi dalam gambarajah ditunjukkan dengan bulatan yang dipanggil keadaan.


Keadaan dihubungkan dengan satu anak panah yang dipanggil sebagai peralihan.
Peralihan daripada keadaan s mempunyai label menunjukkan aksara yang boleh
muncul dari simbol input.

Pada bahagian pertama ini kita mengandaikan bahawa rajah peralihan yang
digunakan adalah deterministic; iaitu, tiada simbol yang boleh sepadan dengan label
pada dua peralihan daripada satu keadaan.

Terdapat satu keadaan yang dilabelkan sebagai keadaan mula. Keadaan mula adalah
permulaan untuk suatu token. Untuk menjejaki token, kita membaca input dan
kemudian input tersebut dipadankan dengan keadaan dalam rajah. Oleh kerana itu,
input dibaca pada setiap kali tiba di keadaan. Jika wujud peralihan yang sepadan
dengan simbol input, maka pergerakan adalah mengikut peralihan ke arah keadaan
yang ditunjuk. Sebaliknya, jika tidak wujud aksara input yang sepadan dengan aksara
dalam rajah, maka ralat dijumpai.

Rajah berikut menunjukkan gambarajah perlihan untuk mengecam corak >= dan >

Kita akan menggunakan simbol ( ) untuk menggantikan

mula > =
(0) (6) ((7))
Lain-lain

((8))*

Kita menjejaki rajah peralihan bermula daripada keadaan 0, iaitu keadaan mula.
Daripada keadaan tersebut baca input. Jika aksara input adalah >, maka ikut

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 37


pergerakkan peralihan kepada keadaan 6. Jika input bukan >, maka token yang
dijumpai bukan > atau >=.

Apabila berada di keadaan 6, input seterusnya dibaca. Jika input adalah = maka ikut
peralihan ke keadaan 7. Jika tidak ikut peralihan ke keadaan 8. Tanda (( ))
menunjukkan keadaan terima, iaitu suatu token telah dicam.

Oleh kerana aksara > dan satu aksara tambahan telah dibaca apabila pergerakkan
sampai di keadaan 8, maka penganalisis perlu memulangkan kembali aksara
tambahan tersebut. Tanda * menunjukkan terdapat tindakan yang perlu dilakukan
terhadap aksara yang dibaca.

Secara umum, terdapat banyak jenis rajah peralihan untuk mengecam kumpulan-
kumpulan token. Semasa analisis mencari token, jika ralat berlaku, maka analisis
dilakukan menggunakan rajah yang lain pula dilakukan untuk mencari jenis suatu
token.

Berikut adalah rajah peralihan untuk mengecam token ophub.

mula < =
return(ophub,KS)
(0) (1) ((2))
Lain-lain

((3))* return(ophub,LK)
=
=
(4) ((5)) return(ophub,SD)

Lain-lain

return(opkhas,UP)
((6))*
>
=
return(ophub,BS)
(7) ((8))
Lain-lain

return(ophub,LB)
((9))*

Oleh kerana pencam merupakan jujukan aksara, maka peraturan pencam


pembolehubah iaitu jujukan aksara dan digit yang bermula dengan aksara dicamkan
menggunakan rajah seperti berikut :

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 38


aksara atau digit atau uscore

mula aksara Lain-lain


(10) (11) ((12)) * return(ambiltoken( ), masukid( ))

Satu teknik mudah untuk membezakan pencam pembolehubah dengan pencam khas
adalah dengan memberikan nilai awalan yang tepat kepada jadual simbol. Sebagai
contoh pencam if, else dimasukkan dalam jadual simbol sebelum input dibaca. Ini
membolehkan jadual simbol memulangkan maklumat mengenai token ini jika ia
dijumpai. Pernyataan ambiltoken( ) dan masukid( ) menunjukkan nilai token serta
atributnya diambil untuk disemak dan kemudian disimpan dalam jadual simbol.

Fungsi gettoken( ) digunakan untuk menyemak token yang dijumpai dengan token
dalam jadual simbol.

Rajah peralihan untuk mengenalpasti nombor tak bertanda :

digit digit digit

mula Lain-lain
digit . E digit + atau - digit
(13) (14) (15) (16) (17) (18) (19) ((20)) *

digit digit

digit digit

mula digit digit Lain-lain


.
(21) (22) (23) (24) ((25)) *

digit

mula digit Lain-lain


(26) (27) ((28)) *

Terdapat beberapa isu yang timbul apabila membina pengecam untuk nombor tak
bertanda yang diberikan oleh ungkapan regular berikut :

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 39


num  digit+ (.digit+)* (E (+|-)* digit)*

lexeme untuk token seperti ini berkemungkinan panjang. Sebagai contoh, penganalisa
tidak boleh berhenti sehingga 22 atau 22.4 apabila menjumpai input 22.4E3.

Implementasi Satu Rajah Peralihan

Jujukan rajah peralihan boleh ditukarkan kepada aturcara untuk mengecam token
yang telah diterangkan menggunakan rajah peralihan.

Setiap keadaan akan menjadi satu kod segmen aturcara. Jika terdapat peralihan
daripada satu keadaan, maka kod membaca aksara dan pilih peralihan untuk diikuti.
Fungsi aksberikut( ) digunakan untuk membaca aksara seterusnya daripada buffer
input.

Kita gunakan pernyataan switch-case untuk mencari keadaan mula. Dua


pembolehubah iaitu keadaan dan mula digunakan untuk menyimpan data keadaan
semasa dan keadaan mula untuk rajah peralihan yang digunakan.

Berikut adalah contoh kod yang digunakan :

int keadaan = 0, mula = 0;


int nilai_leks;

int fail(void)
{
depan = token_mula;
switch(mula)
{
case 0 : mula = 10; break;
case 10 : mula = 13; break;
case 13 : mula = 21; break;
case 21 : mula = 26; break;
case 26 : recover( ); break;
}
return mula;
}

Aturcara Penganalisa Leksikal

Kita memperkenalkan satu alat yang dinamakan sebagai Lex, yang telah digunakan
dalam penganalisa leksikal untuk banyak bahasa. Pengkompil ini dinamakan sebagai
pengkompil Lex dan inputnya dipanggil sebagai Bahasa Lex.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 40


token tokenberikut(void)
{
while(1)
{
switch(keadaan)
{
case 0 : c = tokenberikut( );
if ( c = = ‘ ’ || c == ‘\t’ || c = = ‘\n’)
{
keadaan = 0;
lexeme_mula++;
}
else if ( c = = ‘<’) keadaan = 1;
else if ( c = = ‘=’) keadaan = 4;
else if ( c = = ‘>’) keadaan = 7;
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
case 9 :

case 10 : c = aksberikut ( );
if ( isletter( c ) ) keadaan = 11;
else
keadaan = fail( );
break;
case 11 : c = aksberikut ( );
if (isletter( c ) ) keadaan = 11;
else if (isdigit( c ) ) keadaan = 11;
else
keadaan = 12;
break;
case 12 : retract(1); masukid( );
return( ambiltoken( ) );

case 13 :
case 14 :
case 15 :
case 16 :
case 17 :
case 18 :
case 19 :

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 41


case 20 :
case 21 :
case 22 :
case 23 :
case 24 :
case 25 :

case 26 : c = askberikut ( );
if (isdigit( c ) ) keadaan = 27;
else
keadaan = fail( );
break;

case 27 : c = aksberikut ( );
if (isdigit( c )) keadaan = 26;
else
keadaan = 28;
break;
case 28 : retract(1); masuknum( );
return (NUM);
}

}
}

Dalam aturcara di atas, fungsi masukid( ) dan fungsi masuknum( ) mempunyai


pembolehubah yang memberikan nilai kepada kemasukkan jadual simbol untuk token
berjenis id atau num.

Berikut adalah fungsi masukid( ) dan masuknum( )

void masukid(void)
{
/*fungsi ini adalah untuk memasukkan nilai pencam dalam lexeme. */
}

void masuknum(void)
{
/* fungsi ini adalah untuk memasukkan nilai nombor dalam lexeme */
}

Berikut pula adalah token-token yang boleh digunakan dalam aturcara :

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 42


Delim [\t\n]
Ws {delim}+
huruf [A-Za-z]
Digit [0-9]
Id

Input : Skema sintaks-terarah dengan nahu yang bersesuaian untuk penghuraian


ramal.

Output : Kod untuk penterjemah sintaks-terarah.

Method : Teknik ini adalah satu pengubahsuaian penghurai ramal.

1. Untuk setiap nonterminal A, bina satu fungsi yang mempunyai parameter formal
untuk setiap atribut warisan A yang memulangkan nilai-nilai sinthesized atribut
A. Atribut ini adalah berkemungkinan satu record[struct], penunjuk kepada rekod
dengan medan untuk setiap atribut atau menggunakan mekanisma panggilan
fungsi secara rujukan untuk menghantar parameter. Untuk memudahkan
kefahaman, kita andaikan bahawa setiap nonterminal hanya mempunyai satu
atribut sinthesized. Fungsi untuk A mempunyai satu pembolehubah setempat
untuk setiap atribut nahu simbol yang wujud dalam pengeluaran A.
2. Kod untuk nonterminal A menentukan pengeluaran untuk digunakan bergantung
kepada input simbol semasa.
3. Kod yang berkaitan dengan setiap pengeluaran melakukan perkara yang
dinyatakan di bawah. Andaikan token-token, nonterminal dan perlaksanaan pada
sebelah kanan dilakukan dari kiri ke kanan.

i. Untuk token X dengan atribut sinthesized x, simpan nilai x dalam


pembolehubah yang diistiharkan untuk X.x. Kemudian jana satu
panggilan untuk memadankan token X dan terus kepada input
berikutnya.
ii. Untuk nonterminal B, jana umpukkan c = B(b1,b2,….,bk) dengan satu
fungsi memanggil pada sebelah kanan, dimana b1, b2, ….,bk adalah
pembolehubah untuk atribut warisan B dan c adalah pembolehubah
untuk atribut sinthesized B.
iii. Untuk satu perlaksanaan, salin kod ke dalam penghurai, mengantikan
setiap rujukan kepada atribut dengan pembolehubah untuk atribut
tersebut.

OPERATOR pandang

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 43


Penganalisa leksikal memerlukan satu mekanisma untuk pandang depan lexeme
sebelum mengenalpasti suatu token. Sebagai contoh, sepasang pernyataan Fotran
berikut :

DO 5 I = 1.25
DO 5 I = 1,25

Dalam Fotran, ruang kosong adalah tidak dikira. Oleh kerana itu, pernyataan di atas
boleh dianggapkan sebagai :

DO5I=1.25
DO5I=1,25

Untuk pemprosesan leksikal.

Dalam pernyataan yang pertama, penganalisa tidak boleh mengambil string DO


sebagai pencam kata rezab kerana perkataan tersebut menjumpai nilai 1.25 selepas
operator umpukkan. Dalam kes ini Penganalisa perlu membaca sehingga menjumpai
nombor 1.25. Selagi tidak menjumpai token yang mengesahkan bahawa token
tersebut merupakan token DO, ia tidak boleh menggangap DO sebagai pencam kata
rezab. DO adalah token pencam kerana ia adalah sebahagian daripada pencam DO5I.

Dalam pernyataan yang kedua, DO merupakan pencam kata rezab.

AUTOMATA TERHINGGA

Satu pengecam untuk bahasa merupakan satu aturcara yang menerima input, string x
dan mengeluarkan maklumat “betul” apabila x adalah satu ayat yang betul untuk
bahasa tersebut.

Kita menggunakan ungkapan regular untuk mengecam satu pembinaan yang


dipanggil sebagai automata keadaan terhingga. Terdapat dua jenis automata, iaitu :

1. deterministic
2. nondeterministic

Automata deterministic dikatakan boleh melakukan pengecaman lebih cepat daripada


pengecaman yang dilakukan oleh automata nondeterministic.

Nondeterministic Automata Terhingga

Satu NAT merupakan satu model matematik yang mengandungi ;

1. satu set keadaan S

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 44


2. satu set simbol input, 
3. satu fungsi pergerakkan yang memetakan pasangan simbol keadaan dengan set-
set keadaan.
4. Satu keadaan S0 yang membezakan keadaan mula dengan keadaan-keadaan yang
lain.
5. Satu set keadaan F, yang menunjukkan keadaan menerima.

Satu NFA boleh diwakilkan oleh label graf terarah yang dipanggil graf peralihan.
Nod-nod dalam graf ini adalah keadaan dan anak panah merupakan fungsi peralihan.
Graf ini seakan-akan sama dengan rajah peralihan. Perbezaaannya adalah, aksara
yang sama boleh menjadi peralihan daripada dua atau lebih kedaaan. Anak panah
juga boleh dilabelkan dengan simbol .

Graf peralihan untuk menerima bahasa (a | b)* abb ditunjukkan seperti berikut :

a b b
mula
0 1 2 3

BAB III

NAHU BAHASA

Pengenalan

Apakah yang dilakukan apabila memproses sesuatu bahasa ? Kita melihat


pembentukan sesuatu bahasa betul dengan cara :

1. melihat struktur bahasa


2. melihat makna bahasa

Struktur sesuatu bahasa dikenali sebagai sintaks bahasa dan makna sesuatu bahasa
dikenali sebagai semantik bahasa.

Sintaks bahasa mempunyai struktur atau peraturan yang perlu diikuti.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 45


Bahasa Malaysia sebagai contoh perlu memenuhi Rumus Struktur Frasa (RSF) ayat
Bahasa Malaysia seperti yang ditetapkan oleh DBP.

Semakan sintaks sesuatu bahasa agak mudah dilakukan berbanding dengan


semantiknya kerana ia mempunyai peraturan dan rumus yang jelas.

Semantik hanya boleh dikenalpasti setelah sintaks sesuatu bahasa telah memenuhi
syarat atau rumus. Sebagai contoh :

Berikut adalah contoh ayat dalam Bahasa Malaysia :

Saya makan nasi.


Makan saya nasi.
Nasi makan saya.

Harimau makan nasi.


Nasi makan harimau.

RSF bahasa Malaysia digambarkan seperti dalam rajah berikut.

A  S+P
S  FN
P  {FN,FK,FA,FS}
FN  (Bil) + (Pbil) + (Gel) + KN + (KN..)+ (Penerang) + (Penentu)
FK  (Kbtu) + {Kktr+FN+(Ket)} {Kkttr+(Pel)}
FA  (Kbtu) + (Kpeng) + KA + {(KA,KN)}+(Ket)
FS  (Kbtu)+KSN+(Karah)+FN+(Ket)
Penerang  {FA,FS}
Pel  {FN,FA,FS}
Kbtu  (Knafi)+Kbtu+(Kbtu)
Ket  FS
Kpeng  Kpeng + (Kpeng)
Penentu  Kbtu

Rajah 1

Oleh kerana itu, tiga ayat di atas dapat disemak kesahihannya dengan merujuk kepada
jadual ini.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 46


Kata Nama
Kata Kerja

Dalam contoh di atas, ayat pertama adalah betul kerana:

Kn Kkjr Kn.
Ayat kedua tidak memenuhi syarat yang ditetapkan.
Ayat yang ketiga betul daripada segi sintaks (struktur), tetapi ia mempunyai kesilapan
semantik (makna).

Pengkompil diwujudkan dalam persekitaran pengaturcaraan untuk menguji sesuatu


aturcara yang ditulis itu memenuhi syarat bahasa pengaturcaraan paras tinggi yang
digunakan.

Ia penting untuk memastikan bahasa tersebut dapat diterjemahkan kepada bahasa


mesin dengan arahan yang betul.

Analisis Nahu :

Sintaksis : Hirarki Chomsky

Dalam pemerhatian kita, sintaksis (nahu) boleh dinyatakan dalam bentuk matematik
sebagai 4-tuple; yang mewakilkan empat komponen iaitu : alphabet, nonterminal,
production dan simbol gol. Perwakilan ini diwakilkan dengan simbol , N, P dan S.
Ia dilitupi dengan ( dan ) dan dipisahkan dengan koma :

(, N, P, S)

Rentetan Aksara dan Alphabet

Set yang pertama, , adalah alphabet atau satu set terminals. Ia adalah terhingga dan
mengandungi karakter atau simbol yang boleh disusun membentuk ayat dalam

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 47


bahasa. Dalam Bahasa Inggeris, alphabet selalunya adalah huruf A hingga Z, tetapi
dalam definisi ini, ruang kosong antara huruf juga adalah termasuk dalam alphabet.

Kebanyakkan bahasa pengaturcaraan, alphabet ialah teks yang dinyatakan


dalam ASCII. Satu pengkompil mendefinisikan dua jenis grammar, iaitu alphabet
untuk grammar pengimbas ialah ASCII dan alphabet untuk parser adalah set token-
token yang di outputkan daripada pengimbas.

Terminal dalam alphabet boleh disambungkan menjadi string dengan panjang


yang tidak rigid mengikut peraturan grammar. Istilah string merujuk kepada jujukan
sifar atau lebih terminal dalam jujukan tertentu.

Satu contoh string,  = {a,b,c,d}. Kemungkinan string yang boleh dibentuk


adalah aaa, aabbccdd, d, cba, abad, ccccccccccaccccccc dan sebagainya. String
kosong selalunya ditandakan dengan . Set untuk semua string dalam  termasuk
string kosong  ditandakan dengan *. Tanda * dinamakan bintang Kleene yang
bermaksud sifar atau lebih daripada.

Nonterminals dan Pengeluaran

Set kedua dalam definisi nahu matematik adalah set nonterminals yang ditunjukkan
dalam 4-tuple sebagai “N”. Ia adalah set simbol terhingga yang tidak berada dalam
alphabet. Nonterminals bukan satu set string, tetapi simbol boleh dinyatakan sebagai
perwakilan string iaitu subset *. Dalam nonterminal tertentu, simbol gol,
mewakilkan semua string dalam bahasa. Nonterminal dipanggil kategori sintatik atau
pembolehubah nahu.

Peraturan untuk nahu ( tuple ketiga) adalah set untuk menulis semula
peraturan, ditulis sebagai 2 string yang diasingkan dengan anak panah.

Contoh-contoh Nahu

Contoh yang pertama, G1 adalah nahu yang paling mudah. Ia adalah nahu untuk
semua string mengandungi dua huruf a, b, c ( kemungkinan huruf yang sama) dalam
mana-mana turutan.

G1 = ({a, b, c}, { A, B}, {A  aB, A  bB, A  cB, B  a, B  b, B  c },


A)

Dalam grammar ini,  adalah set huruf kecil { a, b, c}; nonterminal pula adalah set
huruf besar { A, B} yang mana A adalah simbol gol. Set pengeluaran disenaraikan di
bawah :

A  aB B a
A  bB B b

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 48


A  cB B c

Nonterminal A mewakilkan “semua string dalam bahasa” dan nonterminal B


mewakilkan “semua string satu karakter”. Bermula dengan A, peraturan ini boleh
diimplementasikan sehingga terminal diperolehi.

Contoh :

Bermula dengan simbol gol, A

Gantikan A dengan bB ( pilihan boleh diambil daripada mana-mana tiga nonterminal)


Daripada B  c,
mendapat bc.

Sehingga ini, hanya terminals yang tinggal dan tiada nonterminals yang ditemui.
Proses terhenti.

Langkah-langkah ini dinamakan derivation, dan boleh ditulis dalam satu baris
menjadi :

A => bB => bc

Selain daripada derivation di atas, pemilihan production yang lain juga boleh
menghasilkan : A => aB => aa

Contoh nahu yang kedua ialah G2 = ( ,N, P, E ).  ialah ialah set { n, +, *, ), (, }. N


adalah adalah set nonterminal { E, T, F} dan P adalah pengeluaran yang berikut :

D.1. E  E + T
D.2. E  T
D.3. T  T * F
D.4. T  F
D.5. F  (E)
D.6. F  n
Pengeluaran pertama mempunyai satu nonterminal tunggal, E pada sebelah kiri dan
dua nonterminal E dan T yang dipisahkan oleh terminal “+’ pada sebelah kanan.
Pengeluaran ini bermaksud apabila nahu ini digunakan, nonterminal E muncul dalam
string iaitu nonterminal boleh ditulis sebagai string “E+T”. Nahu ini akan derive
n+n*n.

Berikut adalah langkah-langkah yang dilakukan.

E
E+T
E+T*F
T+T*F

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 49


F+T*F
F+F*F
F+F*n
F+n*n
n+n*n

Proses ini boleh digambarkan dengan diagram yang dipanggil abstract syntact tree
atau parse tree atau derivation tree.

E =>* n+n*n

bermaksud nonterminal E mewakilkan n+n*n dalam sifar atau lebih jujukan. Ayat
boleh dibentuk daripada * yang bermula dengan simbol gol dengan satu atau lebih
jujukan. Satu sentential form,  ialah string dalam (  N)* yang mengandungi
sejumlah terminals dan nonterminals dalam hubungan,

S => *  => *, yang mana,

S adalah simbol gol dan  adalah ayat dalam *.

Jika dua parse tree dapat dibina daripada nahu, maka ia dikatakan sebagai nahu
berambiguiti.

Kedua-dua nahu di atas mempunyai satu simbol nonterminal pada sebelah kiri
pengeluaran. Karakteristik grammar seperti ini amat seseuai digunakan dalam
pembangunan pengkompil.

Terdapat juga satu grammar yang tidak rigid kepada peraturan ini.

G3 = ({a,b,c}, {A,B,C}, P, A), P adalah set pengeluaran,

A  aABC CB  BC
A aBC
bC  bc ab ab
cC  cc bB bb

Production ini menghasilkan aabbcc dengan deivationnya :


A
aABC
aaBCBC
aaBBCC
aabBCC

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 50


aabbCC
aabbcC
aabbcc

Hirarki Chomsky

Ahli linguistik, Noam Chomsky (1950) mendefinisikan grammar kepada empat paras
yang boleh untuk menganalisis bahasa.
Paras ini berkait secara langsung dengan kelas automata untuk mengenalpasti bahasa.

Paras Bahasa Chomsky Grammar Pengenal


3 Biasa (Regular) Finite- State Automata
2 Context-Free Push-Down Automata
1 Context-Sensitive Linear-Bounded Automata
0 Unrestricted Turing Machine

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 51


Penghurai

Penghurai adalah proses untuk mengenalpasti token bagi string yang dijana oleh
nahu. Masalah ini lebih mudah difahami dengan mengkaji bagaimana satu pokok
boleh dibina. Walaupun pengkompil tidak membina pokok huraian, namun, satu
penghurai perlu menghasilkan pokok supaya hasil yang diperolehi adalah tepat.

Bahagian ini akan memperkenalkan satu method untuk menjana penterjemah sintak.
Satu penghurai boleh dibina untuk sebarang nahu.

Untuk nahu bebas konteks, satu penghurai selalunya mengambil masa paling lama O
(n3) untuk menghurai string yang mempunyai n token. Namun n kuasa tiga adalah
terlalu lama untuk bahasa pengaturcaraan komputer. Penghurai bahasa
pengaturcaraan biasanya membuat imbasan daripada kiri-ke-kanan terhadap inputnya.

Method penghuraian terbahagi kepada dua kelas iaitu atas-bawah dan bawah-atas.
Istilah ini merujuk kepada nod-nod dalam pokok penghurai yang dibina. Pembinaan
atas-bawah bermula di akar dan turun ke daun-daun sementara bawah atas adalah
bermula di daun dan naik ke atas. Penghurai atas-bawah lebih mudah dilakukan
berbanding dengan penghurai bawah-atas. Walaubagaimanapun, penghurai bawah-
atas mampu untuk melakukan huraian nahu untuk kelas-kelas yang besar dan
kompleks.

Penghurai Atas-bawah

Berikut adalah satu contoh pengeluaran untuk satu nahu :

jenis  mudah | ^id | array [ simple ] of jenis


mudah  integer | char | num dotdot num

Penjanaan penhurai atas-bawah bermula pada pokok huraian bermula di akar yang
dilabel dengan nonterminal mula. Ia seterusnya akan melakukan aktiviti berikut
secara berulang-ulang :

1. Pada nod n yang dilabel dengan nonterminal A, pilih satu daripada


pengeluaran untuk A dan bina anak di n untuk simbol yang ada pada sebelah
kanan pengeluaran.
2. Cari nod seterusnya pada subpokok untuk dijana.

Untuk sesetengah nahu, langkah-langkah di atas, boleh dilakukan pada masa imbasan
kiri ke kanan input string. Gambarajah di bawah menunjukkan proses menghurai
string.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 52


Token semasa yang diimbas dinamakan sebagai simbol pandang.

String yang diimbas adalah :

array [ num dotdot ] of integer

jenis

jenis

array [ mudah ] of jenis

jenis

array [ mudah ] of jenis

num dotdot num

jenis

array [ mudah ] of jenis

num dotdot num mudah

jenis

array [ mudah ] of jenis

num dotdot num mudah

integer

(a) Pokok huraian jenis

Input array [num dotdot num ] of integer

(b) Pokok huraian jenis

array [ mudah ] of jenis

Input array [num dotdot num ] of integer

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 53


(c) Pokok huraian jenis

array [ mudah ] of jenis

Input array [ nom dotdot ] of integer

Daripada rajah didapati bahawa, apabila satu nod dimasukkan dalam pokok, satu
simbol yang dinamakan simbol pandang akan membandingkan dengan input semasa.
Secara am, pemilihan pengeluaran untuk nonterminal melibatkan proses “trial and
error”, iaitu, satu pengeluaran dicuba dan kemudian cuba pula dengan yang lain jika
didapati bahawa pengeluaran tersebut tidak memenuhi padanan.

Penghurai Ramal

Penghurai ramal adalah satu method atas-bawah untuk analisis sintaks yang
menggunakan fungsi secara rekursif untuk memproses input. Satu fungsi adalah
berkait dengan setiap nonterminal nahu. Berikut adalah kod-pseudo untuk penghurai
ramal.

Nahu yang digunakan :

jenis  mudah | ^id | array [ simple ] of jenis


mudah  integer | char | num dotdot num

void jenis
{
jika ( pandang adalah integer atau char atau num )
mudah;
else jika pandang = = ‘^’
{
padan(‘^’);
padan(id);
}
else jika pandang = = array
{
padan( array ) ;
padan( ‘[’ );
mudah;
padan( ‘]’);
padan ( of );
jenis;
}
else
ralat; }

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 54


void mudah
{
jika pandang = = integer
padan( integer );
else jika pandang = = char
padan( char );
else jika pandang = = num
{
padan(num);
padan(dotdot);
padan(num);
}
else
ralat;
}

void padan( token t)


{
jika ( pandang = = t )
pandang = tokenseterus;
else
ralat;
}

Dalam kod-pseudo di atas, penghurai ramal mengandungi fungsi untuk nonterminal


mudah dan jenis nahu yang telah dibincang di atas, serta satu fungsi tambahan iaitu
padan. Fungsi padan diwujudkan untuk memudahkan penghuraian jenis dan mudah.
Ia akan bergerak kepada token berikutnya jika parameter yang dihantar sepadan
dengan simbol pandang. Oleh itu, fungsi padan menukar kandungan pembolehubah
pandang kepada token semasa yang diimbas oleh input.

Huraian bermula dengan panggilan terhadap fungsi untuk nonterminal jenis (kerana
jenis adalah simbol mula). Fungsi jenis melakukan aktiviti :

padan(array); padan(‘[’); mudah; padan(‘]’); padan(of); jenis

yang mempunyai kaitan secara langsung dengan sebelah kanan pengeluaran :

jenis  array [ mudah ] of type

Perhatikan bahawa setiap terminal pada sebelah kanan dipadankan dengan simbol
pandang dan setiap nonterminal pada sebelah kanan akan memanggil fungsinya.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 55


Penghurai ramal bergantung kepada maklumat mengenai simbol pertama yang boleh
dijana oleh pengeluaran pada sebelah kanan.

Biarkan  berada pada sebelah kanan pengeluaran untuk nonterminal A. Kita berikan
PERTAMA() sebagai set token-token yang akan muncul sebagai simbol-simbol
pertama untuk satu atau lebih string yang terjana daripada .

Jika  adalah , maka juga berada dalam PERTAMA(). Sebagai contoh,

PERTAMA(mudah) = {integer, char, num}


PERTAMA(^id) = { ^ }
PERTAMA(array [ mudah ] of jenis) = { array}

Kebanyakkan sebelah kanan pengeluaran bermula dengan token yang menerangkan


set-set PERTAMA.

Set PERTAMA perlu mengambil kira jika terdapat dua pengeluaran A   dan A 
. Simbol pandang boleh digunakan untuk memilih pengeluaran untuk digunakan.
Jika simbol pandang dalam PERTAMA() maka  digunakan. Sebaliknya jika
simbol dalam PERTAMA() maka  digunakan.

Pengeluaran dengan  pada sebelah kanan pengeluaran memerlukan satu pendekatan


yang berbeza. Penghurai rekursif akan menggunakan  secara default jika tiada
pengeluaran lain yang boleh digunakan.

Sebagai contoh,

pern  { pern_pilihan }
pern_pilihan  senarai_pern | 

Apabila menghurai pern_pilihan, jika simbol pandang bukan dalam


PERTAMA(senarai_pern), maka pengeluaran- digunakan. Pilihan ini
berkemungkinan betul sekiranya simbol pandang adalah }. Sebarang simbol selain
daripada } akan menghasilkan ralat semasa menghurai pern.

Rekabentuk Penghurai Ramal

Satu penghurai ramal adalah satu aturcara yang mengandungi fungsi-fungsi untuk
setiap nonterminal. Setiap fungsi melakukan dua perkara :

1. Ia membuat pilihan untuk memilih pengeluaran yang digunakan dengan melihat


simbol pandang. Pengeluaran dengan sebelah kanan  digunakan jika simbol
pandang dalam PERTAMA(). Jika terdapat konflik antara dua belah untuk
sebarang simbol pandang, kita tidak boleh menggunakan method huraian dalam

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 56


nahu ini. Satu pengeluaran dengan  pada sebelah kanan digunakan jika simbol
pandang tiada dalam set PERTAMA di sebelah kanan.

2. Fungsi menggunakan pengeluaran dengan menukarkannya menjadi pengeluaran


sebelah kanan. Satu nonterminal terhasil dalam panggilan fungsi untuk
nonterminal. Satu token dipadankan dengan token input yang dibaca oleh simbol
pandang. Jika terdapat token dalam pengeluaran yang tidak sepadan dengan
simbol pandang, ralat dilaporkan.

Rekursif kiri

Penghurai rekursif boleh menyebabkan penghurai bergelung tanpa henti. Masalah ini
timbul dengan pengeluaran seperti berikut :

unkp  unkp + term

Pengeluaran seperti ini mempunyai simbol nonterminal yang sama pada sebelah
kanan dan pada sebelah kiri. Ia akan menyebabkan fungsi akan memanggil fungsi
yang sama berulang kali. Masalah ini boleh diselesaikan dengan mengubah semula
pengeluaran. Sebagai contoh :

Andaikan nonterminal A mempunyai dua pengeluaran :

A  A | 

 dan  adalah perwakilan untuk jujukan terminal dan nonterminal yang tidak
bermula dengan A. Sebagai contoh,

unkp  unkp + term | term

A = unkp,  = + term, dan  = term

Nonterminal A adalah rekursif kiri kerana pengeluaran A  A mempunyai A pada


sebelah paling kiri di sebelah kanan. Ini boleh diatasi dengan menulis semula
pengeluaran menjadi :

A  R
R  R | 

Dalam pengeluaran yang baru ini, R adalah nonterminal baru yang diwujudkan dan ia
telah menggantikan rekursif kiri kepada rekursif kanan.

unkp  termR | term


R  +termR | 

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 57


Penterjemahan Ungkapan Mudah

Untuk menguji apa yang telah dibincangkan, kita cuba dengan ungkapan yang
mengandungi ungkapan yang mengandungi digit yang dipisahkan oleh tanda campur
dan tanda tolak seperti berikut :

unkp  unkp + term


unkp  unkp – term
unkp  term
term  0

term  9

Titik permulaan untuk menterjemah satu input string adalah menggunakan pokok
sintaks atau abstract syntax tree.Dalam pokok ini, setiap nod diwakilkan dengan
operator dan anak nod diwakilkan dengan operan.

Pokok penghurai pula dipanggil sebagai concrete syntax tree yang mewakilkan nahu
sebagai sintaks concrete sesuatu bahasa.

Pokok sintaks berbeza daripada pokok penghurai kerana hanya terminal yang penting
untuk sintaks sahaja yang muncul.

Pokok untuk 9-5+2 ditunjukkan seperti berikut :

- 2

9 5

‘+’ dan ‘-’ mempunyai keutamaan yang sama, oleh sebab itu, pokok dinilai dari kiri
ke kanan. Kita dapati bahawa pokok sintaks bersekutu dengan operator di nod
dalaman.

Membina skema penterjemahan adalah bergantung kepada nahu yang mana pokok
penghurai adalah hampir sama dengan pokok sintaks.

Oleh kerana nahu yang diberikan di berikut adalah rekursif kiri,

unkp  unkp + term


unkp  unkp – term
unkp  term

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 58


term  0

term  9

maka ia tidak sesuai untuk dilakukan penghurai ramalan. Cara yang nyata untuk
mengatasi masalah ini ialah dengan menghapuskan rekursif kiri.

Nahu berikut pula tidak sesuai untuk diterjemah kepada bentuk postfix.

unkp  term rest


rest  + unkp | - unkp | 
term  0
….
term  9

Nahu ini mempunyai masalah dimana operan operator yang dijana oleh rest  +
ungkp dan rest  - unkp adalah bukan nyata daripada pengeluaran. Tidak satupun
daripada pilihan pembentukan penterjemahan rest.t daripada unkp.t berikut diterima
pakai :

rest  unkp { rest.t = ‘-’ || unkp.t} --- (1)


rest  unkp { rest.t = unkp.t || ‘-’} --- (2)

Terjemahan untuk 9 – 5 adalah 95 -. Tetapi jika penterjemahan (1) di atas digunakan,


ia kekal sebagai 9 – 5. Atau jika perterjemahan (2) dipilih, 9-5+2 menjadi 952+-
sepatutnya 95-2+.

Menggunakan Skema Penterjemahan

Teknik penghapusan rekursif kiri boleh digunakan dalam pengeluaran yang


mempunyai tindakan semantik.

Penukaran A  A | A |  kepada

A  R
R  R | R | 

Jika A = unkp,  = +term {print(‘+’)},  = -term{print(‘-’) dan  = term,


penukarannya menghasilkan,

unkp  term rest


rest  + term { print(‘+’)} rest | - term { print(‘-’) } rest | 
term  0 { primt(‘0’)}

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 59


:
term  9 { print(‘9’) }

non-terminal baru, rest digunakan.

Berikut adalah gambarajah menunjukkan 9-5+2 diterjemah menggunakan nahu baru.

unkp

term rest

9 {print(‘9’)} - term {print(‘-’)} rest

5 {print(‘5’)} + term{print(‘+’)} rest

2 {print(‘2’)} 

Fungsi Untuk Nonterminal unkp, term dan rest

Fungsi-fungsi di bawah ini menggunakan skema penterjemahan iaitu mencetak


operator.

void unkp(void)
{
term( );
rest( );
}

void rest(void)
{
if (pandang = = ‘+’)
{
match(‘+’);
term( );
putchar(‘+’);
rest( );
}

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 60


else if (pandang = = ‘-’)
{
match(‘-’);
term( );
putchar(‘-’);
rest( );
} else;
}

void term(void)
{
if (isdigit(pandang))
{
putchar(pandang);
match(pandang);
}
else error( );
}

Aturcara C lengkap untuk melakukan penterjemahan adalah seperti berikut :

#include <ctype.h>

int pandang;

void main(void)
{
pandang = getchar( );
unkp( );
putchar(‘\n’);
}

void unkp(void)
{
term( );
while (1)
if (pandang = = ‘+’)
{
match(‘+’);
term( );

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 61


putchar(‘+’);
rest( );
}
else if (pandang = = ‘-’)
{
match(‘-’);
term( );
putchar(‘-’);
rest( );
}
else break;

void term(void)
{
if (isdigit(pandang))
{
putchar(pandang);
padan(pandang);
}
else error( );
}

void padan(int t)
{
if (pandang = = t)
pandang = getchar( );
else error( );
}

void ralat(void)
{
printf(“Ralat Sintaks”);
exit(1);
}

Analisis Leksikal

Tambahan kepada bahagian yang dibincangkan sebelum ini adalah analisis leksikal.
Penganalisa leksikal membaca dan kemudian menukar input kepada jujukan token

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 62


untuk dianalisa oleh penghurai. Input terdiri daripada jujukan karakter yang pelbagai
termasuk juga ruang kosong.

Ruangan kosong dan komen dalam aturcara perlu diabaikan untuk memberikan
maksud kepada pengkompil. Jujukan karakter yang terdiri daripada token dipanggil
lexeme.

Pemalar

Apabila digit muncul dalam ungkapan, ia berkemungkinan satu pemalar integer


kerana pemalar integer merupakan jujukkan digit.

Tugas untuk mengenalpasti digit sebagai integer dilakukan oleh penganalisa leksikal.

Biarkan num mewakili token integer. Apabila jujukan digit muncul dalam jujukan
input, penganalisa leksikal akan menghantar num kepada penghurai. Nilai integer
tersebut dihantar sebagai atribut token num.

Sebagai contoh jika ungkapan seperti berikut wujud dalam aturcara :

31 + 28 + 59

Input kepada penganalisa ini akan menghasilkan

< num, 31> < +, > <num, 28> < +, > <num, 59>

token + tidak mempunyai atribut. Komponen kedua dalam perwakilan iaitu atribut
tidak memainkan peranan semasa penghuraian tetapi ia diperlukan semasa
penterjemahan.

Pengecaman Pencam dan Katakunci

Bahasa menggunakan pencam sebagai nama pembolehubah, tatasusunan dan fungsi.


Nahu akan mengecam pencam sebagai satu token. Sebagai contoh pernyataan;

bilangan = bilangan + pembilang;

akan ditukar oleh penganalisa leksikal sebagai id = id + id;

Jujukan token ini digunakan untuk penghuraian.

Penganalisa leksikal akan menggunakan jadual simbol untuk mengenalpasti jenis


token yang dijumpai. Jadual simbol akan menyimpan maklumat token katakunci,
pembolehubah dan sebagainya. Lexeme disimpan dalam jadual simbol dan satu
penunjuk kepada kedudukan jadual simbol ini menjadi atribut kepada token id.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 63


Kebanyakkan bahasa pengaturcaraan menetapkan karakter seperti if dan else untuk
membentuk bahasa. Karakter ini dipanggil pencam katakunci.

Satu masalah yang mungkin dihadapi oleh penganalisa adalah untuk token-token
yang mempunyai dua karakter seperti = = , < = dan > =. Teknik untuk mengecam
karakter seperti ini akan dibincangkan dalam bab khusus mengenai penganalisa
leksikal.

Antaramuka Penganalisa Leksikal

Apabila penganalisa leksikal diletakkan diantara penghurai dengan jujukan input, ia


akan beroperasi dengan dua keadaan seperti yang ditunjukkan dalam rajah di bawah :

Baca Hantar token


karakter dan atributnya
input Penganalisa penghurai
leksikal

Pulang
karakter

Penganalisa akan membaca karakter dan kemudian mengumpulnya menjadi satu


kumpulan token-token yang dipanggil lexemes.

Lexemes kemudiannya dihantar bersama atributnya kepada penghurai. Dalam


beberapa keadaan, penganalisa membaca karakter di depan karakter yang sedang
dibaca sebelum membuat keputusan terhadap jenis token untuk dihantar kepada
penghurai.

Sebagai contoh, jika penganalisa menjumpai token operator >, jika karakter
seterusnya adalah =, maka token yang dijumpai adalah token lebih besar dan sama.
Tetapi jika token seterusnya adalah selain daripada =, maka ia akan memulang token
kembali kepada jujukan input dan menghantar token lebih besar kepada penghurai.
Token yang dipulang akan dibaca semula sebagai kumpulan token(lexemes) yang
baru.

Satu Penganalisa Leksikal

Tujuan penganlisa leksikal adalah untuk membenarkan ruang kosong dan nombor
muncul di antara ungkapan. Berikut adalah model penganalisa leksikal.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 64


getchar( ) lexan( )

(Penganalisa
ungetc(c,stdin) leksikal)

nilaitoken

Dalam model yang ditunjukkan di atas, karakter dibaca oleh fungsi lexan( ). Fungsi
akan menghantar nilai token menggunakan perwakilan nombor. Sebagai contoh jika
token adalah berjenis NUM, kita akan wakilkan token NUM sebagai integer 256.

Berikut adalah nahu untuk mengenalpasti sesuatu token adalah NUM.

faktor  ( unkp ) | num { print (nilai.num) }

Aturcara C untuk mengenalpasti nahu di atas boleh dilakukan secara langsung seperti
berikut :

void faktor(void)
{
if ( pandang = = ‘(’ )
{
padan( ‘(’ );
unkp( );
padan( ‘)’ );
}
else if ( pandang = = NUM )
{
printf(“ %d ”, nilaitoken);
padan(NUM);
}
else error( );
}

Sementara fungsi lexan( ) pula ditunjukkan seperti berikut :

#include <stdio.h>

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 65


#include <ctype.h>

int baris = 1;
int nilaitoken = NONE;

int lexan(void)
{
int t;
while(1)
{
t = getchar( );
if ( t = = ‘ ’ | | t = = ‘\t’ )
;
else if ( t = = ‘\n’ )
baris++;
else if ( isdigit(t) )
{
nilaitoken = t – ‘0’;
t = getchar( );
while ( isdigit(t) )
{
nilaitoken = nilaitoken * 10 + t – ‘0’;
t = getchar( );
}
ungetc(t, stdin);
return NUM;
}
else {
nilaitoken = NONE;
return t;
}
}
}
}

Dalam fungsi lexan( ), apabila karakter ruang kosong atau tab dijumpai, ia tidak
memulangkan sebarang token kepada penghurai, dan ia akan terus mengulang.

Jika karakter ‘\n’ dijumpai, pembolehubah baris akan menokok satu baris. Ia adalah
untuk memantau aktiviti yang berlaku pada setiap baris. Ini membolehkan
pengkompil mengenalpasti baris ralat.

Jika input adalah nombor, nilai interger dalam ASCII dan EBCDIC diberikan
mengguna ungkapan t – ‘0’.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 66


Jadual Simbol

Struktur data “jadual simbol” digunakan untuk menyimpan maklumat sumber


daripada bahasa yang dibina. Maklumat diperolehi daripada fasa analisis pengkompil
yang digunakan dalam fasa pemprosesan analisis.

Sebagai contoh, pada masa analisis leksikal, karakter yang membentuk pencam
disimpan dalam kemasukkan jadual simbol. Pada fasa pengkompil seterusnya,
pengkompil akan memasukkan kemasukkan ini dengan maklumat seperti jenis
pencam dan kedudukkannya dalam ingatan. Dalam fasa penjanaan kod, maklumat ini
akan digunakan untuk menjana kod yang sempurna untuk menyimpan dan mencapai
pembolehubah ini.

Rekabentuk Jadual Simbol

Rutin jadual simbol berminat untuk menyimpan dan mencapai lexeme. Berikut
adalah operasi asas jadual simbol.

SelitTok(s, t) : mengembalikan indeks kemasukkan untuk string s dan token t.


GelintarTok(s) : mengembalikan indeks untuk kemasukkan string s atau 0 jika s
tidak dijumpai.

Penganalisa Leksikal menggunakan operasi GelintarTok untuk mengenalpasti lexeme


yang telah dimasukkan dalam jadual simbol. Jika belum wujud, gunakan SelitTok
untuk memasukkan maklumat.

Mengendalikan Katakunci Rezab

Katakunci atau perkataan Rezab juga disimpan dalam jadual simbol. Sebagai contoh
token div dan mod (Pascal).

Kita boleh memberikan nilai awalan kepada jadual simbol dengan cara :

SelitTok(“div”, div);
SelitTok(“mod”, mod);

Jika fungsi GelintarTok(“div”) dipanggil, maka, nilai true akan dikembalikan. Ini
menunjukkan bahawa “div” tidak boleh digunakan sebagai pencam pembolehubah.

Implementasi Jadual Simbol

Struktur data untuk jadual simbol ditunjukkan seperti berikut :

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 67


Tatasusunan JadSim

Penunjuk lex token atribut


0
1 div
2 mod
3 id
4 id

d i v Eos m o d Eos b i l Eos i eos

p/s : Eos adalah end-of-string

Gambarajah di atas menunjukkan tatasusunan yang terdiri daripada penunjuk kepada


lokasi token, jenis token dan nilai token. Lokasi 0 dalam tatasusunan dibiarkan
kosong dalam alkhawarizmi ini. Ini disebabkan nilai 0 digunakan untuk
mengembalikan token yang tiada dalam jadual simbol.

Gambarajah tatasusunan adalah bersamaan dengan gambarajah sebaris lexeme.


Penunjuk menunjuk kepada lokasi pertama token yang disimpan dalam jadual simbol.

Berikut adalah alkhawarimi penganalisa Jadual Simbol untuk mengendalikan


pencam.

int lexan (void)


{
int lexbuf[100];
char c;

{
mula loop
{
baca c;
if c adalah ruang kosong atau tab
;
else if c adalah baris baru
baris++;
else if c adalah digit
{
setkan nilaitoken dengan nilai ini dan digit-digit selepasnya;
return NUM;
}

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 68


else if c adalah huruf
{
letakkan c dan karakter yang selepasnya ke dalam lexbuf;
p = GelintarTok(lexbuf);
if p = = 0
p = SelitTok(lexbuf, ID);
nilaitoken = p;
return medan token p dalam jadual ;
}
else {
set nilaitoken kepada NONE;
return integer untuk karakter c;
}
}
}

Daripada alkhawarizmi, apabila penganalisa leksikal membaca karakter, ia mula


menyimpannya ke dalam leksikal buffer. Jujukkan karakter tersebut kemudiannya
dirujuk daripada jadual simbol untuk melihat sama ada ia wujud atau tidak dalam
jadual simbol. Apabila pencam tersebut tidak wujud, ia akan dimasukkan dalam
jadual simbol. Pencam yang akan dimasukkan merupakan pencam pembolehubah
kerana perkataan rezab telah dimasukkan dalam jadual simbol terlebih dahulu.
Mesin Abstrak Timbunan

Pengkompil akan mebina satu perwakilan pertengahan daripada aturcara sumber.


Perwakilan pertengahan yang biasa digunakan merupakan struktur data timbunan.

Mesin abstrak mempunyai bahagian suruhan dan bahagian data dalam ingatannya.
Semua operasi arithmetik dilaksanakan pada nilai dalam timbunan. Suruhan ini
terbahagi kepada tiga kelas iaitu; arithmetik integer, manipulasi timbunan dan aliran
kawalan. Terdapat satu “program counter” (pc) untuk mengenalpasti suruhan yang
perlu dilaksanakan. Berikut Rajah berikut menggambarkan contoh mesin abstrak.

suruhan timbunan data

1 push 5 16 0 1
2 nkanan 2
3 + 7 11 2
atas
4 nkanan
5 * pc 7 3
6 ….
… 4

Suruhan Arithmetic

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 69


Mesin abstrak perlu diimplementasikan untuk setiap operator dalam bahasa
pertengahan. Dalam operasi asas, penambahan dan penolakkkan disokong secara
langsung oleh mesin abstrak.

Walau bagaimanapun, dalam operasi yang lebih kompleks, ia perlu dilakukan sebagai
jujukan suruhan mesin abstrak.

Kita memudahkan penghuraian mesin ini dengan menggangap terdapat satu suruhan
untuk setiap operator arithmetik.

Kod mesin abstrak untuk ungkapan aritmetik mesimulasikan penilaian perwakilan


postfix untuk ungkapan menggunakan timbunan. Penilaian dilakukan dengan
memproses perwakilan postfix daripada kiri ke kanan, memasukkan operan ke dalam
timbunan untuk pengiraan.

Sebagai contoh, ungkapan 1 3 + 5 *

Berikut adalah langkah-langkah untuk menyelesaikan ungkapan ini menggunakan


timbunan:

1. MasukTimbunan 1
2. MasukTimbunan 3
3. tambah dua operan teratas, KeluarTimbunan (pop) dan masukkan hasiltambah
dalam timbunan
4. MasukTimbunan 5
5. darabkan dua operan teratas, KeluarTimbunan dan masukkan hasildarab
dalam timbunan

Nilai atas timbunan pada akhirnya adalah 20. Ia adalah nilai untuk penyelesaian
ungkapan yang diberikan.

NKanan dan Nkiri

Terdapat perbezaan antara pencam pada sebelah kiri dan pencam pada sebelah kanan
dalam satu pernyataan umpukkan. Contoh :

i = 5;
i = i + 1;

Nilai pada sebelah kanan menyatakan nilai, sementara nilai di sebelah kiri
,menyatakan dimana nilai disimpan.

Begitu juga dengan penggunaan penunjuk. Jika p dan q adalah penunjuk kepada
karakter seperti berikut :

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 70


^p = ^q;
sebelah kanan ^q menyatakan karakter dan sebelah kiri, ^p menyatakan dimana
karakter akan disimpan. Istilah nkanan dan nkiri merujuk kepada nilai sebelah kanan
atau sebelah kiri.

Manipulasi Timbunan

Selain daripada suruhan untuk MasukTimbunan dan KeluarTimbunan, terdapat juga


suruhan untuk mencapai data dari ingatan.

MasukTimbunan v masukkan v dalam timbunan


Nkanan l masukkan kandungan data lokasi l
Nkiri l masukkan alamat data lokasi l
KeluarTimbunan keluarkan nilai paling atas timbunan
= nilai nkanan di atas timbunan digantikan
dengan nkiri yang berada di bawahnya.
Kedua-duanya nilai tersebut dikeluarkan
dari timbunan.
Salin MasukTimbunan salinan nilai paling atas
timbunan

Terjermahan Ungkapan

Kod untuk penilaian satu ungkapan dalam timbunan berkait rapat dengan notasi
postfix ungkapan tersebut.

Ungkapan a+b diterjemah menjadi :

Nkanan a
Nkanan b
+

Contoh ungkapan dengan umpukkan.

hari = (1461*y) div 4 + (153*m + 2) div 5 + d

Diterjemahkan menjadi :

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 71


Nkiri hari
MasukTim 1461
Nkanan y
*
MasukTim 4
Div
MasukTim 153
Nkanan m
*
MasukTim 2
+
MasukTim 5
Div
+
nkanan d
+
=

Ungkapan ini boleh dijelaskan secara formal dengan cara :

unkp  id = unkp { pern.t = ‘nkiri’ || id.lexeme || unkp.t || ‘=’ }

Atribut lexeme id, memberikan perwakilan string pencam.

Aliran Kawalan

Mesin timbunan melaksanakan suruhan dalam jujukkan numerik melainkan jika


disuruh untuk melakukan pernyataan bersyarat. Beberapa pilihan boleh dilakukan
untuk menyatakan sasaran lompatan jika terdapat suruhan lompat.

1. operan suruhan menyatakan lokasi sasaran


2. operan suruhan menyatakan jarak, positif atau negatif
3. terdapat simbol pada sasaran. (Mesin membenarkan penggunaan label)

Dengan dua pilihan pertama di atas, terdapat lagi kemungkinan tambahan untuk
mengambil operan daripada atas timbunan.

Pilihan ketiga digunakan kerana ia mudah dilaksanakan. Suruhan yang boleh


digunakan adalah :

1. Label l Sasaran lompatan adalah l; tiada kesan lain

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 72


2. Goto l Suruhan seterusnya di label l
3. Gofalse l KeluarTim; lompat jika sifar
4. Gotrue l KeluarTim; lompat jika bukan-sifar
5. halt Berhenti perlaksanaan

Menterjemah Pernyataan

Berikut adalah kod mesin abstrak untuk pernyataan bersyarat pilihan dan ulangan.

Pilihan Ulangan

Kod unkp Label test

Gofalse out Kod unkp

Kod untuk pern Gofalse out

Label out Kod untuk pern

Goto test

Label out

Dalam mesin di atas, terdapat hanya satu suruhan untuk ke label out dari aturcara
sumber; jika tidak, akan berlaku kekeliruan.

Mengeluarkan Output Terjemahan

Fungsi emit digunakan untuk mencetak hasil terjemahan. Berikut adalah nahu yang
digunakan :

Pern  if (unkp) { out = labelbaru ; emit(‘gofalse’, out); }


then
pern { emit( ‘label’, out); }

nahu asal :

pern  if (unkp) pern { out = labelbaru;


pern.t = unkp.t || ‘gofalse’ out || pern.t || ‘label’ out }

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 73


Label baru merupakan fungsi yang memulangkan label baru pada setiap kali ianya
dipanggil. Dalam tindakan semantik di atas, label baru dihasilkan dalam
pembolehubah setempat out.

Apabila tindakan semantik wujud dalam pengeluaran, unsur di sebelah kanan


pengeluaran adalah mengikut tertib kiri-ke-kanan.

Dalam pengeluaran di atas, tertib tindakan adalah: tindakan semasa menghurai unkp
dilakukan, out disetkan kepada label, dikembalikan oleh labelbaru dan arahan gofalse
dikeluarkan. Tindakan semasa menghurai pern dilakukan, dan arahan label
dikeluarkan.

Kod untuk menterjemah pernyataan umpukkan dan pilihan dilakukan seperti berikut :

void pern(void)
{
int test,out;

if (pandang = = id)
{
emit(“nkiri”, nilaitok);
padan(id);
padan(‘=’);
unkp( );
}

else if (strcmp(pandang, “if”) = = 0 )


{
padan(“if”);
padan(‘(’);
unkp( );
out = labelbaru;
emit(“gofalse”, out);
padan(‘)’);
pern( );
emit(“label”, out);
}
else error( );
}

Oleh kerana pembolehubah out merupakan pembolehubah setempat untuk fungsi


pern, nilainya tidak akan ditukar semasa panggilan fungsi ungkp dan pern.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 74


Penjanaan label adalah dalam bentuk L1, L2, … Kod-pseudo memanipulasi label
menggunakan integer dan diikuti dengan L. Pembolehubah out diitiharkan sebagai
integer kerana labelbaru mengembalikan nilai integer.

Contoh :

if (t = = ‘’ || t = = ‘\t’)

Dalam ungkapan di atas, jika t adalah ruang kosong, ujian terhadap t sama dengan tab
tidak perlu dilakukan kerana menggunakan matik ‘atau’ syarat menjadi benar jika
syarat pertama telah benar.

Ungkapan di atas sama dengan ungkapan :

unkp1 atau unkp2

dan ia boleh diimplemenkan dengan cara :

if (unkp1) true else unkp2

Berikut adalah pembuktian :

Kod unkp1
Salin // salin nilai unkp1
Gotrue out
Pop // pop nilai unkp1
Kod unkp2
Label out
Arahan gotrue dan gofalse mengeluarkan nilai dari atas timbunan.

Menggabungkan teknik-teknik

Dalam perbincangan yang lepas kita telah mewakilkan mewakilkan nombor daripada
teknik sintaks-berpandu untuk membina pengkompil.

Dalam bahagian ini kita menggunakan aturcara untuk penterjemahan infix kepada
postfix untuk bahasa yang mengandungi ungkapan yang diakhiri dengan semicolon.

Ungkapan mengandungi nombor, pencam, operator-operator +, - , *, / , div dan %.

Output daripada terjemahan ini adalah perwakilan postfix untuk setiap ungkapan.

Penerangan kepada Penterjemah

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 75


Penterjemah ini direkabentuk menggunakan terjemahan sintaks-berpandu seperti
yang telah diterangkan di bahagian atas. Token id mewakili jujukan aksara dan digit
tanpa ruangan kosong. Token id mesti bermula dengan aksara. Token num
merupakan jujukan digit sahaja. Token eof adalah karakter end-of-file.
Semua token-token dikenalpasti apabila wujud ruangan kosong, tab dan baris baru.

Berikut adalah nahu yang digunakan :

mula  sen eof


sen  unkp ; sen | 
unkp  unkp + term { printf( ‘+’) }
| unkp – term { printf(‘-’) }
| term

term  term * faktor { printf(‘*’) }


| term / faktor { printf(‘/’) }
| term div faktor { printf(‘div’) }
| term % faktor { printf(‘%’) }
| faktor

faktor  ( unkp )
| id { printf (id.lexeme) }
| num { printf(num.nilai) }

Aturcara akan bermula dengan memanggil fungsi init( ) untuk pengistiharan nilai-
nilai awalan. Ini diikuti dengan fungsi parse( ) untuk aktiviti penterjemahan.

Modul Analisis Leksikal

Fungsi lexan( ) dipanggil oleh penghurai untuk mencari token. Ia akan


mengembalikan token kepada pembolehubah nilaitok. Berikut adalah token-token
yang dijangka.

+ - * / DIV % ( ) ID NUM DONE

ID mewakili pencam, NUM mewakili nombor dan DONE mewakili aksara end-of-
file.

Penganalisa leksikal menggunakan jadual-simbol dan rutin pandang untuk


mengenalpasti sama ada pencam telah wujud atau belum. Rutin Selit digunakan untuk
memasukkan lexeme baru dalam jadual simbol.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 76


Modul Penghurai

Fungsi parse( ) digunakan untuk melaksanakan tugas ini. Fungsi ini memanggil
fungsi lexan untuk mengenalpasti token. Kemudian ia menggunakan fungsi error
untuk melaporkan ralat sintaks.

Modul Cetak dan Modul Jadual Simbol

Modul cetak menggunakan fungsi emit(t, nilait) yang akan menjana output daripada
token t dengan atribut nilait. Jadual simbol mempunyai tatasusunan jadualSim yang
mempunyai dua nilai iaitu penunjuk kepada tatasusunan lexemes dan integer yang
mengandungi perwakilan token yang disimpan. Operasi Selit(s, t) mengembalikan
indeks untuk lexeme s yang terdiri daripada token-token t. Fungsi pandang(s)
mengembalikan indeks untuk kemasukkan JadualSim iaitu lexemes s atau 0 jika s
tidak wujud.

Fungsi init( ) digunakan untuk memasukkan nilai awalan kepada JadualSim.


Perwakilan lexeme dan token disimpan dalam tatasusunan.

Aturcara :

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define BSIZE 128;


#define NONE -1;
#define EOS '\0';

#define NUM 256;


#define DIV 257;
#define MOD 258;
#define ID 259;
#define DONE 260;

#define STRMAX 999;


#define SYMMAX 100;

void unkp(void);
void term(void);
void padan(int);
void init(void);
int insert( char s[], int);
void error( char *m);

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 77


void parse(void);
int lexan(void);
int lookup(char s[]);
void factor(void);
void emit(int, int);

int lookahead;
int lineno = 1;
int tokenval = -1;
char lexemes[999];
int lastchar = -1;
int lastentry;

struct entry {
char *lexptr;
int token;
};

struct entry symtable[128];

FILE *fin;

main()
{
fin = fopen("kompil.in","r");

int i;
init();
parse();

for (i = 1; i <= lastentry; i++)


printf (" %s %d\n",symtable[i].lexptr,symtable[i].token);
fclose(fin);
return 0;
}

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 78


void unkp(void)
{
int t;
term();
while(1)
switch(lookahead) {
case '+' : case '-':
t = lookahead;
padan(lookahead); term(); emit(t,-1);
continue;
default :
return;
}

void term(void)
{
int t;
factor();
while(1)
switch(lookahead) {
case '*' :
case '/' :
case '%' :
case 257 :
case 258:
t = lookahead;
padan(lookahead);
factor();
emit(t, -1);

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 79


continue;
default:
return;
}

void factor(void)
{
switch(lookahead) {
case '(' :
padan('('); expr(); padan(')'); break;
case 256 :
emit(256, tokenval); padan(256); break;
case 259 :
emit(259, tokenval); padan(259); break;
default :
error("ralat sintaks 2");
}
}

void emit(int t, int tval)


{
switch(t) {
case '+' : case '-': case '*' : case '/': case '%' :
printf("%c\n",t); break;
case 257 :
printf("DIV\n");break;
case 258 :
printf("MOD\n");break;
case 256 :
printf("%d",tval);break;
case 259 :
printf("%s ",symtable[tval].lexptr);break;
default :
printf("token %d, tokenval %d\n",t,tval);

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 80


}
}

void padan(int t)
{
if (lookahead == t)
{
// fflush(stdin);
//lookahead = getchar();
lookahead = lexan();
}
else error("ralat");
}

int insert( char s[], int tok)


{
int len;
len = strlen(s);
if (lastentry + 1 >= 100 )
error("Jadual Simbol Penuh");
if (lastchar + len + 1 >= 999)
error ("lexemes array full");
lastentry++;
symtable[lastentry].token = tok;
symtable[lastentry].lexptr = &lexemes[lastchar + 1];
lastchar = lastchar + len + 1;
strcpy(symtable[lastentry].lexptr,s);
return lastentry;
}

void init(void)
{

char temp1[3], temp2[3], temp3[3];


struct entry keywords[3];// = {"div", DIV, "mod", MOD,0, 0};
struct entry *p;
int i;

strcpy(temp1,"div");
keywords[0].lexptr = temp1;
keywords[0].token = DIV;
strcpy(temp2,"mod");
keywords[1].lexptr = temp2;
keywords[1].token = MOD;
strcpy(temp3,"0");

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 81


keywords[2].lexptr = temp3;
keywords[2].token = 0;

for ( p = keywords; p->token; p++)


// for ( i = 0; i <= 2; i++)
insert( p -> lexptr, p ->token);

for ( i = 0; i <= 10; i++)


printf("lexemes[%d] = %c\n",i,lexemes[i]);
}

void error( char *m)


{
//fprintf(stderr," line %d : %s\n",lineno,m);
printf(" line %d : %s \n",lineno,m);
exit(1);
}

void parse(void)
{
lookahead = lexan();
while (lookahead != 260)
{
unkp();
padan(';');
}
}

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 82


int lexan(void)
{
char lexbuf[128];
int t;

while (1)
{
t = fgetc(fin);
if (( t == ' ') ||( t == '\t'))
;
else if ( t == '\n')
lineno++;
else if (isdigit(t)) {
ungetc(t,fin);
fscanf(fin,"%d", &tokenval);
return NUM;
}
else if (isalpha(t))
{
int p, b = 0;

while (isalnum(t))
{
lexbuf[b] = t;
t = fgetc(fin);
b++;
if ( b >= 128)
error ("ralat kompilasi");
}

lexbuf[b] = '\0';

if ( t != EOF)
ungetc(t, fin);
p = lookup(lexbuf);

if ( p == 0)
p = insert(lexbuf, 259);

tokenval = p;
return symtable[p].token;
}

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 83


else if ( t == EOF)
return 260;
else {
tokenval = -1;
return t;
}
}
}

int lookup(char s[])


{
int p;
for ( p = lastentry; p > 0 ; p--)
if (strcmp(symtable[p].lexptr,s) == 0)
return p;
return 0;
}

Fail kompil.in

n4om * 4 ;
(9 - no) + 3 * 4 ;
n + 1;
5 + 10 ;
7 + bil ;
10 5+2-

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 84


BAB III

Sintaks Bahasa

Definisi

Kita akan menghuraikan bahasa yang mempunyai peraturan yang mengikut notasi
yang dipanggil sebagai nahu bebas konteks. Nahu dihuraikan melalui struktur hiarki
bahasa pengaturcaraan yang dibina. Sebagai contoh pernyataan if-else dalam C
mempunyai bentuk

if ( ungkapan) pernyataan else pernyataan

Pernyataan if-else ini terbentuk dengan katakunci if, buka kurungan, ungkapan, tutup
kurungan, pernyataan, katakunci else dan pernyataan. Pembentukan ini boleh
diwakilkan dalam bentuk peraturan seperti berikut :

pern  if ( unkp) pern else pern

(nahu 1)

Dengan mewakilkan pernyataan sebagai pern dan ungkapan sebagai unkp, peraturan
ini disebut sebagai satu pengeluaran (production). Anak panah  dibaca sebagai
“boleh mempunyai pengeluaran”

Pembinaan Pokok Sintaks

Bahagian ini menunjukkan bagaimana definisi sintaks-terarah digunakan untuk


membina pokok sintaks yang digunakan untuk perwakilan gambaran penghuraian.
Rutin penterjemahan perlu mengikut dua kekangan semasa penghuraian iaitu :

1. Nahu yang bersesuaian dengan huraian tidak mengubah struktur hiarki bahasa.
Sebagai contoh, subrutin Fotran, boleh dilihat dengan melihat senarai

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 85


pernyataannya sahaja. Bagaimanapun analisis untuk subrutin lebih mudah dilihat
menggunakan perwakilan pokok yang menjejaskan gelung tersarang DO.
2. Kekangan method huraian terhadap jujukan nod dalam pokok huraian. Jujukan ini
tidak berada dalam aliran yang mana maklumat mengenai pembinaan berada.
Oleh kerana itu, pengkompil C membina pokok sintaks untuk pengistiharan.

POKOK Sintaks

Pokok sintaks berguna untuk mewakili pembinaan bahasa. Pengeluaran S  if B then


S1 else S2 membentuk pokok sintaks :

if-then-else

B S1 S2
Dalam pokok sintaks, operator dan katakunci tidak muncul sebagai daun, tetapi ia
muncul sama ada sebagai nod dalaman atau sebagai bapa. Satu lain kebaikkan dalam
pokok sintaks adalah jaringan pengeluaran boleh hilang seperti yang ditunjukkan
dalam rajah di bawah :

* 4

3 5

Pembinaan pokok sintaks untuk ungkapan

Pembinaan pokok sintaks untuk ungkapan adalah sama dengan penterjemahan


ungkapan kepada bentuk postfix. Subpokok dibina untuk sub-ungkapan dengan
membina satu nod untuk setiap operator dan operan. Anak pada nod operator adalah
akar nod yang mewakili sub-ungkapan untuk operan operator tersebut.

Setiap nod dalam pokok sintaks boleh disediakan sebagai rekod dengan beberapa
medan. Dalam nod untuk operator, satu medan mengisi operator dan yang selainnya
mengandungi penunjuk kepada nod untuk operan. Berikut adalah fungsi-fungsi yang
digunakan untuk mencipta nod pokok sintaks untuk ungkapan dengan operator binari.
Setiap fungsi akan mengembalikan penunjuk kepada nod yang baru dicipta.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 86


1. mknode(op, kiri, kanan) mencipta nod operator dengan medan op dan dua
penunjuk untuk kiri dan kanan.
2. mkleaf(id, entry) mencipta nod pencam dengan id dan satu medan mengandungi
penunjuk (entry) yang merujuk kepada jadual simbol untuk kemasukkan pencam
tersebut.
3. mkleaf(num,val) mencipta nod nombor dengan label num dengan medan
memegang nilai nombor, val.

Contoh :

Berikut adalah jujukan fungsi membina pokok sintaks untuk ungkapan a-4+c. p1,p2,
…,p5 adalah penunjuk nod pencam dan entrya dan entryc adalah penunjuk kepada
kemasukkan jadual-simbol untuk pencam a dan c.

(1) p1 = mkleaf(id,entrya);
(2) p2 = mkleaf(num,4);
(3) p3 = mknode(‘-’,p1,p2);
(4) p4 = mkleaf(id,entryc);
(5) p5 = mknode(‘+’,p3,p4);

Pokok ini dibina dari bawah ke atas. Fungsi memanggil mkleaf(id,entrya) dan
mkleaf(num,4). Panggilan ini mencipta nod daun untuk a dan 4 dan penunjuk untuk
nod-nod ini disimpan menggunakan p1 dan p2. Panggilan mknode(‘-’,p1,p2)
kemudian membina nod dalaman dengan anak nod adalah a dan 4. Selepas dua
langkah, p5 menunjuk kepada akar.

Definisi sintaks-terarah dengan pokok sintaks

Rajah di bawah mengandungi S-atribut untuk membina satu pokok sintaks untuk satu
ungkapan yang mengandungi operator + dan -. Penggunaan atribut nptr untuk E dan
T adalah untuk menjejaki penunjuk yang memulangkan panggilan fungsi.

Pengeluaran Peraturan semantik


E  E1 + T E.nptr = mknode(‘+’, E1.nptr, T.nptr)
E  E2 – T E.nptr = mknode(‘-’, E1.nptr, T.nptr)
ET E.nptr = T.nptr
T  (E) T.nptr = E.nptr
T  id T.nptr = mkleaf(id, id.entry)
T  num T.nptr = mkleaf(num,num.val)

Peraturan semantik yang berkaitan dengan pengeluaran T  id dan T  num


menyatakan atribut T.nptr sebagai penunjuk kepada daun baru untuk pencam dan
nombor. Atribut id.entry dan num.val adalah nilai leksikal yang dipulangkan oleh
penganalisa leksikal dengan token id dan num.

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 87


Daripada rajah di bawah pula menunjukkan bahawa ungkapan E adalah istilah
tunggal yang berkaitan dengan pengeluaran E  T. Atribut E.nptr menunjuk nilai
T.nptr. Apabila peraturan semantik E.nptr = mknode(‘-’, E1.nptr, T.nptr) yang
bersamaan dengan E  E1 – T dilakukan, peraturan yang sebelumnya, E1.nptr dan
T.nptr menunjuk kepada daun untuk a dan 4.

E.nptr

E.nptr + T.nptr

E - T.nptr id

T.nptr num +
-
id
num 4 id
id
a c

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 88


B S
bahasa, 1, 2, 3, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 19, sintaks, 46
24, 31, 36, 39, 42, 43 Sintaks, 4, 8, 14, 19, 20, 35, 42, 43

P
pengaturcaraan, 1, 2, 10, 14, 16, 18, 19, 24, 36, 42

Teknik Pemprosesan Bahasa – TK,FTSM,UKM 89

Anda mungkin juga menyukai