Saya mempelajari topik kompiler dan juru bahasa secara intensif. Saya ingin memeriksa apakah pemahaman dasar saya benar, jadi mari kita asumsikan yang berikut:
Saya memiliki bahasa yang disebut "Foobish" dan kata kuncinya adalah
<OUTPUT> 'TEXT', <Number_of_Repeats>;
Jadi jika saya ingin mencetak ke konsol 10 kali, saya akan menulis
OUTPUT 'Hello World', 10;
Hello World.foobish-file.
Sekarang saya menulis penerjemah dalam bahasa pilihan saya - C # dalam hal ini:
using System;
namespace FoobishInterpreter
{
internal class Program
{
private static void Main(string[] args)
{
analyseAndTokenize(Hello World.foobish-file)//Pseudocode
int repeats = Token[1];
string outputString = Token[0];
for (var i = 0; i < repeats; i++)
{
Console.WriteLine(outputString);
}
}
}
}
Pada tingkat penerjemah yang sangat mudah, penerjemah akan menganalisis file skrip, dll. Dan mengeksekusi foobish-bahasa dengan cara implementasi penerjemah.
Akankah kompiler membuat bahasa mesin yang berjalan pada perangkat keras fisik secara langsung?
Jadi seorang penerjemah tidak menghasilkan bahasa mesin, tetapi apakah kompiler melakukannya untuk inputnya?
Apakah saya memiliki kesalahpahaman dalam cara dasar bagaimana kompiler dan penerjemah bekerja?
sumber
Jawaban:
Istilah "interpreter" dan "compiler" jauh lebih kabur daripada sebelumnya. Bertahun-tahun yang lalu, lebih umum bagi kompiler untuk menghasilkan kode mesin untuk dieksekusi nanti, sementara penerjemah kurang lebih "mengeksekusi" kode sumber secara langsung. Jadi kedua istilah itu dipahami dengan baik saat itu.
Tetapi hari ini ada banyak variasi dalam penggunaan "kompiler" dan "penerjemah." Sebagai contoh, VB6 "mengkompilasi" ke kode byte (bentuk Bahasa Antara ), yang kemudian "ditafsirkan" oleh VB Runtime. Proses serupa terjadi di C #, yang menghasilkan CIL yang kemudian dieksekusi oleh Just-In-Time Compiler (JIT) yang, di masa lalu, akan dianggap sebagai interpreter. Anda dapat "membekukan-kering" output JIT ke dalam biner aktual yang dapat dieksekusi dengan menggunakan NGen.exe , produk yang akan menjadi hasil kompiler di masa lalu.
Jadi jawaban untuk pertanyaan Anda tidak semudah dulu.
Bacaan Lanjutan
Compiler vs Interpreter di Wikipedia
sumber
Ringkasan yang saya berikan di bawah ini didasarkan pada "Compiler, Prinsip, Teknik, & Peralatan", Aho, Lam, Sethi, Ullman, (Pearson International Edition, 2007), halaman 1, 2, dengan tambahan beberapa ide saya sendiri.
Dua mekanisme dasar untuk memproses suatu program adalah kompilasi dan interpretasi .
Kompilasi sebagai input program sumber dalam bahasa yang diberikan dan output program target dalam bahasa target.
Jika bahasa target adalah kode mesin, itu dapat dieksekusi langsung pada beberapa prosesor:
Kompilasi melibatkan pemindaian dan menerjemahkan seluruh program input (atau modul) dan tidak melibatkan pelaksanaannya.
Interpretasi mengambil sebagai input program sumber dan inputnya, dan menghasilkan output program sumber
Interpretasi biasanya melibatkan pemrosesan (analisis dan eksekusi) program satu per satu pernyataan.
Dalam praktiknya, banyak pengolah bahasa menggunakan campuran dari dua pendekatan. Misalnya, program Java pertama-tama diterjemahkan (dikompilasi) menjadi program perantara (kode byte):
output dari langkah ini kemudian dieksekusi (ditafsirkan) oleh mesin virtual:
Untuk memperumit hal-hal lebih jauh, JVM dapat melakukan kompilasi just-in-time pada saat runtime untuk mengkonversi kode byte ke format lain, yang kemudian dieksekusi.
Juga, bahkan ketika Anda mengkompilasi ke bahasa mesin, ada penerjemah yang menjalankan file biner Anda yang diimplementasikan oleh prosesor yang mendasarinya. Oleh karena itu, bahkan dalam kasus ini Anda menggunakan hibrida kompilasi + interpretasi.
Jadi, sistem nyata menggunakan campuran keduanya sehingga sulit untuk mengatakan apakah prosesor bahasa yang diberikan adalah kompiler atau juru bahasa, karena mungkin akan menggunakan kedua mekanisme pada berbagai tahap pemrosesan. Dalam hal ini mungkin akan lebih tepat untuk menggunakan istilah lain yang lebih netral.
Namun demikian, kompilasi dan interpretasi adalah dua jenis proses yang berbeda, seperti yang dijelaskan dalam diagram di atas,
Untuk menjawab pertanyaan awal.
Belum tentu, kompiler menerjemahkan program yang ditulis untuk mesin M1 ke program yang setara yang ditulis untuk mesin M2. Mesin target dapat diimplementasikan dalam perangkat keras atau menjadi mesin virtual. Secara konseptual tidak ada perbedaan. Poin penting adalah bahwa kompiler melihat sepotong kode dan menerjemahkannya ke bahasa lain tanpa menjalankannya.
Jika dengan memproduksi Anda merujuk ke output, maka kompiler menghasilkan program target yang mungkin dalam bahasa mesin, seorang penerjemah tidak.
sumber
defined A && !defined B
.No Sebuah compiler hanyalah sebuah program yang mengambil sebagai masukan program yang ditulis dalam bahasa A dan menghasilkan sebagai output program semantik setara dalam bahasa B . Bahasa B bisa apa saja, tidak harus bahasa mesin.
Kompiler dapat mengkompilasi dari bahasa tingkat tinggi ke bahasa tingkat tinggi lainnya (misalnya GWT, yang mengkompilasi Java ke ECMAScript), dari bahasa tingkat tinggi ke bahasa tingkat rendah (misalnya Gambit, yang menyusun Skema ke C), dari bahasa tingkat tinggi ke kode mesin (misalnya GCJ, yang mengkompilasi Jawa ke kode asli), dari bahasa tingkat rendah ke bahasa tingkat tinggi (misalnya Clue, yang mengkompilasi C ke Java, Lua, Perl, ECMAScript dan Umum Lisp), dari bahasa tingkat rendah ke bahasa tingkat rendah lainnya (misalnya Android SDK, yang mengkompilasi kode byte JVML ke kode byte Dalvik), dari bahasa tingkat rendah ke kode mesin (mis. Kompiler C1X yang merupakan bagian dari HotSpot, yang mengkompilasi bytecode JVML ke kode mesin), kode mesin ke bahasa tingkat tinggi (apa pun yang disebut "dekompiler", juga Emscripten, yang mengkompilasi kode mesin LLVM ke ECMAScript),kode mesin ke bahasa tingkat rendah (misalnya kompiler JIT dalam JPC, yang mengkompilasi kode asli x86 ke bytecode JVML) dan kode asli ke kode asli (mis. kompiler JIT di PearPC, yang mengkompilasi kode asli PowerPC ke kode asli x86).
Perhatikan juga bahwa "kode mesin" adalah istilah yang benar-benar kabur karena beberapa alasan. Misalnya, ada CPU yang secara asli mengeksekusi kode byte JVM, dan ada penerjemah perangkat lunak untuk kode mesin x86. Jadi, apa yang membuat satu "kode mesin asli" tetapi tidak yang lain? Juga, setiap bahasa adalah kode untuk mesin abstrak untuk bahasa itu.
Ada banyak nama khusus untuk kompiler yang menjalankan fungsi khusus. Terlepas dari kenyataan bahwa ini adalah nama khusus, semua ini masih kompiler, hanya jenis kompiler khusus:
Belum tentu. Itu bisa dijalankan dalam juru bahasa atau dalam VM. Itu bisa dikompilasi lebih lanjut ke bahasa yang berbeda.
Seorang juru bahasa tidak menghasilkan apa-apa. Itu hanya menjalankan program.
Kompiler menghasilkan sesuatu, tetapi tidak harus berupa bahasa mesin, bisa berupa bahasa apa pun. Bahkan bisa bahasa yang sama dengan bahasa input! Sebagai contoh, Supercompiler, LLC memiliki kompiler yang mengambil Java sebagai inputnya dan menghasilkan Java yang dioptimalkan sebagai outputnya. Ada banyak kompiler ECMAScript yang mengambil ECMAScript sebagai input dan menghasilkan ECMAScript yang dioptimalkan, diperkecil, dan dikaburkan sebagai outputnya.
Anda mungkin juga tertarik dengan:
sumber
Saya pikir Anda harus membuang gagasan "kompiler versus juru bahasa" sepenuhnya, karena ini merupakan dikotomi yang salah.
Kata kolektif untuk membuat bahasa pemrograman abstrak bermanfaat di dunia nyata adalah implementasi .
Di masa lalu, implementasi bahasa pemrograman sering terdiri dari hanya sebuah kompiler (dan CPU yang dihasilkannya kode) atau hanya seorang juru bahasa - sehingga mungkin tampak seperti dua jenis alat yang saling eksklusif. Hari ini, Anda dapat dengan jelas melihat bahwa ini bukan masalahnya (dan itu tidak pernah dimulai dengan). Mengambil implementasi bahasa pemrograman yang canggih, dan berusaha untuk mendorong nama "kompiler" atau "juru bahasa" untuk itu, sering kali akan membawa Anda ke hasil yang tidak meyakinkan atau tidak konsisten.
Implementasi bahasa pemrograman tunggal dapat melibatkan sejumlah kompiler dan juru bahasa , seringkali dalam berbagai bentuk (standalone, on-the-fly), sejumlah alat lainnya, seperti analisa statis dan pengoptimal , dan sejumlah langkah. Bahkan dapat mencakup seluruh implementasi dari sejumlah bahasa perantara (yang mungkin tidak terkait dengan yang sedang diterapkan).
Contoh skema implementasi meliputi:
...dan seterusnya.
sumber
Sementara garis antara kompiler dan interpreter menjadi kabur dari waktu ke waktu, orang masih dapat menarik garis di antara mereka dengan melihat semantik dari apa yang harus dilakukan oleh program dan apa yang dilakukan oleh kompiler / juru bahasa.
Kompiler akan menghasilkan program lain (biasanya dalam bahasa tingkat rendah seperti kode mesin) yang, jika program itu dijalankan, akan melakukan apa yang seharusnya dilakukan oleh program Anda.
Seorang juru bahasa akan melakukan apa yang seharusnya dilakukan oleh program Anda.
Dengan definisi ini, tempat-tempat di mana fuzzy menjadi kasus di mana kompiler / juru bahasa Anda dapat dianggap melakukan hal-hal yang berbeda tergantung pada bagaimana Anda melihatnya. Misalnya, Python mengambil kode Python Anda dan mengkompilasinya menjadi bytecode Python yang dikompilasi. Jika bytecode Python ini dijalankan melalui penerjemah bytecode Python , ia melakukan apa yang seharusnya dilakukan oleh program Anda. Namun, dalam sebagian besar situasi, pengembang Python menganggap kedua langkah tersebut dilakukan dalam satu langkah besar, sehingga mereka memilih untuk menganggap juru bahasa CPython sebagai mengartikan kode sumber mereka, dan fakta bahwa itu dikompilasi sepanjang jalan dianggap sebagai detail implementasi . Dengan cara ini, itu semua masalah perspektif.
sumber
Berikut adalah disambiguasi konseptual sederhana antara kompiler dan penerjemah.
Pertimbangkan 3 bahasa: bahasa pemrograman , P (ditulis dalam program apa); bahasa domain , D (untuk apa yang terjadi dengan program yang sedang berjalan); dan bahasa target , T (beberapa bahasa ketiga).
Secara konseptual,
sebuah compiler menerjemahkan P ke T sehingga Anda dapat mengevaluasi T (D); sedangkan
seorang juru bahasa mengevaluasi P (D) secara langsung.
sumber