Neden C ++ derleyici yazmak için?


14

Neden C ++ bir derleyici yazmak için iyi bir seçim olduğunu merak ediyordum. Tabii ki C bu amaç için de iyidir, çünkü birçok derleyici C veya C ++ ile yazılmıştır, ancak bu sefer C ++ ile daha fazla ilgileniyorum. Bunun iyi bir nedeni var mı? Bunu internette arıyordum, ancak iyi bir neden bulamıyorum.


3
"Birçok derleyici C ++ ile yazılmış [...]" - herhangi bir referans? Hangileri? C ++ 'nın derleyici yapımında diğer popüler dillerden daha sık kullanıldığını düşündüren nedir?
Doc Brown

6
@DocBrown Eh, Clang ve MSVC çoğunlukla C ++ ile yazılmıştır, gcc şimdi biraz C ++ 'a sahiptir, Java JVM C ++ ile yazılmıştır stackoverflow.com/questions/410320/what-is-java-written-in ve ayrıca süper kullanıcı. com / sorular / 136136 /…
Klaim

@DBBrown DMD D için referans derleyici C ++ ile yazılmıştır
cırcır ucube

3
Kim bunun iyi bir seçim olduğunu söylüyor?
Phil

1
@Phil Sizce bu seçeneği alternatif düşünmeden yaptılar mı? "İyi" bir seçim değil, "verimli" bir seçim.
Klaim

Yanıtlar:


24

C ++ 'ın iki tarafı vardır. Düşük seviyeli bir geliştirme tarafına sahiptir, bu da kod üretimi gibi düşük seviyeli bir şey yapmak için doğal bir dil gibi görünmesini sağlar. Ayrıca, performansı korurken, karmaşık bir uygulamayı (derleyici gibi) mantıksal, nesne yönelimli bir şekilde yapılandırmanıza izin veren yüksek düzeyli bir tarafa (C'nin sahip olmadığı) sahiptir. Hem düşük hem de yüksek seviye yönleri olduğundan, düşük düzey özellikler veya performans gerektiren büyük uygulamalar için iyi bir seçimdir.


11
Bildiğim kadarıyla bir derleyicinin içindeki mantığın birçoğu işlevsel niteliktedir (karmaşık veri yapılarını diğer veri yapılarına dönüştürür), bu yüzden nesne yönelimli tesislerin (daha geniş çapta programlamaya daha fazla hedeflenip hedeflenmediğinden emin değilim) , mimari yönleri) yordamsal bir programlama stiline göre derleyici yapımına gerçek bir avantaj sağlar. Sadece 2 sentim.
Giorgio

5
@Giorgio Nesnelere sahip olmak, derleyici yazmanın diğer birçok yönüne yardımcı olur. Örneğin, bir derleyicinin optimizasyon sırasında uğraşması gereken birçok durum vardır ve bu tür şeyler OOP'ye iyi bir şekilde katkıda bulunur. Ayrıca, OOP ve Fonksiyonel programlama oldukça ücretsiz olabilir, bu nedenle algoritmalar çoğunlukla işlevsel olabileceği için nesnelerin yardımcı olmayacağı anlamına gelmez.
Oleksi

3
@ Giorgio ve Oleksi: İkinizi de teyit edebilirim. Haskell ile gerçek bir dünya dili için bir derleyici yazdım. Gerçekten iyi bir uyum vardı. Ama bazen etrafta biraz OO kaçırdım. Başka bir derleyici yazmak zorunda kalsaydım kesinlikle Haskell'i seçerdim, ama bu gerçekten özel bir durum. Diğer projeler için çekinmeden Haskell'i tercih etmem.
scarridge

27
Kod üretimi için neden "düşük seviye tarafı" olan bir dile sahip olmanız gerekiyor? Bu ikisinin hiçbir şekilde nasıl bağlandığını göremiyorum.
phant0m

5
Kod oluşturma için bir dosyaya Japonca metin yazabilmek için Unicode tanımlayıcılarına ihtiyaç duyduğunuzdan daha fazla "düşük düzeyli tarafa" ihtiyacınız yoktur .
dan04

17

Deneyimim, buradaki öncülünüzle aynı fikirde değil. Aslında, üst düzey genel amaçlı diller için, derleyiciyi kaynak dil ile aynı dilde (derlenen dil) yazmak çok yaygın bir uygulamadır . Örneğin:

  • Sun'ın Java derleyicisi Java ile yazılmıştır
  • Scala derleyicisi Scala'da yazılmıştır
  • Mono'nun C # derleyicisi C # ile yazılmış
  • Squick'in Smalltalk derleyicisi Smalltalk ile yazılmıştır
  • ... ve daha fazlası

Bunun bir istisnası, daha sonra çerçevenin dilinde yazılan GCC, LLVM veya Polyglot gibi mevcut derleyici çerçeveleri için yazılan derleyici ön uçları veya Yacc gibi mevcut ayrıştırıcı jeneratörlerine dayanan derleyicilerdir. GCC, LLVM ve Yacc, C ve C ++ ile yazılmış yaygın, yerleşik araçlar olduğundan, derleyici yazarlarının bunları kullanması için bir teşvik verir, bu da C ve C ++ 'nın derleyici uygulama dili dağıtımında büyük bir pay almasına neden olabilir.


2
Bunun, derleyiciyi iyi tanıyan ve derleyici yazdıkları dili objektif teknik nedenlerden daha çok beğenen insanlarla ilgisi olduğunu düşünüyorum.
Thomas Bonini

1
@Krelp Bunun objektif bir teknik sebeple ilgili olmadığına katılıyorum, ama gerçekten "beğenme" de değil - sadece bir dil için bir parça ayin olarak kabul ediliyor - "kendi uygulama dili olarak hizmet edebilecek kadar olgun mu? derleyici".
Meşe

1
Sun'ın Java derleyicisi C ++ ile yazılmıştır: stackoverflow.com/questions/410320/what-is-java-written-in
Klaim

12
@ Burada iki ürünü karıştırıyorsunuz. Bunlardan biri, javacJava'yı Java Bytecode'a derleyen Sun'ın Java derleyicisidir ( komut satırı). Java ile yazılmıştır - kendim birçok kez değiştirdim ve Java kaynaklarına çevrimiçi göz atabilirsiniz . Diğeri, Java Bytecode'u yerel makine koduyla derleyen Hotspot JVM'ye gömülü tam zamanında derleyicidir . JVM'nin çoğu gibi C ++ ile yazılmış, ancak bir Java derleyicisi değil - aslında, Java dili hakkında hiçbir şey bilmiyor.
Meşe

@ Tamam, kesinlikle doğru! Başka bir deyişle, JVM! = Javac
Paul Draper

6

Neyi neye derlemek için? Derleyici kaynak kodu bir dilden (kaynak dil) diğerine (hedef dil) dönüştürür, bu da hedef dilin düşük seviyeliğiyle ilgili hiçbir şey göstermez.

  • CoffeeScript , JavaScript'e derler, derleyici CoffeeScript'te yazılır.
  • Komut dosyası # C # 'ı JavaScript olarak derler, derleyici yazılır, eğer iyi hatırlıyorsam C #.
  • vb.

Derleyici yazmak için seçtiğiniz dil bağlama bağlıdır. Örneğin, PHP'den türetilmiş bir dili yerel bir PHP koduna derleyen bir proje üzerinde çalışırken, derleyiciyi yazmak için PHP ve C # karışımını kullandım, çünkü becerilerim bana en mantıklı geldi. Başka bir kişi Python, Java ve PHP veya biraz da JavaScript ile C ++ seçebilir.

C veya C ++, derleyici ile ilgili araçların desteği nedeniyle popüler bir seçimdir (Telastyn'in cevabına bakın) ve bu iki dil gerçekten yerel olmanıza izin verdiğinden. Ama başka bir dil seçerken yanlış bir şey yok.

Daha geeky olmak için, derleyicinin kendisini yazmak için kaynak dili seçebileceğinizi unutmayın. CoffeeScript derleyicisi ve diğer birçok derleyici için olan buydu. IDE'ler arasında da popülerdir: ilk Visual Studio'lardan biri aynı Visual Studio kullanılarak oluşturulmuştur.


5
Kendini barındırma geeky değil, bir derleyici taşımak için önemli bir özelliktir.

5
Bunun nedeni derleyicinin derhal bir test programı olmasını sağlar. Büyük olasılıkla bir süre için bu derleyici için en büyük program olacaktır.

6

Burada temel önermeyi sorgulamaya meyilliyim. C ve C ++ derleyiciler yazmak için mükemmel çalışıyorken, diğer birkaç dil de görev için mükemmel çalışıyor.

Biraz derlediğiniz dile bağlıdır. Küçük, basit diller için C ve Pascal oldukça iyi çalışır. Büyük ve karmaşık bir şey derleyecekseniz, derleyiciniz de büyük ve karmaşık hale gelir - bu durumda, C ++ 'ın daha büyük programları düzenlemek ve çalışmak için ekstra özellikleri kullanışlı olur. Bu derlemeye gerçekten çok özgü değil, sadece daha büyük programlar için yararlı özellikler.

Bence başka bir noktaya değinmeye değer. Yeni başlayanlar (derler) derleyicileri çoğunlukla metin manipülasyonu olarak görürler, bu yüzden Perl gibi bir şey derleyicilerin yazılmasında büyük bir yardımcı olacağını düşünürler. Gerçekte, derlemenin ilginç kısımlarının çoğu AST'nizi inşa edene kadar gerçekten başlamıyor. Perl'in işi mükemmel bir şekilde yapabileceğinden emin olsam da, metin manipülasyon yeteneği gerçekten de büyük bir avantaj sağlamaz (metin manipülasyonu çoğunlukla lexer'de ve C gibi şeyler için lexer jeneratörleri zaten RE'leri destekliyor).


2
AST = Soyut Sözdizimi Ağacı, RE = Düzenli İfadeler
kaotik3quilibrium

5

Derleyiciler herhangi bir modern dilde uygulanabilir. Ancak, bir derleyicinin en önemli gereksinimlerinden biri hızlı olmaktır.

C ++ burada açık bir avantaja sahiptir. C ++ 'ta optimizasyon ucuz değildir. Bununla birlikte, bu dilin düşük düzeyli yapısı nedeniyle, C ++ kodunu diğer dillerden daha fazla manuel olarak optimize etmek mümkündür (taşınabilir olmayan Montaj hariç).


11
Üretilen kodun doğru olması için bir başka önemli gereksinim - Ben yanlış kod üreten hızlı bir daha güvenebileceğiniz yavaş bir derleyici olurdu.

2
C ++ 'ı çok yoğun bir şekilde optimize etmek kesinlikle mümkün olsa da, çok daha iyi… orada… optimal C ++ kodundan daha az.
Donal Fellows

2
@DonalFellows Ters çevirin: herhangi bir dilde en uygun koddan daha az yazmak mümkündür, ancak C ++ (Assembler dışında) dışında başka dillerde etkinleştirilmesi mümkün olmayan optimizasyonlar vardır. daha güçlü inlining sağlayan yüksek seviyeli yapıların).
Klaim

user1249 - C ++ kodunun hızının herhangi bir cevher arabası yapmasının bir nedeni yoktur. Yavaş, doğru bir derleyiciden daha hızlı, doğru bir derleyiciye sahip olmayı tercih ederim.
gnasher729

3

Kullanımları için asıl motivasyonun Lex / Yacc / Bison çıktısının (öncelikle) C'de olduğundan şüpheleniyorum. Bu çok uzun süredir standart olduğu için ivme var.

Bunlar özellikle iyi nedenler değil ...


Aslında beni tatmin etmiyor, ama denediğiniz için teşekkürler.
Kobra

Bu "derleyici yapımı için neden C + + üzerinde C + + seçmelisiniz" sorusuna cevap vermez.
Doc Brown

3
Hiç de iyi bir sebep değil. Lex ve Yacc'a benzer araçlar birçok platform için mevcuttur. Mesela PLY ve ANTLR.
user16764

Dahası, en popüler gerçek dünya derleyicileri (örneğin, Clang ve GCC'den oldukça eminim) elle yazılmış ayrıştırıcılar kullanır.

@delnan: Evet ama muhtemelen işleri yoldan çıkarmak için üretilmiş birini kullanmaya başladılar. Ayrıştırıcının el üretimi, başka şeylerin çalıştığını kanıtlayana kadar gerçekten yapmak istemediğiniz bir optimizasyon adımıdır.
Martin York

1

Bu konuda deneyimim var. C ve C ++ 'da derleyiciler yazdım. C ve C ++ arasındaki temel fark, C'nin otomatik olarak dinamik bellek yönetimine sahip olmamasıdır. C'deki tüm bellek yönetimi açıkça yapılmalıdır. Bir derleyici yazmak, dize işleme ve dizi yönetimi ile çok ilgilidir. C'de, bildirdiğiniz her dizenin ve her dizinin boyutunu düşünmeye ve bu nesnelere eriştiğinizde dizinleri kontrol etmeye zorlanırsınız (kodunuzun güvenli ve kararlı olmasını istiyorsanız). C'de elbette dinamik bellek yönetimine sahip olabilirsiniz, ancak hiçbir şey otomatik değildir. Malloc () ve free () kullanarak açık bir şekilde bellek ayırmanız ve serbest bırakmanız, sınırların dışına erişmediğinizden emin olmak için dinamik nesnelerinizin boyutunu ayrı değişkenlerde tutmanız gerekir.

C ++ 'da aynı mekanizmalara sahip olabilirsiniz, ancak tüm bellek yönetiminiz açıkça çağırmanız gerekmeyen yapıcılar ve yıkıcılar içinde kapsüllenebildiğinden, gerçekten geliştirme zamanından etkilidir. Böylece derleyici kaynakları sizin için ayırıyor ve serbest bırakıyor. Kendi sınıflarınızı oluşturursanız dinamik nesnelerinizin boyutu da kapsüllenebilir ve aşırı yük operatörü [] ile dizin erişimi sınır erişimi açısından kontrol edilebilir. Bu soyutlamalar, kodunuzu daha temiz, daha kolay anlaşılır ve hata ayıklamaya yardımcı olur ve kesinlikle daha hızlı geliştirilmesini sağlar.

C'de bir derleyici oluşturursanız, emin olmanız daha uzun sürecektir. C ++ projenizi daha kısa sürede bitirmenizi sağlayacaktır. C ve C ++ aynı performansa sahiptir, ancak C ++, C'nin sahip olmadığı birçok avantaja sahiptir.


0

CompCert projesi bir araştırma C ++ C veya C yazılı değil derleyici, ama daha ocaml ve Coq içindedir.

C ++ 'ın C'ye çevrildiğini gözlemleyin ( Cfront'ta ). Şimdi Gimple için GCC ön ucunu kullanabilir , sonra Gimple'ı bir veritabanına dökebilir, ardından montajcı çevirmeninize bir Gimple yazabilirsiniz. Ancak yasal nedenler ( GCC çalışma zamanı kitaplığı istisnası ) böyle bir derleyicinin açık kaynak olmasını gerektirir. Avukatınızdan bilgi isteyin, ben bir avukat değilim. GCC'nin eski varyantları, C ++ 'nın bazı varyantları için bir ön uç ile C (+ alana birkaç farklı dilde) yazılmıştır. OpenWatcom C ile yazılmış bir C ++ derleyicisi olabilir (bunu kontrol etmenizi istiyorum).

Compcert'in kaynağı akademik ve araştırma amacıyla serbestçe kullanılabilir. Endüstriyel (ve yasal olarak) kullanmak istiyorsanız, Absint'ten bir lisans almanız gerekir.

Ayrıca bakınız bu ve bu iki ilgili soruların yanıtlarını.

2020'de sıfırdan bir C (veya C ++) derleyicisi yazmakla görevlendirildiysem (Linux'ta çalışıyor, belki bazı çapraz derleyiciler ) Muhtemelen C ++ 'da yazmayacağım. Ocaml , Go veya Rust kullanarak yazmayı düşünürdüm . İzin verilirse Frama-C'ye dayandırabilirim . C veya C ++ ile kodlamak gerekirse, öncelikle bunun için bir çöp toplayıcı kütüphanesi kodlar , muhtemelen bazı kalıcılık katmanı - tüm program optimizasyonu için çok yararlı - ve sonra bir metaprogramlama yaklaşımı (C veya C ++ kodunun çoğunu üreterek) düşünürdüm derleme araçlarımla, belki Bismon veya RefPerSys izin veriliyorsa).

Common Lisp veya Python'da (örn. ShivyC veya nqcc ) kodlanmış bazı (daha fazla veya daha az açık kaynaklı) C derleyicilerini bulabilirsiniz . ZetaC'a da bakınız .

GCC'nin son sürümlerinin teknik olarak saf C ++ ile kodlanmadığına dikkat edin, GCC'ye dahil olan bir düzine alana özel dil (birçoğu Turing-complete ). Ayrıca bkz. Eski GCC KİTİM . projem.

GCC'nin gelecekteki sürümlerinde, bazı Python veya Guile yorumlayıcılarının içine gömüleceği (örneğin, GCC'nin geçiş yöneticisinin yerine geçmesi) .

İçine de bak Milepost GCC projesi.

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.