Önceki yazıda bir yorumlayıcının nelerden oluştuğu hakkında bahsetmiştim. Artık kendi dilimizi tasarlamanın zamanı geldi. Bunun için ilk önce bir lexer yapacağız.
Bu yazıda D dilini kullanarak lexerımızı inşa ediyoruz. Neden D dili seçtiğimi ise bir başka yazımda değineceğim. Ben burada kodları Ubuntu 13.10 64 bit üzerinde yazdım. DMD ile derledim. DMD’yi buradan indirebilirsiniz. Eğer ddiline yeni iseniz Ali Çehreli hocamın yazmış olduğu ve şu an Amerika’da bazı üniversitelerde okutulmakta olan kitabından D dilini öğrenebilirsiniz. Kitaba erişmek için ddili.org/ders/d/ sayfasına bakabilirsiniz. D dilinde Merhaba Dünya yazımı okumak için buraya tıklayabilirsiniz.
Öncelikle bir enum oluşturacağız ve içerisine lexerımızda kullanacağımız Token türlerini yazacağız.
Yukarıda true ve false için başına _ eklemek zorunda kaldık çünkü kullandığımız D dili içerisinde true ve false ları keyword olarak görmesi karışıklık yaratıyor.
Ve şimdi de Token struct’ımızı tanımlıyoruz. Burada oluşturduğum Token içerisinde sadece tür ve değer bilgilerini tutuyorum siz isterseniz satır ve sütun bilgilerini de tutabilirsiniz.
Fonksiyonumuzu oluşturuyoruz.
Kaynak kodu parçalamak için sonlu otomataları kullanıyoruz.
Sonlu otomatalar bir durumdan diğer duruma geçişi esas alır. Sistem 0 başlangıç durumundan başlar. Her durum için bir geçiş kümesi tanımlanır. Örneğin aşağıdaki çizimde ilk durum için a-z geçiş kümesidir. 0 dan 1 e geçiş yapabilmek için a-z harflerinden biri gelmek zorundadır. 1.duruma geçiş yaptığında ise a-z ve 0-9 karakterleri artık geçiş kümemiz oldu ve o karakterler geldiği sürece 1.durumda kalınır.
Bizim yapacağımız sistemde bu küme dışında karakter gelirse kimi durumda hata verdireceğiz kimi durumda ise başlangıç durumu yani 0’a geri döneceğiz. Bunu koda dökersek eğer;
Burada kodda karakterin a-z ve A-Z arası olup olmadığını std.ascii içerisinde bulunan isAlpha ve isAlphaNum ile kontrol ettik. Şimdi ise tmp de tutulan kelimeyi token dizisine aktarma zamanı.
Kaynak koddaki boşluk, tab, yeni satır gibi beyaz karakterleri görmezden gelelim.
Harfleri yakaladığımız gibi rakamları yakalayalım.
Bu lexer da stringleri tırnak karakteri ile başlattım ve sonraki tırnak karakterine kadarki bütün karakterleri topluyoruz.
Ve aynı şekilde + - gibi özel karakterleri ve yorum satırlarını yakalayacağız.
Son olarak eğer beklenmedik bir karakter geldiyse ekrana hata mesajı fırlatacağız.
Evet artık Lexerımız hazır sadece kendisine gönderilecek olan kodu bekliyor. Ben deneme amaçlı aşağıdaki kodu yazdım.
Aldığım çıktı ise:
Projeyi indirmek için: Make Your Own Language - 1
isWhite, isDigit gibi fonksiyonların bulunduğu std.ascii kütüphanesi