Lexer Yapmak | Karşılaşacağım Hatalar,Seçmemi Önerdiğiniz Dil,Ekstralar

Merhabalar!

Kendimi geliştirmek amacıyla bir dil yapmayı hedefliyorum.Python,C,C++,Java gibi bir dil olmayacak,merak etmeyin.Amacım dediğim gibi kendimi geliştirmek.Konsol uygulaması yapabilen cross-platform bir dil yapabilirsem ne mutlu bana.Bazı konularda danışmam gerekiyor ve burada bunları cevaplayacak kişiler olduğunu biliyorum.Konu kalabalığı yapmamak için lütfen konu ile alakasız soruları özelden veya yeni bir konu oluşturarak sorun.

1. Hangi Dili Seçmeliyim?

C ve C++ burada en iyi seçim gibi duruyor.C++ performans ve geniş kullanım alanıyla radarıma girdi.C++ ile kötü bir dil yapmak C ile iyi bir dil yapmaktan kötü,bunu biliyorum ama iki dili de bilmediğim için hangisini öğrenirsem öğreneyim yüksek ihtimal aynı şeyleri yapacağım.Ayrıca OOP desteği olan bir dil C++.

2. Karşılaşacağım Hatalar

Lexer birkaç yüz satır olacak gibi.Algoritmayı hazırladım ama dili bilmediğim için bir şey yapamıyorum :frowning:

Merhaba dünya örneğinin şöyle olmasını hedefliyorum :

yaz("Merhaba dünya!\y")

//Yorum satırı

Yapmayı planladığım dil derlenecek bu arada.Lexer şöyle işleyecek :

[kod: yaz]
[girdi: ""]
[değer: Merhaba Dünya]
[komut: yeni_satır]

Kodda bulunan \y “yeni satır” anlamına geliyor.Print’in Println’i var ama buna bir şey bulamadım :smiley: Bu yüzden \n yerine \y kullanmayı planladım.

Buradaki Lexer hata verecek midir? Veya Lexer’a eklemediğim şey nedir?

Şimdiden teşekkürler.İyi forumlar…

C ile C++ arasında kalıyorsan C seç.

Sanırım bunlar token type: token value şeklinde veriler. Yeni satır karakterinin karakter dizisi değerinden ayrılmasına gerek yok, derlenirken "\n" karakterine dönüştürülebilir.

Bu arada normalde lexer’ler yukarıda gösterdiğiniz şekilde çalışmıyor, şunun gibi bir çıktı veriyor:

[(TokenTypes.IDENTIFIER, "yaz"), (TokenTypes.LEFT_PAREN, "("), (TokenTypes.STRING, "Merhaba dünya!\n"), (TokenTypes.RIGHT_PAREN, ")")]

yaz’ın bir fonksiyonu temsil ettiğine parser karar verir mesela, lexer değil.

C’de println yok.

Ortada henüz bir kod yok. Nasıl bir hatadan bahsediyoruz?

Sebebini açıklayabilir misiniz?

Bilgilendirme için teşekkür ederim.Lexer mi önce çalışıyor yoksa Parser mi?

Herhangi bir dilde olabilir bunlar.Dil belirtmemiştim :slight_smile:

Kurduğum algoritmanın değişmesi gerektiği,%100 hata verecekmiş çünki ( ve ) karakterlerini tanımlamamışım.Kod olmasa bile hata olacağı bariz :slight_smile:

C, C++'a kıyasla çok daha basit ve öğrenimi kolay bir dil. Bazı konularda type safety açısından problemleri var ama zaten siz yorumlanan bir dil yapacağınız için (değil mi?) C kodunda buna sebep olacak yapılara ihtiyaç duymazsınız diye tahmin ediyorum.

Bunu lexer yapmaya karar veren birinin zaten bilmesi lazım.

Aslında değil :smiley: Derlenmesini planlıyorum.

İngilizce eğitimlerde Lexer yaparak başlıyorlar.Oradan bildiklerimle sordum.

Dil mi yapiyorsun, lexer mi yapiyorsun, anlamadim.

Lexer yaptigini varsayiyorum. Python.

Lexer yapiyorsun, ikisiyle de isin yok.

Burada yine bir kafa karisikligi var. C ve C++ gibi programlama dilleriyle program yapiliyor, dil degil.

C++ ogrenmek icin C bilmek gerekiyor. Veya: C++ ogrenirken C’nin %80’ini ogreniyorsun zaten.

Neden? Lexer ne ise yariyor?


Hic calismakta olan bir lexer gordun mu? Yapmaya calistigin seyin neye benzeyecegini biliyor musun?

3 Beğeni

Sıfırdan yapmaya kalkarsan bazı şeyleri öğrenmen gerekir. Kaynak kodundan başlayıp, makine koduna kadar(veya başka bir ara dile kadar) olan süreçte neler olup bittiği hakkında fikrin olmak zorunda. İnternette bunun için kaynak çok, bence kaynak bulmak zor olmaz senin için.

Ama sorun henüz hiç birine bakmadan, fikir edinmeden bir şeyler üretmeye kalkman Ve soruları da bu üretmeye çalıştığın temelsiz fikirler üzerinden sormak. Ben bir kaynak paylaşıyorum. İçerisinde yer alan örnek kodları kendin inceleyip mantığı anlarsan, belki sıfırdan kendin yapmak isteyebilirsin.

Ha tabiki sıfırdan yapmak zorunda değilsin. Birçok araç geliştirilmiş bugüne kadar. Temel mantığı anladıktan sonra bu araçlar üzerinde kendini geliştirip basit bir dil tasarlayabilirsin.

Haklısınız.Lexer’in bile ne olduğunu bilmiyorum galiba.Yapmak istediğim bir dil yapmak,basitçe.Galiba yeni bir konu gerekli?

Dili yapmak icin “kagit-kalem” yetiyor.

Dilin compiler’i, ne bileyim linter’i, interpreter’i dedigin noktada programlara ve programlama dillerine basvuruyorsun.

Istersen dildeki butun ozellikleri ornekleyerek basla. (Simdiye kadar fonksiyon cagrisi, string deger, bir adet escape ve tek satirlik yorum gorduk.) Yeni konu da olabilir, evet.

2 Beğeni

Selam dostum bende seninkine benzer bir sıkıntı çekiyorum yazılım bilgim vardı algoritma idare ederdi
Ama tokenler falan ugrasmamistim.
bak şöyle yap yazıyorum mantığını

İnputla istenilen Dosya aç

Dosyayı oku

Açılan dosya adında ve yazma modunda bir dosya aç ama uzantisi py olsun

Eğer dosanın içinde varsa printf

Yeni açılan dosyaya şunu yaz

// Mesela bizim çıktımız printf(“selam”) olsun bu kod değil

Printf den “f” harfini çıkart

Py uzantili dosyaya yaz

Umarım anlamissindir anlaman için biraz programlama dili bilmen lazim çok zor dil yazma ben perişan olmuştum yazilimi birakmayi bile düşündüm sabır gerekiyor bu yolda baya.

Konu eski ama hoşuma gitti birileri de cevap yazarak güncellemiş gözüme takıldı.

Gecenin 3’ü madem yazayım bir şeyler dedim.

Sürçülisan edersek şimdiden affola.

Daha önce belirtmişimdir. Bilgisayar dilleri bilmez, bilgisayarın tek anladığı dil 1011100.

Bu nedenle nasıl yazıldığı sadece insanın kavrayabilmesine kolaylık sağlamak için ortaya çıkmıştır.

İşlemci datasheetlerinde (bilgi kağıdı) genellikle assembly dilinde makine diline daha yakın bir komut kümesi referansı verilir. Zaten kumut kümesi sınırlıdır ve basit tek adımlık nadiren bir kaç adımlık komutlardan oluşur.

Öncelikle neden yeni bir dil yapmak isteyesin.

Diller şimdiye kadar hadi oturayım bir dil oluşturayım denilerek başlamamış. Hep ihtiyaçlar nedeniyle diller geliştirimiş.

Şimdi programlama dilleri tarihçesi anlatmaya gerek yok, ama askeri, ticari, bilimsel çeşitli ihtiyaçlar dillerin doğmasına sebep olmuş.

Burada bir programlama dili tasarlamak itiyorum dediğinde, ilk sorulması gereken, hangi ihtiyaca yönelik tasarlıyorsun olmalı.

Yanlış anlama, tabi ki bir ihtiyaca yönelik geniş kapsamlı bir dil tasarlamak zorunda değilsin, sadece bir derleyicinin nasıl çalıştığını merak ettiğin için veya bu konuda zihin cimnastiği yapmak için de dillere ilgi duymuş olabilirsin.

Cross-platform tabirin de dikkatimi çekti. Bu konuda da bir kaç şey söylemem gerekir. İşletim sistemi bir birindn oldukça farklı mantıkla çalışır, benzer yönleri de vardır. Ama birden çok platformda çalışan program yazman göründüğü kadar basit yada mantıklı olmayabilir.

Derlenen yadan o işletim sisteminin doğal yollarıyla çalıştırılabilen programlar oluşturmak için o işletim sistemine özel araçlar geliştirmek zorunda kalırsın. Yani windows için hazırladığın bir derleyci setinin linux türevlerinde ( mac ios u da unix ve linux türevleri şeklinde bir seferde ifade edeceğim yazının kalan kısmında.) doğrudan çalıştıramazsın. Tabi istisnai wine veya virtual machine gibi çözümler de var ama her konunun istisnalarına girmeyelim.

Yani elinde tasarladığın bir dil var, bu durumda, windows için ayrı bir derleyici, linux türevleri için ayrı derleyici, ne kadar linux türevlerinden ayrılabilir bilmiyorum ama android türevleri için de ayrı tasarımlar yapmak gerekir.

Hadi birden çok platform un araç seti oluşturma zorluğunu göze aldın diyelim. Bu sefer işletim sistemlerinin GUI denilen grafik kullanıcı arayüzü özellikleri farklı olduğu için bunları tüm işletim sistemleri için optimize edemeyebilirsin.

Örneklersek, bir radiobutton görselin ve kontrolcün var. Ama linuxta yada android de böyle bir modül yok. Bu durumda program android yada linux için çalışamaz. Window yada button kavramları windows için ayrı anlam ifade ederken linux türevleri ve android de farklı anlam ifade edebilir.

Yani derlenen bir dili birden çok platforma doğrudan adapte etmek ciddi emek gerektirecek her bir işletim sisteminin niteliklerinin tamamını dikkatlice ve günce olarka takip etmeyi zorunlu kılacaktır. Bu da tek kişilik dev kadroların başa çıkabileceğinden fazlasıdır.

Bu nedenle yorumlanan dilleri tercih ederler, kodlar aynı olsa bile arada bir yorumlayıcı, ilgili işletim sistemi özellikleri ile dili koordine eder ve işletim sistemi özelliklerini takip etme zorunluğundan kurtarır.

Bunlar ilk gözüme çarpan ve üzerinde sayfalarca yazı yazılması gereken konular. Ama burada keseyim bu kısmı.

Dönelim, dil için araç geliştirme kısmına.

Burada işletim sistemine ne kadar yakın bir dil kullanırsan o kadar kolaydır. Elimizdeki bir çok işletim sistemi de assembly ve C dilleriyle gayet güzel anlaşır. Bunlar için hazır bir çok derleyici, bağlayıcı, kaynak editörü, kaynak bağlayıcı gibi araçlar da rahatlıkla bulunabilir.

Ama sonuçta, eğer tasarladığın bir dili işletim sisteminin kurallarına uygun bir dosyaya dönüştürdüğün sürece, hangi dili kullanarak bu araçları oluşturduğunun çok da önemi kalmaz. Dosya giriş çıkış kabiliyeti olan herhangi bir dil, tasarladığın dil için programlar yazmana olanak sağlar.

Burada, işletim sistemleri kuralı koyar. Yani işletim sistemi hazırladığın/dönüştürdüğün dosyaları belli kurallara göre oluşturmanı ister.

Mesela, windows com, bat, exe gibi bir çok dosya biçimini yürütebilecek kabiliyetlerdedir.

Daha fazla listesini aşağıda bulabilirsin.

List of Executable File Extensions - Windows - Aerorock

Mesela windows, yürütülecek dosyayı uzantısı ile ayırırken linux dosya uzantısını dikkate almaksızın çalıştırabilir. Bu dahi belirgin bir ayrımdır. Yani linux dosyanın niteliğini x yaparak yürütülebilir hale gelen nitelik kontrolü ile çözebilirken, windows uzantısını dikkate alarak çalışır.

Yani öncelikle kendi tasarladığın dille yazdığın bir programın ilk kısıtlaması, işletim sisteminin koyduğu kriterler ve şartlardır.

Varsayılan windows yürütülebilir dosya uzantısı .exe idi ve uzun süre PE dosya formatında oluşturulması şeklinde çalışıyor du. Du diyorum, format biraz değişti. Özellikle windows 8-10 gibi sürümlerle gui üzerinde yaptığı değişikler bu formatın farklı türlerini de geliştirdi ki buna da gece gece girmek istemiyorum.

Ama PE dosya formatı için de buraya bir link bırakayım.

PE Format - Win32 apps | Microsoft Docs

Gelelim bir diğer konuya. Hangi dili kullanmayılım. Az önce söylediğim gibi dosya giriş çıkış işlemleri yapabileceğin herhangi bir dili kullanabilirsin.

C, C++, Java, Delphi, Python vs aklına gelen herhangi bir yorumlanan yada derlenen dili rahatlıkla kullanabilirsin.

Neden?

Çünkü, hepsinde dosya okuma yazma yapan bir çok komut kümesi ve kütüphane mevcut.

Peki hız? Hız sorun teşkil etmeyecektir. Bilgisayar için birkaç yüz yada bir kaç bin satır text formatında metni işlemek çok uzun süreler almayacaktır ve arada bir hız farkı göremeyeceksin. (Derleme aşaması için konuşuyorum.)

C ve C++ gibi dillerin hızlı olduğu iddasına girmeyeceğim ama, bir programı derlerken, C ve C++ gibi diller o kadar çok kütüphaneyi kullanabiliyor ki, derleme aşaması uzayabiliyor. Bu durum araçlarını oluştururken yaşayacağın bir durum. Yoksa kendi tasarladığın dil ve sürelerden bahsetmiyorum.

Dil derleme araçlarının yapım aşamasını konuşuyorum yani. Tabi bunlar içinde artık bir çok hazır araç da geliştirildi. O konuya da girmek lazım ama girersek yine uzun bir yazı olacak bir yerde kesmem gerekiyor.

C yada C++ yada java ve hatta python gibi birden çok dili kullandığında oldukça benzer yönleri olduğunu göreceksin. Yani yıl 2022 hangi dili kullanayım yada hangisi hızlı demek gereksiz kalıyor. Bir dili öğrendikten sonra diğerine geçmek sadece duruma göre bir kaç gününü alır.

Ve bunu yaptığında zaten hepsinin sanki aynı dilin lehçeleri gibi durduğunu görürsün. Tabi temel farklılıkları da var ama bunlar öğrenilmesi yada anlaşılması karmaşık konular değil.

Yani bir programlama dilini seç ve onun üzerinde çalış farketmez.

Nihayet bu kadar ön bilgiden( burada bilgiden kasıt benim bilgi verdiğim iddası değil, anahtar kelimeler ile üzerinde araştırma yapılacak konulara kasıttır, okuyucu kendi bu konularda resmi ve güvenilir kaynaklardan çalışmalıdır.) sonra biraz da dil konusunda yazayım ve bırakayım.

Dili tasarladık (İhtiyaç, keyif veya başka nedenler) Yazım formatını, anahtar kelimelerini tespit ettik.

Kodlama kısmına geldik. Bu durumda işte derleyici, bağlayıcı vs gibi konular devreye giriyor.

Şimdi, derleyici nedir, kaynak editörü nedir, bağlayıcı nedir, IDE nedir gibi konulara girmek istemiyorum, arama motorlarında bir seyahat yeterince bilgi getirecektir.

Yazdığımın metnin önce analiz edilmesi gerekir. Hangi yönlerden? Öncelikli olarak, doğru şekilde anlamlı bölümlendirmelere yarılması sağlanır.

Bu bölümlendirmeler, komut, değişken, veri bloğu, talimat, anahtar kelime ve operastörler, derleyici ön talimatı gibi farklı farklı bölümleri sezebilmelidir.

Bu bölümlendirmeleri yaparken ilk hataları da yakalayabilir. Sonlandırımamış bloklar, hatalı satır yerleşimleri vs.

Sonrasında kodları ayrıştırıp, gerekli kod parçalarının doğru yazıldığını gerekli parametrelerin oluşturulup oluşturulmadığının kontrolünü gerektirir.

Parser, lexer, compiler, linker aldı başını gitti.

Aslında bu kısmı daha uzun tutmak gerekiyor ve çok uzadı bir yerde kesmek isiyorum.

Bu aşamada, Herbert Schildt amcayı tavsiye edeceğim. Aslında C ile C yorumlayıcısı yazan bir kitabı vardı, ne zaman konu C yada C++ olunca aklıma hep Herbert amca geliyor ve hep onu referans veresim geliyor. O beni tanımaz ben onu tanımaz ama bir çok C dili kitabı okuduğum gençlik dönemimde onun ki kadar rahat ettiğim kitap hatırlayamadığımdan herhalde.

GitHub - assyrianic/Herbert-Schildt-s-Little-C: Herbert Schildt’s (vastly unmodified) Little C

Yukarıdaki kod, c ile bir yorumlayıcı yazılan bir örnek. Bulabilirseniz pdf formatında C kitabı da mevcuttu bir yerlerde.

Bir dilin nasıl tasarlanacağı ve yorumlanacağı konusunda güzel bir çalışma olur bu kod üzerinde çalışmak bu nedenle tavsiye edebilirim.

Bu kısmı hallettikten sonra düşünelin aksine derleyici ve bağlayıcı yazmak daha kolay. Ona da ayrıca bir değinmek lazım. Ama konu konuyu açar mı bir gün denk gelip yazar mıyım bilmiyorum.

Her zaman olduğu gibi hatırlatayım. Teknik döküman hazırlama amaçlı bir yazı yazmadım. Olayların felsefi ve fikir taraflarına bakıyorum hep. Gerekli yerlerde ilgili teknik yayınlara atıf yapmayı tercih ettim. Bunlar kişisel fikirlerimdir, değişmez doğrular değildir. Bu gözle okunur ve yorumlanırsa sevinirim.

03:00 civarı başladığım yazıyı 4:11 civarı sonlandırıyorum. Uzun bulanlar için şimdiden özür dilerim. Yine de yazmam gereken birden çok konuyu da kısa tutmaya çalışmama rağmen. Bi polar gibi delirmiş uzunca bir yazı yazmışım.

5 Beğeni