Mengapa C ++ menulis compiler?


15

Saya bertanya-tanya mengapa C ++ adalah pilihan yang baik untuk menulis kompiler. Tentu saja C juga baik untuk tujuan ini, karena banyak kompiler ditulis dalam C atau C ++ tetapi saya lebih tertarik pada C ++ kali ini. Ada alasan bagus? Saya mencari itu di Internet, tetapi saya tidak dapat menemukan alasan yang bagus.


3
"Banyak kompiler ditulis [...] dalam C ++" - ada referensi? Yang mana Apa yang membuat Anda berpikir C ++ lebih sering digunakan untuk konstruksi kompiler daripada bahasa populer lainnya?
Doc Brown

4
@DocBrown Yah, Dentang dan MSVC sebagian besar ditulis dalam C ++, gcc memiliki sedikit C ++ di dalamnya sekarang, Java JVM ditulis dalam C ++ stackoverflow.com/questions/410320/what-is-java-written-in dan juga superuser. com / pertanyaan / 136136 / ...
Klaim

@DocBrown DMD kompiler referensi untuk D ditulis dalam C ++
ratchet freak

3
Siapa bilang itu pilihan yang bagus ??
Phil

1
@ Phil Apakah Anda pikir mereka membuat pilihan ini tanpa mempertimbangkan alternatif? Ini bukan pilihan "baik", itu pilihan "efisien".
Klaim

Jawaban:


21

C ++ memiliki dua sisi untuk itu. Ini memiliki sisi pengembangan tingkat rendah yang membuatnya tampak seperti bahasa alami untuk melakukan hal tingkat rendah seperti pembuatan kode. Ia juga memiliki sisi tingkat tinggi (yang C tidak) yang memungkinkan Anda menyusun aplikasi yang kompleks (seperti kompiler) dengan cara yang logis, berorientasi objek, sambil tetap mempertahankan kinerja. Karena memiliki aspek level rendah dan tinggi, itu adalah pilihan yang baik untuk aplikasi besar yang membutuhkan fitur atau kinerja level rendah.


9
Sejauh yang saya tahu banyak dari logika di dalam kompiler adalah sifat fungsional (mengubah struktur data yang kompleks menjadi struktur data lainnya) jadi saya tidak yakin apakah fasilitas berorientasi objek (yang lebih ditargetkan untuk pemrograman-in-the-large) , aspek arsitektural) membawa keuntungan nyata pada penyusunan konstruksi dengan gaya pemrograman prosedural. Hanya 2 sen saya.
Giorgio

5
@Giorgio Memiliki objek membantu dalam banyak aspek penulisan kompiler lainnya. Sebagai contoh, ada banyak kondisi yang harus ditangani oleh kompiler ketika mengoptimalkan dan hal-hal semacam itu cocok untuk OOP. Selain itu, pemrograman OOP dan Fungsional bisa sangat gratis, jadi hanya karena sebagian besar algoritmanya fungsional, tidak berarti objek tidak akan membantu.
Oleksi

3
@Iorgio dan Oleksi: Saya bisa mengkonfirmasi Anda berdua. Saya menulis kompiler dengan Haskell untuk bahasa dunia nyata. Itu sangat cocok. Tetapi kadang-kadang saya melewatkan beberapa OO di sekitar. Jika saya harus menulis kompiler lain saya pasti akan memilih Haskell, tetapi ini benar-benar kasus khusus. Saya tidak akan memilih Haskell tanpa ragu untuk jenis proyek lainnya.
scarfridge

23
Mengapa Anda perlu memiliki bahasa dengan "sisi level rendah" untuk melakukan pembuatan kode? Saya tidak bisa melihat bagaimana keduanya terhubung dengan cara apa pun.
phant0m

5
Anda tidak memerlukan "sisi level rendah" untuk melakukan pembuatan kode lebih dari yang Anda butuhkan pengidentifikasi Unicode untuk dapat menulis teks Jepang ke file.
dan04

11

Pengalaman saya tidak setuju dengan premis Anda di sini. Bahkan, untuk bahasa tujuan umum tingkat tinggi, itu adalah praktik yang sangat umum untuk menulis kompiler dalam bahasa yang sama dengan bahasa sumber (bahasa yang dikompilasi). Sebagai contoh:

  • Kompiler Java Sun ditulis dalam Java
  • Kompilator Scala ditulis dalam Scala
  • Kompiler C # Mono ditulis dalam C #
  • Kompiler Smalltalk Squick ditulis dalam Smalltalk
  • ... dan masih banyak lagi

Pengecualian adalah compiler front-ujung yang ditulis untuk kerangka kerja kompiler yang ada, seperti GCC, LLVM atau Polyglot, yang kemudian ditulis dalam bahasa kerangka kerja, atau kompiler yang mengandalkan generator parser yang ada seperti Yacc. Karena GCC, LLVM dan Yacc adalah alat yang umum dan mapan yang ditulis dalam C dan C ++, itu memberikan insentif kepada penulis kompiler untuk menggunakannya, yang mungkin menyebabkan C dan C ++ mendapatkan bagian besar dalam distribusi bahasa implementasi kompiler.


2
Saya pikir itu lebih banyak berkaitan dengan orang-orang yang menulis kompiler dengan baik dan sangat menyukai bahasa yang mereka tulis sebagai kompiler daripada karena alasan teknis yang objektif.
Thomas Bonini

1
@ Krelp Saya setuju ini bukan tentang alasan teknis obyektif, tapi itu tidak benar-benar "suka", baik - itu hanya dianggap sebagai ritus peralihan untuk suatu bahasa - "apakah cukup matang untuk dapat berfungsi sebagai bahasa implementasi sendiri penyusun".
Oak

1
Kompiler Java Sun ditulis dalam C ++: stackoverflow.com/questions/410320/what-is-java-written-in
Klaim

10
@Klaim Anda membingungkan dua produk di sini. Salah satunya adalah kompiler Java Sun ( javaccommand-line), yang mengkompilasi Java ke Java Bytecode. Ini ditulis dalam Java - Saya telah memodifikasinya sendiri berkali-kali dan Anda dapat menelusuri sumber Java secara online . Yang lainnya adalah kompiler just-in-time yang tertanam dalam Hotspot JVM, yang mengkompilasi Java Bytecode ke kode mesin asli. Seperti kebanyakan JVM yang ditulis dalam C ++, tetapi ini bukan kompiler Java - pada kenyataannya, ia tidak tahu apa-apa tentang bahasa Java.
Oak

@ Oke, benar sekali! Dengan kata lain, JVM! = Javac
Paul Draper

5

Untuk mengkompilasi apa untuk apa? Kompiler mengubah kode sumber dari satu bahasa ( bahasa sumber) ke bahasa lain (bahasa tujuan), yang tidak menunjukkan apa pun tentang tingkat rendah bahasa tujuan.

  • CoffeeScript mengkompilasi ke JavaScript, kompiler sedang ditulis dalam CoffeeScript.
  • Script # mengkompilasi C # ke dalam JavaScript, kompiler yang ditulis, jika saya ingat dengan baik, C #.
  • dll.

Bahasa yang Anda pilih untuk menulis kompiler tergantung pada konteksnya. Sebagai contoh, bekerja pada proyek yang mengkompilasi bahasa yang berasal dari PHP ke kode PHP asli, saya menggunakan campuran PHP dan C # untuk menulis kompiler, karena itu paling masuk akal bagi saya mengingat keterampilan saya. Orang lain akan memilih Python, atau Java dan PHP, atau C ++ dengan sedikit JavaScript, atau apa pun.

C atau C ++ adalah pilihan populer karena dukungan alat terkait kompiler (lihat jawaban oleh Telastyn), dan karena kedua bahasa tersebut memungkinkan Anda untuk benar-benar asli. Namun tidak ada salahnya memilih bahasa lain.

Perhatikan bahwa agar lebih culun , Anda dapat memilih bahasa sumber untuk menulis kompiler itu sendiri. Itulah yang terjadi pada kompiler CoffeeScript dan banyak kompiler lainnya. Ini juga populer dengan IDE: salah satu Visual Studio pertama dibangun menggunakan Visual Studio yang sama.


4
Hosting sendiri bukan geeky, itu adalah properti penting untuk porting kompiler.

4
Alasannya adalah bahwa itu segera memungkinkan kompiler itu sendiri menjadi program pengujian. Kemungkinan besar juga akan menjadi program terbesar untuk kompiler itu untuk sementara waktu.

5

Saya cenderung mempertanyakan premis dasar di sini. Sementara C dan C ++ berfungsi dengan baik untuk menulis kompiler, beberapa bahasa lain tampaknya bekerja dengan baik untuk tugas tersebut.

Sedikit tergantung pada bahasa yang Anda kompilasi. Untuk bahasa yang kecil dan sederhana, C dan Pascal bekerja dengan cukup baik. Jika Anda akan mengkompilasi sesuatu yang besar dan kompleks, kompiler Anda akan menjadi besar dan kompleks juga - dalam hal ini, fitur tambahan C ++ untuk mengatur dan bekerja dengan program yang lebih besar jelas berguna. Itu tidak benar-benar sangat spesifik untuk kompilasi, hanya fitur yang berguna untuk program yang lebih besar secara umum.

Saya pikir itu juga layak disebutkan satu poin lainnya. Pemula (tampaknya) menganggap kompiler kebanyakan melakukan manipulasi teks, sehingga mereka berpikir sesuatu seperti Perl akan sangat membantu dalam menulis kompiler. Pada kenyataannya, sebagian besar bagian kompilasi yang menarik tidak benar-benar dimulai sampai setelah Anda membangun AST Anda. Sementara saya yakin Perl dapat melakukan pekerjaan dengan sangat baik, kemampuan manipulasi teksnya tidak benar-benar memberikan keuntungan besar juga (manipulasi teks sebagian besar di lexer, dan generator lexer untuk hal-hal seperti C semua dukungan RE tetap).


2
AST = Pohon Sintaksis Abstrak, RE = Ekspresi Reguler
chaotic3quilibrium

5

Kompiler dapat diimplementasikan dalam bahasa modern apa pun. Namun, salah satu persyaratan paling penting dari sebuah kompiler adalah harus cepat.

C ++ memiliki keunggulan yang jelas di sini. Optimasi dalam C ++ tidak murah. Namun, karena sifat tingkat rendah dari bahasa ini, dimungkinkan untuk mengoptimalkan kode C ++ secara manual lebih dari bahasa lain (kecuali Majelis yang tidak portabel).


9
Persyaratan penting lainnya adalah agar kode yang dihasilkan benar - Saya lebih suka memiliki kompiler lambat yang bisa saya percayai daripada yang cepat yang menghasilkan kode yang salah.

1
Meskipun sangat mungkin untuk mengoptimalkan C ++ dengan sangat berat, ada banyak kode yang agak ... well ... kurang dari optimal C ++ di luar sana.
Donal Fellows

2
@DonalFellows Balikkan sebaliknya: dimungkinkan untuk menulis kode yang kurang optimal dalam bahasa apa pun, tetapi ada optimisasi yang tidak mungkin untuk diaktifkan dalam bahasa lain selain C ++ (selain Assembler. Saya tidak menyertakan C karena kurangnya struktur tingkat tinggi yang memungkinkan penyisipan yang lebih kuat).
Klaim

2

Saya menduga bahwa motivator utama untuk penggunaannya adalah keluaran Lex / Yacc / Bison (terutama) dalam C. Karena itu sudah menjadi standar sejak lama, ia memiliki momentum.

Bukannya itu alasan yang sangat bagus ...


Sebenarnya itu tidak memuaskan saya, tapi terima kasih sudah mencoba.
Kobra

Itu tidak menjawab pertanyaan "mengapa memilih C ++ over C untuk konstruksi compiler".
Doc Brown

2
Itu bukan alasan yang baik sama sekali. Alat analog dengan Lex dan Yacc ada untuk banyak platform. PLY dan ANTLR, misalnya.
user16764

Selain itu, kompiler dunia nyata paling populer (saya cukup yakin abuot Clang dan GCC, misalnya) menggunakan parser tulisan tangan.

@ Darnan: Ya tapi mereka mungkin mulai menggunakan yang dibuat untuk mendapatkan sesuatu dari tanah. Pembuatan tangan parser adalah langkah pengoptimalan yang tidak benar-benar ingin Anda lakukan sampai Anda dapat membuktikan hal-hal lain berfungsi.
Martin York
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.