Önyükleme hala dışarıdan destek gerektiriyor


97

Bir dili önyükleme, yani kendi başına dil için bir derleyici / yorumlayıcı yazma fikrini duydum. Bunun nasıl başarılabileceğini merak ediyordum ve etrafa biraz baktım ve birinin bunun sadece her ikisiyle de yapılabileceğini söylediğini gördüm.

  • farklı bir dilde ilk derleyici yazmak.
  • Assembly'de bir ilk derleyiciyi elle kodlamak, bu ilk derleyicinin özel bir durumu gibi görünüyor

Bana göre bunların hiçbiri, her ikisinin de dışarıdan destek gerektirmesi anlamında bir dili ön plana çıkarmıyor gibi görünüyor . Kendi dilinde bir derleyici yazmanın bir yolu var mı?


Bu tür şeyler konusunda pek tecrübeli değilim, ancak ilk derleyicinin başka bir dilde yazılması gerektiğini varsayabilirim . Derleyicilere atıfta bulunarak "önyükleme" nin, derlemek istediği dilde ilk derleyiciyi yazmayı değil, derlemesi gereken dilde bir derleyici yazmayı ifade ettiğinden oldukça eminim .
jdd

1
Bilgi için teşekkürler millet. Başlangıçta sınırlı bir derleyici yazma, ardından bunun üzerine inşa etme fikri ile açıklandığında, önyükleme fikri daha mantıklı geliyor. Bu dönem bir Derleyiciler dersi alıyorum, Steve Yegge'in Derleyicilerdeki bir sınıfın ne kadar önemli olduğu konusundaki gönderisinden büyük ölçüde etkilenen bir karar ve daha önce SO'da modası geçmiş olan Amazon bağlantısından Dragon kitabının bir kopyasını satın aldım.
pbh101

1
Ayrıca benzer soruya bakın: Kendi içinde bir derleyici uygulamak
Urban Vagabond

Yanıtlar:


108

Kendi dilinde bir derleyici yazmanın bir yolu var mı?

Yeni derleyicinizi yazmak için mevcut bir dile sahip olmanız gerekir . Örneğin yeni bir C ++ derleyici yazıyorsanız, bunu sadece C ++ ile yazıp önce mevcut bir derleyiciyle derlemeniz gerekir. Öte yandan, yeni bir dil için bir derleyici oluşturuyorsanız, buna Yazzleof diyelim, yeni derleyiciyi önce başka bir dilde yazmanız gerekir. Genel olarak, bu başka bir programlama dili olurdu, ancak olması gerekmiyor. Montaj veya gerekirse makine kodu olabilir.

Eğer varsa edildi Yazzleof için bir derleyici bootstrap edeceksen, genellikle başlangıçta tam bir dil için bir derleyici yazmak olmaz. Bunun yerine Yazzleof'un olası en küçük alt kümesi olan Yazzle-lite için bir derleyici yazarsınız ( en azından oldukça küçük bir alt küme). Sonra Yazzle-lite'da tam dil için bir derleyici yazarsınız. (Açıkçası bu, tek bir atlama yerine yinelemeli olarak gerçekleşebilir.) Yazzle-lite, Yazzleof'un uygun bir alt kümesi olduğundan, artık kendi kendini derleyebilen bir derleyiciniz var.

Bir yoktur gerçekten başlıklı, (modern makine üzerinde temelde bir onaltılık editörü) mümkün olan en düşük seviyesinden bir derleyici işe koşulması hakkında iyi writeup yoktan basit derleyici önyüklemesinin . Https://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html adresinde bulunabilir .



7

Bir süper ilginç bu tartışma Unix ortak hazırlayıcısı olduğu Ken Thompson 'ın Turing Ödülü ders.

Şöyle başlıyor:

Tarif etmek üzere olduğum şey, derleyiciler kendi dillerinde yazıldıklarında ortaya çıkan birçok "tavuk ve yumurta" sorunlarından biridir. Bu kolaylıkta, C derleyicisinden belirli bir örnek kullanacağım.

ve Unix C derleyicisinin her zaman parola olmadan oturum açmasına izin verecek bir sürümünü nasıl yazdığını göstermeye devam ediyor, çünkü C derleyicisi oturum açma programını tanıyacak ve özel kod ekleyecektir.

İkinci model C derleyicisine yöneliktir. Değiştirme kodu, her iki Truva atını da derleyiciye ekleyen Aşama I kendini yeniden üreten bir programdır. Bu, Aşama II örneğindeki gibi bir öğrenme aşaması gerektirir. İlk olarak, hatalı bir ikili oluşturmak için değiştirilmiş kaynağı normal C derleyicisiyle derliyoruz. Bu ikiliyi resmi C olarak kurarız. Artık hataları derleyicinin kaynağından kaldırabiliriz ve yeni ikili, her derlendiğinde hataları yeniden yerleştirir. Tabii ki, oturum açma komutu hiçbir yerde kaynakta hiçbir iz bırakmadan dinlenmiş olarak kalacaktır.


9
Bu konu dışı .. İlginç ama kafa karıştırıcı ve sorunun cevabı değil.
blueshift

5

Duyduğum yol, başka bir dilde son derece sınırlı bir derleyici yazmak, ardından bunu yeni dilde yazılmış daha karmaşık bir sürümü derlemek için kullanmak. Bu ikinci sürüm daha sonra kendisini ve sonraki sürümü derlemek için kullanılabilir. Her derlendiğinde son sürüm kullanılır.

Bu, önyüklemenin tanımıdır :

aynı amaca hizmet eden daha karmaşık bir sistemi harekete geçiren basit bir sistem süreci.

DÜZENLEME: Derleyici önyükleme hakkındaki Wikipedia makalesi konsepti benden daha iyi kapsıyor.




3

Anladığım kadarıyla, ilk Lisp yorumlayıcısı yapıcı işlevleri ve belirteç okuyucuyu elle derleyerek önyüklendi. Tercümanın geri kalanı daha sonra kaynaktan okundu.

Orijinal McCarthy makalesini, Sembolik İfadelerin Özyinelemeli İşlevleri ve Makineye Göre Hesaplamaları, Bölüm I'i okuyarak kendiniz kontrol edebilirsiniz .


2. ve 3. bölümlere ne oldu? ... @ Wing'in benden 3 yıl önce aynı şeyi paylaştığını nasıl fark etmedim? Ben bir aptalım En azından gazeteyi bağladım (yardımla).
luser droog

2

Diğer bir alternatif, diliniz için bir bayt kodu makinesi oluşturmak (veya özellikleri çok sıra dışı değilse mevcut olanı kullanmak) ve bayt kodunda veya istediğiniz dilde başka bir ara geçiş kullanarak bayt koduna bir derleyici yazmaktır. AST'yi XML olarak çıkaran ayrıştırıcı araç seti, ardından XSLT (veya başka bir kalıp eşleştirme dili ve ağaç tabanlı gösterim) kullanarak XML'i bayt koduna derler. Başka bir dile olan bağımlılığı ortadan kaldırmaz, ancak önyükleme çalışmalarının çoğunun son sistemde biteceği anlamına gelebilir.


2

Tavuk ve yumurta paradoksunun bilgisayar bilimi versiyonu. İlk derleyiciyi assembler veya başka bir dilde yazmamanın bir yolunu düşünemiyorum. Eğer yapılabilseydi, Lisp yapmalıydım.

Aslında, Lisp'in neredeyse hak ettiğini düşünüyorum. Check out onun Wikipedia girişi . Makaleye göre, Lisp eval işlevi bir IBM 704 üzerinde makine kodunda uygulanabilir ve tam bir derleyici (Lisp'in kendisi ile yazılmıştır) 1962'de MIT'de ortaya çıkacaktır .


2

Aklıma gelen bir dili ( C , PyPy ) önyüklemenin her örneği, çalışan bir derleyici olduktan sonra yapıldı. Bir yerden başlamalısınız ve bir dili kendi içinde yeniden uygulamak, önce başka bir dilde bir derleyici yazmayı gerektirir.

Başka nasıl çalışır? Aksini yapmanın kavramsal olarak mümkün olduğunu bile sanmıyorum.


4
İlk Lisp derleyicisi, en azından, var olan bir Lisp yorumlayıcısı kullanılarak önyüklendi . Yani anlamsal olarak başka bir dil değil, başka bir dil uygulaması.
Ken

0

Bazı önyüklemeli derleyiciler veya sistemler, hem kaynak formunu hem de nesne formunu depolarında tutar:

  • ocaml , hem bir bayt kodu yorumlayıcısına (yani Ocaml bayt kodu derleyicisine) hem de yerel bir derleyiciye (x86-64 veya ARM, vb ... assembler) sahip bir dildir. Svn deposu , derleyicinin hem kaynak kodunu (dosyaları */*.{ml,mli}) hem de bayt kodu (dosya boot/ocamlc) biçimini içerir. Dolayısıyla, derlediğinizde, kendisini derlemek için ilk olarak bayt kodunu (derleyicinin önceki bir sürümünün) kullanır. Daha sonra yeni derlenmiş bayt kodu yerel derleyiciyi derleyebilir. Dolayısıyla Ocaml svn deposu hem *.ml[i]kaynak dosyalarını hem de boot/ocamlcbayt kodu dosyasını içerir.

  • Pas (kullanarak derleyici indirme wgetonun ikili önceki bir sürümünü çalışan bir internet bağlantısına ihtiyacınız böylece) kendisini derlemeye.

  • MELT , GCC'yi özelleştirmek ve genişletmek için Lisp benzeri bir dildir . Önyüklemeli bir çevirmen tarafından C ++ koduna çevrilir. Çevirmenin oluşturulan C ++ kodu dağıtılır, böylece svn deposu çevirmenin hem *.meltkaynak dosyalarını hem de melt/generated/*.cc"nesne" dosyalarını içerir.

  • J.Pitrat'ın CAIA yapay zeka sistemi tamamen kendi kendini üretir . Bu binlerce topluluğu olarak kullanılabilir [A-Z]*.c(aynı zamanda oluşturulan ile oluşturulan dosyaların dx.hbinlerce koleksiyonu ile başlık dosyası) _[0-9]*veri dosyalarının.

  • Birkaç Scheme derleyicisi de önyüklenir. Scheme48, Tavuk Şeması, ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.