Bir derleyici yapmak mı istiyorsunuz? Yalnızca bu iki makaleyi okumanız yeterli (2008)
(prog21.dadgum.com)- Çoğu derleyici ders kitabının teori odaklı ve çok kapsamlı olması, yeni başlayanların gerçekten çalışan bir derleyiciyi uygulamasını zorlaştırdığı sorununa dikkat çekiliyor
- Bunu aşmaya yardımcı olacak pratik bir kaynak olarak Jack Crenshaw'ın “Let’s Build a Compiler!” serisi tanıtılıyor; tek geçişli yapıda sade bir Pascal derleyicisini ele alıyor
- Bu öğretici, sözdizimi çözümleme ile kod üretiminin birleştirilmesini, en düşük düzeyde optimizasyonu ve C·Forth sürümleri üzerinden deneysel öğrenmeyi destekliyor
- İkinci kaynak olan “A Nanopass Framework for Compiler Education” makalesi ise çok sayıda basit dönüşümden (pass) oluşan modüler bir derleyici mimarisi sunuyor
- Her iki kaynakla gerçek uygulama deneyimi kazandıktan sonra, gerekirse geleneksel ders kitaplarına (Dragon Book) başvurularak ileri düzey öğrenime geçilebileceği belirtiliyor
Derleyici öğrenmenin gerçekliği ve iki temel makale
- Mevcut derleyici kitaplarının aşırı kapsamlı ve zor olması nedeniyle, yeni başlayanların gerçekten çalışan bir derleyici yazmasının güç olduğuna dikkat çekiliyor
- Kitapların çoğu düzenli ifade dönüşümleri, dilbilgisi kuramı gibi çok geniş konuları ele alıyor ve pratik bir başlangıç noktası sunmuyor
- Bu da “derleyici yapmak zordur” şeklindeki yanılgı ve mitlerin oluşmasına yol açıyor
- Bu algıyı kıran temsilî bir kaynak olarak Jack Crenshaw'ın “Let’s Build a Compiler!” serisi tanıtılıyor
- 1988'de başlayan bu öğretici, Turbo Pascal düzeyinde tek geçişli bir derleyiciyi ele alıyor
- Sözdizimi çözümleme ile kod üretimini birleştiren bir yapıya sahip ve yalnızca asgari düzeyde optimizasyon yapıyor
- Aslen Pascal ile yazılmıştır; daha sonra C sürümü ve Forth çevirisi de ortaya çıkmıştır
- Forth sürümü, etkileşimli dil özellikleri sayesinde denemeyi ve anlamayı kolaylaştırıyor
- Crenshaw serisinin sınırlılığı, programın iç gösteriminin (soyut sözdizimi ağacı, AST) bulunmaması
- Pascal'da ağaç manipülasyonu karmaşık olduğu için bu kısım atlanmış olsa da, Python, Ruby, Erlang, Haskell, Lisp gibi yüksek seviyeli dillerde bunu uygulamak kolaydır
- Bu diller zaten ağaç yapısındaki verileri işlemek için tasarlanmıştır
- İkinci olarak önerilen kaynak, Sarkar, Waddell, Dybvig imzalı
“A Nanopass Framework for Compiler Education” makalesi
- Temel fikir, “derleyicinin programın iç gösterimini adım adım dönüştüren bir süreçler dizisi olduğu”dur
- Onlarca ila yüzlerce basit dönüşümden (pass) oluşan bir yapı önerir
- Her dönüşüm mümkün olduğunca basit tutulur ve dönüşümler arasında sıkı bağ kurulmasından kaçınılır
- Çerçeve, her geçişin giriş ve çıkışını açıkça tanımlar
- Uygulama dili Scheme'dir ve dinamik tip temelli çalışma zamanı doğrulaması yapılır
- Bu iki kaynakla gerçekten bir derleyici yazdıktan sonra, gerekirse Dragon Book gibi geleneksel kaynaklarla daha ileri çalışmalara geçilebilir
- Ancak yalnızca bu iki kaynakla bile yeterince pratik derleyici geliştirme deneyimi edinmek mümkündür
1 yorum
Hacker News görüşleri
Donald Knuth'un The Art of Computer Programming eseri hâlâ yazım aşamasında ve artık derleyici konusunu ele almama ihtimali yüksek
Ben yazarın iddiasına katılmıyorum. Dragon Book (Aho ve diğerleri) 2. bölümü tek başına okunsa bile yeterince bütünlüklü bir derleyiciye giriş kitabı sayılır
Bir başka harika giriş kitabı da Niklaus Wirth'ün Compilers eseri; 100 sayfadan kısa olmasına rağmen tam bir derleyicinin kaynak kodunu ve net açıklamaları içeriyor
Lisedeyken bu iki kitap sayesinde kendi derleyicimi yapabilecek kadar şey öğrenmiştim
Uygulamaya odaklanıp gerçek bir derleyicinin nasıl yapıldığını adım adım izleten kitapların çok daha iyi olduğunu düşünüyorum
Kaynaklar bu bağlantıda derlenmiş
2. baskıya veri akışı analizi eklenmiş olsa da modern derleyicilerin (GCC, LLVM vb.) çekirdeği olan SSA(Static Single Assignment) biçimine yalnızca bir sayfa ayrılıyor
Modern bir backend yapmak için SSA teorisini ayrıca çalışmanız gerekir
Bkz. TAOCP resmi sayfası
Abdulaziz Ghuloum'un An Incremental Approach to Compiler Construction makalesi
“Derleyiciler sihirli varlıklardır” algısını kırıyor ve yorumlayıcı kadar kolay derleyici yapılabileceğini gösteriyor
Scheme dilinin büyük bir bölümünü destekleyen ve Intel x86 için assembly üreten bir derleyicinin adım adım nasıl inşa edildiğini ayrıntılı biçimde anlatıyor
Son dönemde meta-compiler ve Adaptive Compilation, JIT compiler gibi alanlarla derleyici teknolojisi çok ilerledi
Alan Kay'in araştırma grubu VPRI karmaşıklık sorunlarını ele alıyor
İlgili kaynaklar: Ometa makalesi, Adaptive Compilation videosu, Alan Kay konuşması
Kitap okumaya dair iyi bir tavsiye duymuştum: kitaplara RAM gibi rastgele erişim(random access) yapılabilir
Sadece ihtiyaç duyduğunuz kısımları okuyunca kalın kitaplar da daha az göz korkutuyor
Ama neyi bilmediğinizi bilmiyorsanız bu yöntem işe yaramıyor. Bu yüzden hafif giriş kitapları çok önemli
Bugünlerde en çok Crafting Interpreters tavsiye ediliyor
Nanopass makalesinin bağlantısı bozuk
Bu yüzden Crafting Interpreters'ın özünü özetleyen bir cheat sheet hazırladım
Kitap basit bir el kitabı değil, deneyim odaklı bir öğrenme kaynağı; visitor pattern gibi konularda yazarın aldığı keyif hissediliyor
Son zamanlarda eğlencesine oyuncak bir derleyici yapıyorum
Karmaşık parsing teorileri ya da DSL'ler yerine Megaparsec parser combinator kullanıyorum
Parsing mantığı açık, yeniden kullanımı kolay ve geleneksel lexer/parser ayrımının zahmeti yok
Daha az hata çıkarıyor, hata teşhisi daha iyi ve çoğu dil de (C#, Rust vb.) bu yaklaşımı kullanıyor
tree-sitter da harika ama çok bağımlılığı var. Recursive descent ise bağımlılıksız ve sade bir uygulama sunuyor
Parser combinator yaklaşımının avantajı, hem lexer'ı hem parser'ı aynı parser type ile ele alabilmeniz
Boşluk işleme ve tokenization sorunlarını temiz bir şekilde çözebiliyorsunuz
Daha önce ölü olan Nanopass makalesine buradan ulaşılabiliyor
Bana derleyicileri öğreten şey, 1978 tarihli BYTE dergisindeki Tiny Pascal compiler makalesiydi
Optimizasyonu Stanford'da Ullman ve Hennessy'nin verdiği yaz dersinde öğrendim
Kod üreticisi ise kendi geliştirdiğim özgün bir yöntemdi
Dragon Book bende var ama aslında hiç okumadım
Nanopass yaklaşımının özü pass sayısı değil, her pass için açıkça tanımlanmış giriş ve çıkış dilleri belirlenmesi
Bu yapısal düşünme tarzı sayesinde çalıştırmadan önce çok sayıda hatayı yakalayabiliyorsunuz
Crenshaw'un öğreticisi de harika ama gerçekten ölçeklenebilir bir derleyici yapmayı sağlayan fark, bu dil değişmezlerini yönetme yaklaşımı
UC Irvine dönemimde, Niklaus Wirth'ün öğrencisi olan Profesör Michael Franz'ın CS241 dersinde optimizasyon yapan bir derleyici yazdığımı hatırlıyorum
Ödev, DLX adlı bir sanal makine için bytecode üretmekti
İlgili materyallere DLX mimarisi açıklamasında ve
register allocation algoritmasına dair referans görselde bakabilirsiniz