PLSQL – Javascript Compiler (Antlr v3 – Eclipse)
Merhaba arkadaşlar, bu yazımda sizlere bir yarışma için hazırladığım projeden bahsedeceğim. Proje java ile yazdığım, plsql dilinde verilen bir kodu javascript diline çeviren bir compiler dır. Yani Kullanıcının elinde var olan bir plsql kod parçasını, aynı işi yapan bir javascript kod parçasına çeviren bir derleyici.
Projede lexer ve analyser olarak antlr kütüphanesi kullanılmıştır.Java ile Eclipse üzerinde geliştirilmiştir.
Antlr kütüphanesinin kullanımı ve eclipse üzerine kurulumu burada detaylı olarak anlatılmaktadır. Antlr kütüphanesinin detaylı kullanımından istek olması üzerinde ileride detaylı bir şekilde bahsedebilirim.
Şimdi projemize dönelim. Programımız iki şekilde hizmet sunabilmektedir. İster basit kullanıcı arayüzü ile aşağıda gördüğünüz gibi plsql kodunu programda bulunan alana yazarak javascript karşılığını hemen alabilirsiniz.
İsterseniz plsql kaynak kodunu herhangi bir dosyadan okuyup, javascript halini yine dosyaya yazabilirsiniz.
Antlr kütüphanesini kullandığım için, benim java ile herhangi bir lexer ya da anayzer yazmama gerek kalmadı. Bu işi benim yerime yapan kütüphane sayesinde sadece istediğim özelliklere sahip dilin grammer yapısını yazmam gerekiyordu. Kullanacağım dil yeni bir dil olmayacaktı. Zaten var olan bir dildi.Yani Plsql. Bu dile ait bir kaç satır grammer özelliği şöyledir.
for_loop_statement :
FOR ID IN ( ~(LOOP) )+ LOOP ( statement SEMI )+ END LOOP label_name?
;
Antlr kütüphanesi benim yazdığım bu grammeri kendisi lexer ve analyzer olmak üzere iki java classına çeviriyor. Geriye ise benim bu classları kullanarak programı (plsql javascript compiler )yazmam kalıyor.
Programın çalışma mantığından bahsedecek olursak. Öncelikle basit bir örnekle anlatalım. Örneğin programımız 3+4*5 matematiksel işlemini Topla(3,Çarp(4,5)) haline çevirsin. Burada çarpmaya öncelik veriyoruz. Ve çalışma mantığı bir ağaç yapısını andırıyor.
Grammer:
İşlem = <Sayı> < + > <Sayı>
Sayı = <Sayı> < * > <Sayı> | <1-9>
Yukarıdaki grammerda görüldüğü gibi left most derivation’da 3+4*5 sağlanıyor. (Bu çok basit bir grammer) İşte gerçek grammer dosyamızı yazarken aynen bu şekilde yazıyoruz dilimizi.
Eğer bu grammeri çalıştırırsak şöyle bir ağaç elde ederiz.
Program çalışırken tüm kodu kapsayan böyle bir ağaç üretiyor. Daha sonra ağacı root’tan başlayarak leaf (yapraklar)lere kadar tarıyor ve bu noktadan geriye dönerek recursive bir yapı gibi roota çıkarak işlemi tamamlıyor.
İşte tam bu noktada grammer dosyamızı hazırladıktan sonra, grammer kurallarının arasına istediğimiz çevirme işlerini yapacak kodları ekleyeceğiz. Yukarıdaki örnekte bu işlemi yapacak olursak. Şöyle bir görüntüyle karşılaşacağız.
Grammer:
İşlem = <Sayı> < + > <Sayı> return “Topla(deger1,deger2)”
Sayı = <Sayı> < * > <Sayı> return “Çarp(deger1,deger2)” | <1-9> return”deger”;
Yukarıdaki grammerı incelersek ağaç leaflerden geriye giderken değer döndüre döndüre gidiyor. En sonda dönen stringi aldığımızda, bizim diğer dile çevrilmiş kodu elde etmiş oluyoruz.
İşte program ana mantıkla bu şekilde çalışıyor. Örneğin for döngüsünün son hali:
for_loop_statement returns [String result] :
{
//for loopu tanımlanırken ikiden fazla sınır değeri almasını önlüyoruz
boolean isFirstVariable = true;
String firstVariable = “”;
String secondVariable = “”;
//artan değil azan bir for loopu ise set ediyoruz
boolean reverse = false; }
FOR id=ID IN {$result = “for (var “;}
( l1=(~(LOOP))
{
//reverse ile azalan bir loop olacağını anlıyoruz
if($l1.getText().equals(“reverse”)){
reverse = !reverse;
}
//Helper.isNumber ile ilk değerin sayı olup olmadığını kontrol ediyoruz
else if(isFirstVariable && Helper.isNumber($l1.getText()) )
{
firstVariable = $l1.getText();
isFirstVariable=false;//ikinci değere geçiyoruz
}
else if(Helper.isNumber($l1.getText()))
{
secondVariable = $l1.getText();
}
} )+
{
if(reverse){
$result += $id.getText()+”=”+secondVariable+”; “+$id.getText()+”>”+firstVariable+”; “+$id.getText()+”– ){\n”;
}
else { $result += $id.getText()+”=”+firstVariable+”; “+ $id.getText()+”<“+secondVariable+”; “+$id.getText()+”++ ){\n”;
}
}
LOOP ( statement SEMI {$result += $statement.result+”\n”;} )+ END LOOP {$result +=”}\n”;} label_name?
;
Program bir o kadar basit görünmesine karşın, biraz da geliştirilmesi zor bir hal alıyor.
Programın kaynak kodlarını buradan indirebilirsiniz.Bu proje, itü projekent 2012 kapsamında yarışmış ve dereceye girmiştir.
Bunlara da Göz Atmak İsteyebilirsiniz.
<<< Önceki: Java Web Frameworkleri
Sonraki: Dünyanın En Pahalı İnternetini Kullanıyorsun, Üstüne de Sınırlandırılıyorsun ! >>>
Yorum Bırakın!