Programlama dilimizi yazmaya devam ediyoruz. Bir önceki yazıdaki lexer’a lparen, rparen, comma türlerini ekledim. Siz de bu türleri lexerınıza ekleyin ki print(1, 2) gibi fonksiyonları çağırabilelim.
Parser’ın çalışması için Intermediate Language yazmamız gerektiği için IL çıktısı verilen yerde writeln ile konsol çıktısı vereceğiz. Daha sonradan IL’i tanımladıktan sonra bu writeln fonksiyonlarını dönüştüreceğiz.
Öncelikle parser.d adında bir dosya açalım ve içerisine aşağıdaki yapıyı tanımlayalım.
Bu yapı parser içindeki fonksiyonlar arasındaki iletişimi sağlayabilmek için dönüş değerlerini içeriyor. Fonksiyonlardan parse edilen veriyi döndürmek yerine IL çıktısı vereceğimiz için bir şekilde döndürülen verinin türünü, formatını belirtmemiz gerekecek.
Parser için bir class açtım ve bunu Lexer sınıfından türettim. Bakıldığında Lexer için sınıf açmaya gerek yok gibi duruyor ama ileride Lexer’ınızı geliştirmek isterseniz (Örneğin Token dizisini kaldırıp yield ile Token vermek) sınıf olması daha çok işinize gelecektir.
Şimdi buraya kadar ön hazırlığımızı yaptık. Şimdi tokenleri tek tek işleyeceğiz. Benim burada yapacağım dlin ; kullanımını zorunlu tutmak, ana main içerisinde gereksiz değişken varlığını engellemek gibi bazı katı kuralları olacak. Siz isterseniz bu katı kuralları sisteme dahil etmeyebilir daha farklı kurallara sahip bir dil yapabilirsiniz.
Burada a = 1 şeklindeki bir ifadenin = kısmına kadarını aldık ve şimdi sonraki işlemi kontrol ettireceğiz. Yani = mi gelmiş yoksa bir parantezler () gelip fonksiyon mu çağırılmş.
Burada = den sonra bir değişken, integer, string veya bir matematiksel işlem gelebilir. O yüzden bu tarz genel şeyleri getIt fonksiyonu içerisinde tanımlayacağız. Bu fonksiyon bir değer işliyor mu işlemiyor mu ve eğer işliyorsa da işlediği verinin türünün bilgisini RetType sayesinde öğreneceğiz ve eğer bir ifade dönmüyorsa hata verdireceğiz.
= işaretini algıladığımız gibi fonksiyon çağırma işlemini de algılayacağız ve yine bu işlemi birden fazla yerde yapacağımız için getFunction adında bir fonksiyon içerisinde kodlarını tanımlayacağız.
Daha öncede belirttiğim gibi dili biraz katı kurallı yapıyorum ve noktalı virgülü yukarıdaki kodlar ile zorunlu hale getiriyorum.
Şimdi ise getIt fonksiyonunu tanımlayalım. Temel türlerimizin ayrıştırılmasını sağlayacağız.
Ve son olarak da getFunction fonksiyonumuzu tanımlıyoruz.
Parser içerisinde 1 + 2 * 4 gibi matematiksel ifadeleri işlem önceliğine göre ayrıştırma işleminin nasıl yapılacağını bir sonraki yazımda anlatacağım.