Herhangi bir dilde programlama yapmak için öncelikle o
dile özel bir programa ihtiyaç duyarız. Bu program kaynak kodumuzu
yazabileceğimiz ve kodumuzu çalıştırabileceğimiz bir yapıya sahiptir. İşte bu
özel programa “derleyici” adı verilir.
Derleyici kaynak dildeki bir programı hedef bir dile ya
da hedef bir makineye uygun dile dönüştürür. Makine dilinde programlama yavaş,
hataya açık ve zordur. Kullanılan bilgisayarın mimarisi ile ilgili bilgi
gerektirir. Ayrıca makine değiştiğinde kodu kullanmak mümkün olmaz. Derleyici,
programımızı üst düzeyde rahat bir şekilde yazarak istediğimiz bilgisayarda
çalıştırmamızı sağlar. Bizi makine düzeyine inmekten kurtarır. Derleyici kaynak
olarak aldığı kodu çalıştırabilir koda dönüştürür.
Derleyici, kaynak kodumuzu kolay bir şekilde yazmak, hızlıca gözden
geçirebilmek, yazım hatalarımızı daha kolay görebilmek gibi konularda, bize yardımcı
olmak amacıyla gelişmiş bir metin düzenleyicisine sahiptir. Tabii ki, bu
özellik günümüz derleyicileri için geçerlidir. Eski yıllardaki derleyiciler bu
konuda daha zayıftılar.
Yazdığımız kodu derlediğimizde derleyici, varsa mantık ya da söz dizimi
hatalarımızı listeleyecektir. Ayrıca çalışma sırasında sorun çıkarabilecek ya
da fark edilemeyecek farklı çalışmalara sebep olabilecek durumları da uyarı
olarak listeler. Derleme işlemini belirli satırlara kadar yapmamız ya da her
satırın etkilerini adım adım gözlemlememiz de mümkündür. Bunların dışında
derleyicilerin geliştirmeyi kolaylaştırıcı birçok özelliği olabilir. Bu
özellikler derleyiciyi geliştirene göre değişir. Örneğin; C++ dili için farklı
firmalar tarafından geliştirilen derleyicilerin, özellikleri de çok farklıdır.
Bazı dillerin ilk oluşturuldukları zamanlarda tek derleyicisi vardır. Bu diller
genelde bir yazılım firması tarafından yazılmıştır ve derleyicileri de bu firma
tarafından oluşturulur. Dil, bu ilk derleyicisiyle tanınır. Örneğin; Delphi
dili Borland tarafından geliştirilmiş bir dildir ve yine Borland’ın yazdığı
derleyici ile kullanılmaya başlamıştır. Zamanla açık kaynak yazılımların
yayılmasıyla Delphi ve benzeri diller için açık kaynak derleyiciler ortaya
çıkmıştır. Bugün çok yaygın olarak kullanılan C# dili için de açık kaynak
derleyicilere rastlamak mümkündür.
Derleyici iki temel kısımdan oluşur: Analiz ve
sentez. Analiz (yorumlama) aşamasında,
verilen kaynak programdan orta düzey bir gösterim oluşturulur. Sözcüksel
analiz, söz dizimsel analiz ve anlamsal analiz bu aşamada yapılır. Sentez (kod
üretimi) aşamasında, bu orta düzey gösterime eş değer hedef program
oluşturulur. Orta düzey kod üretimi, kod üretimi ve kod optimizasyonu bu
aşamada yapılır.
Derleyicinin kaynak kodu çalıştırılabilir koda
dönüştürdüğünü söyledik ancak bazı derleyiciler kaynak kodu doğrudan işleme
tabi tutarak da çalıştırabilirler. Bu tip derleyicilerin özel adı
yorumlayıcıdır. Aslında yorumlayıcının çalışma mantığı da derleyiciyle aynıdır.
Sözcüksel, anlamsal ve söz dizimsel analiz aynıdır. Yorumlayıcılar, söz dizim
ağacından kod üretmek yerine söz dizim ağacını doğrudan işlerler. Bu nedenle de
daha yavaştırlar. Yorumlayıcı yazmak derleyici yazmaktan daha kolaydır. Derleme
işleminde ilk safha yorumlama, ikinci safha ise kod üretmektir. Yorumlayıcının
tek farkı kod üretme safhasının bulunmamasıdır. Yorumlayıcılar programı olduğu
gibi çalıştırır. Ön işlem
(preprocessing) azdır ya da hiç yoktur. Derleyiciler ise yoğun bir ön işleme
yaparlar. Genelde derleyiciler kullanılır. Ayrıca yorumlayıcı kodları,
çalışabilmek için bir yorumlayıcıya ihtiyaç duyarlar. Örneğin; PHP kodları PHP
derleyicisine, JavaScript kodları ECMAScript destekli bir tarayıcıya ihtiyaç
duyarlar. Bu kodlar yorumlayıcı olmadan çalıştırılamazlar. Ancak C++, Delphi
gibi derleyicilerin ürettiği kodları direkt olarak işletim sistemi üzerinden
işlemci çalıştırmaktadır.
Bununla birlikte yorumlayıcı olan ama temelde
derleyiciler gibi kod üretebilen derleyiciler de mevcuttur. Örneğin; PHP
derleyicisi yorumlayıcı gibi ayrı bir dosyada, işletim sistemine uygun bir kod
üretmeden hemen çalışmaya başlar ancak yorumlayıcıdan farklı olarak kod üretir.
Bu kod, tabii ki ayrı bir dosya değil, IIS, Apache gibi sunuculara uygun yapıda
işlem kodlarıdır. (opcode)
Derleyicinin Kısımları
Derleyicinin belli kısımlardan oluştuğunu söyledik. Bu
kısımları tek tek gözden geçirelim ve programlarımızın nasıl çalıştırılabilir
koda dönüştürüldüğü hakkında daha ayrıntılı bilgi edinelim.
 |
| Şekil
1:
Derleyicinin kısımları (derleme aşamaları) |
Her bir evre kaynak
programı farklı bir gösterime dönüştürür.
Sözcüksel
Analiz (Lexical Analysis)
Program metninin okunduğu
ve analiz edildiği ilk kısımdır. Kaynak kod derleyiciye ilk geldiği zaman, ilk
olarak, kaynak kodun harfleri teker teker işlenir ve tanımlanarak “token” adlı
nesnelere dönüştürülür. Token; değişken adı, anahtar kelime ya da sayı gibi
programlama dilindeki bir sembolü gösterir.
Örnek bir ifade:
newval:=oldval+12 –> tokenler: newval değişken
:= atama operatörü
oldval değişken
+ toplama operatörü
12 sayı
Sözcüksel analizi
gerçekleştiren derleyici parçasına “lexer” denir. Lexerın görevi, yazım analizi
yapıp sonuç olarak bir token listesi oluşturmaktır. Tokenleri tanımlamak için
düzgün ifadeler (regular expressions) kullanılır. Sözcüksel analizin
uygulanmasında sonlu durum otomatı (finite state automata) kullanılabilir. Bu
yazım analizi sırasında kaynak koddaki hatalar da bulunabilir. Bu hatalar lexer
tarafından tespit edilir ve yazım hatası (syntax error) olarak bildirilir.
Lexer, kaynak kodun ifade ettiği anlam ile uğraşmaz. Hangi tokenin hangisinden
sonra geldiği ile ilgilenmez. Örnek olarak aşağıdaki karakter katarını ele
alalım:
width := 2;
Lexer bu karakter
katarındaki her bir karakteri ayrıştırır. Eğer gramere göre bu karakter
katarında hata mevcut değilse token listesini üretir. Örnek karakter
katarımızdaki “width”, “:=”, “2” ve “;” birer tokendir. Bazı lexerlar her bir
boşluğu da birer token olarak kabul etmektedir. Tokeni, Delphi’deki bir record
ya da C++’daki bir struct yapısına benzetebiliriz. Bu record ya da struct
içinde, tokenin türü, bulunduğu pozisyon gibi değerler bulunur. Lexer, token
listesini oluşturduktan sonra işlemini tamamlar. Bu token listesini “parser”
denilen başka bir derleyici parçasına iletir.
Derleyici karmaşık bir
yapıya sahip olduğundan tüm yapısını ele almak uzun süren bir iş. Önümüzdeki
sayıda derleyicinin lexerdan sonraki aşamalarını ele alacağız. Hoşçakalın
sevgili BilişimDergi okurları.