Mengapa tidak ada penerjemah otomatis dari satu bahasa pemrograman ke yang lain? [Tutup]

37

Sebagian besar bahasa pemrograman Turing selesai, yang berarti bahwa tugas apa pun yang dapat diselesaikan dalam satu bahasa dapat diselesaikan dalam bahasa lain, atau bahkan pada mesin Turing. Lalu mengapa tidak ada penerjemah otomatis yang dapat mengonversi program dari bahasa apa pun ke bahasa lain? Saya telah melihat beberapa upaya untuk dua bahasa, tetapi mereka selalu bekerja hanya pada bagian bahasa yang terbatas dan hampir tidak dapat digunakan untuk mengonversi proyek nyata.

Apakah mungkin, setidaknya secara teori, untuk menulis 100% penerjemah yang benar di antara semua bahasa? Apa tantangan dalam praktik? Apakah ada penerjemah yang sudah ada yang berfungsi?

serg
sumber
5
Ingat, “semua bahasa” termasuk yang bodoh seperti Oook! (Turing kelengkapan bukanlah keseluruhan cerita; Anda perlu syscall juga dalam praktek.)
Donal Fellows
Ada beberapa. Penerjemah C to Pascal dan Pascal to C cukup umum pada satu titik. Seperti yang disarankan oleh jawaban di bawah ini, output biasanya tidak dapat dibaca tanpa setidaknya beberapa manual merapikan. Dan ini adalah bahasa yang relatif sederhana dengan perpustakaan yang relatif sederhana - melakukan pekerjaan dengan baik untuk misalnya C ++ ke Haskell atau sebaliknya mungkin akan mustahil.
Steve314
Lihat Roslyn the .net compiler sebagai layanan yang memiliki kemampuan untuk menerjemahkan C # ke VB dan sebaliknya.
Daniel Little
2
Semua kompiler menerjemahkan satu PL ke PL lainnya, mereka tidak menjamin bahwa kode dalam PL target mudah dibaca
jk.
Setelah melihat keakuratan terjemahan Google, saya yakin bahwa saya akan melihat penerjemah universal dalam hidup saya. Ya itu akan menjadi upaya yang menantang dan mungkin memerlukan upaya besar seperti dalam kasus analisis basis kode besar seperti github atau stackoverflow, tetapi ini akan terjadi dan permintaan untuk alat seperti itu juga akan meningkat di masa mendatang, sekarang terutama bahwa ada sejumlah programmer untuk mempelajari AI dan ML. Mungkin tidak ada satu orang yang mengembangkan alat seperti itu sendirian. Namun seseorang mungkin mengembangkan bot untuk mengembangkan bot untuk mengatasi masalah ini.
Ganesh Kamath - 'Code Frenzy'

Jawaban:

32

Masalah terbesar bukanlah terjemahan kode program yang sebenarnya, tetapi porting platform API.

Pertimbangkan penerjemah PHP ke Java. Satu-satunya cara yang layak untuk melakukan itu tanpa menanamkan bagian dari biner PHP adalah dengan mengimplementasikan kembali semua modul PHP dan API di Jawa. Ini melibatkan penerapan lebih dari 10.000 fungsi. Dibandingkan dengan itu pekerjaan menerjemahkan sintaksis semudah pie. Dan bahkan setelah semua pekerjaan itu Anda tidak akan memiliki kode Java, Anda akan memiliki semacam keburukan yang terjadi untuk berjalan pada platform Java, tapi itu terstruktur seperti PHP di dalam.

Inilah sebabnya mengapa satu-satunya alat yang muncul dalam pikiran adalah semua tentang menerjemahkan kode untuk menyebarkannya, bukan untuk mempertahankannya setelah itu. GWT Google "mengkompilasi" Java ke JavaScript. Hiphop Facebook mengkompilasi PHP menjadi C.

Joeri Sebrechts
sumber
Wikipedia juga memiliki daftar penerjemah bahasa pemrograman otomatis yang cukup luas .
Anderson Green
Sepertinya seseorang membuat penerjemah php ke java dan benar-benar menanamkan biner PHP. Setuju meskipun itu tidak mengubah poin Anda. runtimeconverter.com/single-post/2017/09/15/…
user1122069
20

Jika Anda memiliki format perantara, maka Anda dapat menerapkan sesuatu yang menerjemahkan program dalam Bahasa X ke format itu, dan juga dari format itu ke Bahasa Y. Terapkan konversi tersebut untuk semua bahasa yang Anda minati dan selesai, bukan?

Anda tahu? Format seperti itu sudah ada: perakitan. Kompiler sudah melakukan konversi "Bahasa X ke perakitan", dan pembongkaran ke konversi "perakitan ke Bahasa Y".

Sekarang, assembly bukanlah bahasa yang hebat untuk melakukan konversi terbalik, tetapi MSIL sebenarnya tidak terlalu buruk. Unduh Reflector dan Anda akan melihat ada opsi untuk membongkar perakitan .NET ke banyak bahasa yang berbeda (dan plugin bahkan menyediakan lebih banyak lagi). Jadi sangat mungkin untuk mengambil program dalam C #, kompilasi ke DLL (yaitu, MSIL), kemudian gunakan reflektor untuk membongkar itu menjadi VB, C ++ / CLI, F #, dan banyak lainnya. Tentu saja, semua pekerjaan konversi lainnya juga. Ambil file F #, kompilasi ke DLL, gunakan Reflector untuk mengubahnya menjadi C #.

Tentu saja, dua masalah besar yang akan Anda temukan adalah:

  1. Kode ini pada dasarnya tidak dapat dibaca. MSIL (bahkan dengan informasi debug) menghapus banyak informasi dari sumber asli, sehingga versi yang diterjemahkan tidak memiliki kesetiaan 100% (secara teoritis melakukan konversi C # -> MSIL-> C # akan mengembalikan kode asli, tetapi biasa).
  2. Banyak bahasa .NET memiliki pustaka kustom mereka sendiri (misalnya pustaka runtime VB, pustaka F # dan sebagainya). Ini perlu dimasukkan (atau dikonversi) ketika Anda melakukan konversi juga.

Benar-benar tidak ada yang bisa dikalahkan # 2, tetapi Anda mungkin bisa mendapatkan # 1 dengan beberapa anotasi tambahan di MSIL (melalui atribut, mungkin). Itu akan menjadi pekerjaan tambahan, tentu saja.

Dean Harding
sumber
Banyak metadata dari sumber asli termasuk dalam MSIL (termasuk komentar XML dan metode asli, properti dan nama anggota), jadi saya tidak berpikir konversi ke C # tidak dapat dibaca seperti yang Anda katakan. Coba bongkar bagian kerangka NET.; ini sangat mudah dibaca. Tentu saja, situasinya bisa berbeda untuk konversi F # ke C #.
Robert Harvey
@ Robert: Komentar XML tidak termasuk dalam MSIL. Jika Anda melihat Microsoft.NET\Framework\v2.0.50727\enmisalnya, Anda dapat melihat semua dokumentasi XML untuk pustaka sistem. Inilah yang Reflector (et al) gunakan untuk menampilkan komentar. Konversi ini tidak dapat dibaca, yang saya katakan adalah bahwa itu bukan 100% kesetiaan yang mungkin Anda harapkan dari terjemahan tingkat sumber.
Dean Harding
2
Disassembler mengubah biner yang dapat dieksekusi mesin menjadi assembler untuk jenis prosesor tertentu (Tidak semua dunia adalah x86). Anda benar-benar bermaksud dekompiler untuk mengambil kode yang dikompilasi kembali ke sumbernya. Ini adalah tugas yang sangat sulit karena setiap kompiler, dari masing-masing pabrikan, pada setiap level optimisasi akan mengubah baris sumber menjadi bentuk biner keluaran yang berbeda.
uɐɪ
20

Apakah mungkin, setidaknya secara teori, untuk menulis 100% penerjemah yang benar di antara semua bahasa? Apa tantangan dalam praktik?

  • Menerjemahkan dari bahasa yang lebih terstruktur ke bahasa yang kurang terstruktur yang masih Turing-selesai, selalu memungkinkan.
    • Klaim ini harus dilihat secara teknis: Ini berarti bahwa program yang diterjemahkan akan menghasilkan hasil yang persis sama ketika dijalankan.
    • Tidak ada yang tersirat tentang keterbacaan kode yang diterjemahkan, atau pelestarian struktur program asli.
  • Menerjemahkan dari bahasa yang kurang terstruktur ke bahasa yang lebih terstruktur adalah mungkin, tetapi kode yang diterjemahkan akan tetap dalam bentuk yang kurang terstruktur.
rwong
sumber
1
Anda memukul paku di kepala. Coba baca kode yang keluar dari backend LLVM C. Secara teknis ini adalah kode C legal tetapi Itu Tidak Cukup (TM).
dsimcha
1
@dsimcha: Selain keterbacaan C backend membuat output jadi lebih mudah dibaca daripada debugging atau pembongkaran. Saya sangat senang mereka membawa backend itu kembali, setelah itu keluar dari perawatan untuk sementara waktu.
JM Becker
10

Mengapa Anda ingin mengonversi program?

Kedua bahasa, sumber dan bahasa target dikompilasi ke dalam kode mesin (virtual) *, jadi untuk alasan teknis tidak perlu memiliki kompiler ke bahasa tingkat tinggi lainnya.

Bahasa adalah untuk manusia. Jadi, persyaratan implisit dari pertanyaan Anda adalah: 'mengapa tidak ada penerjemah yang menghasilkan kode yang dapat dibaca ' , dan jawabannya adalah (imho): karena jika ada dua bahasa yang cukup berbeda, cara 'kode yang dapat dibaca' ditulis berbeda dengan cara yang tidak hanya perlu menerjemahkan algoritma, tetapi juga menggunakan algoritma yang berbeda.

Sebagai contoh, bandingkan iterasi tipikal dalam C dan satu dalam lisp. Atau ular sanca 'satu jalan terbaik' dengan ruby ​​idiomatik.

Di sini, masalah yang sama mulai muncul yang Anda miliki dalam bahasa nyata, seperti Anda menerjemahkan 'Ini hujan kucing dan anjing' ke sesuatu dengan arti 'Menuangkan seperti dari ember' ketika menerjemahkan dari bahasa Inggris ke bahasa Jerman, Anda tidak bisa terjemahkan kata demi kata lagi, tetapi Anda harus mencari artinya.

Dan 'makna' bukanlah konsep yang mudah untuk dikerjakan.

*) yah, ada kopi resep ...

keppla
sumber
1
Jawaban yang bagus. Orang dapat menambahkan bahwa jika dua bahasa memiliki serangkaian fitur dan idiom yang persis sama, akan mungkin untuk menerjemahkan satu bahasa ke bahasa lain dengan cukup efisien, tetapi sebagian besar bahasa dirancang untuk tujuan mendukung fitur dan idiom yang menurut pencipta mereka tidak memadai. didukung dalam bahasa lain . Terjemahan mekanis dari kode yang dapat dipelihara kadang-kadang bisa dilakukan ketika fitur dan idiom dalam bahasa target adalah superset dari yang ada dalam bahasa sumber, tetapi situasi seperti itu tidak terlalu umum.
supercat
6

Secara teori itu mungkin tetapi kebanyakan tidak berguna. Hampir semua kombinasi bahasa sumber dan target dimungkinkan, tetapi dalam kebanyakan kasus tidak ada yang ingin melihat atau menggunakan hasilnya.

Sejumlah kompiler melakukan target C, hanya karena kompiler C tersedia untuk hampir setiap platform yang ada (dan ada generator kompiler otomatis yang akan memungkinkan Anda mendesain prosesor, dan secara otomatis menghasilkan kompiler C yang menargetkan prosesor baru Anda). Tentu saja ada juga sejumlah implementasi yang menargetkan bahasa yang digunakan oleh berbagai mesin virtual seperti .NET, JVM, C--, dan LLVM.

Namun, kuncinya adalah bahwa itu benar-benar hanya berguna jika Anda memperlakukan target pada dasarnya adalah bahasa rakitan yang hanya digunakan sebagai langkah dalam proses kompilasi. Secara khusus, Anda biasanya tidak ingin programmer normal membaca atau bekerja dengan hasil itu; biasanya tidak akan terlalu mudah dibaca.

Jerry Coffin
sumber
5

FWIW, ada penerjemah dari Jawa ke D. Ini disebut TioPort dan digunakan dalam upaya yang cukup serius untuk mem -port SWT ke D. Masalah utama yang ditabraknya adalah bahwa akan diperlukan untuk port bagian besar dari perpustakaan standar Java .

dsimcha
sumber
4

Meskipun ini bukan terjemahan kode, konsep workbenches bahasa menunjukkan bagaimana sesuatu yang mirip dengan penerjemah 100% yang benar antara semua bahasa dapat diimplementasikan.

Dalam pendekatan kami saat ini, kode sumber disimpan dalam format tekstual. Selama kompilasi, file teks yang dapat dibaca manusia itu diurai menjadi representasi pohon sintaksis abstrak, yang pada gilirannya digunakan untuk menghasilkan bytecode atau kode mesin. Representasi abstrak ini bersifat sementara dan internal untuk kompiler.

Dalam pendekatan meja kerja bahasa, representasi pohon sintaksis abstrak yang serupa adalah artefak permanen yang disimpan. Baik kode mesin dan kode 'sumber' tekstual dihasilkan berdasarkan representasi abstrak ini. Salah satu konsekuensi dari metode tersebut adalah bahwa representasi abstrak dari program ini sebenarnya adalah bahasa-agnostik, dan dapat digunakan untuk menghasilkan kode teks dalam bahasa yang diterapkan. Berarti bahwa satu orang dapat mengerjakan aspek berbeda dari sistem secara bebas menggunakan bahasa apa pun yang mereka anggap paling tepat, atau setiap anggota tim dapat mengerjakan proyek bersama dalam bahasa yang paling mereka kenal.

Sejauh yang saya tahu, teknologi ini masih jauh dari dapat digunakan dalam pengembangan arus utama, namun ada beberapa kelompok yang bekerja secara mandiri. Sulit untuk mengatakan apakah ada di antara mereka yang akan memenuhi janji mereka, tetapi akan menarik untuk melihat itu terjadi.

scrwtp
sumber
Bisakah Anda menyebutkan beberapa dari grup ini?
Qwertie
4

Sana yang beberapa penerjemah otomatis. Jika tujuan Anda adalah untuk menghasilkan kode yang dapat dikompilasi, bukan kode yang dapat dibaca, sangat mungkin dan kadang-kadang berguna, hanya saja tidak terlalu sering. Terkenal, kompiler C ++ pertama sebenarnya bukan kompiler, tetapi menerjemahkan C ++ ke dalam (sangat rumit) sumber C yang kemudian dikompilasi oleh kompiler C. Banyak kompiler dapat membuat kode rakitan berdasarkan permintaan - tetapi alih-alih mengeluarkan teks rakitan dan kemudian menerjemahkannya ke kode mesin, mereka biasanya dapat menghasilkan kode mesin secara langsung.

Dengan spesifikasi bahasa A yang lengkap, pada prinsipnya tidak sulit untuk menulis sebuah program yang mengekspresikan arahannya dalam beberapa bahasa B. Tetapi biasanya siapa pun yang menghadapi masalah akan memilih sesuatu yang sangat rendah untuk "bahasa B": Kode mesin , atau hari ini bytecode: Jython adalah implementasi dari python yang menghasilkan kode byte java, yang ditafsirkan oleh Java VM. Tidak perlu repot menulis dan menyusun hierarki kelas java!

alexis
sumber
3

Ini dilakukan setiap saat.

Setiap kompiler menerjemahkan "bahasa utama," seperti C ++, ke bahasa assembly asli mesin atau bytecode yang tidak bergantung pada arsitektur dalam kasus bahasa yang ditafsirkan.

Saya membayangkan bukan itu yang Anda bicarakan. Anda mungkin ingin seorang penerjemah yang mengubah C ++ menjadi sesuatu seperti Java atau Python. Apa gunanya itu? Paling-paling, hasil akhirnya akan memiliki efisiensi yang sama persis seperti sumber aslinya. (Praktis, itu akan jauh lebih buruk.)

Jika Anda hanya ingin kode diterjemahkan sehingga Anda dapat membacanya sebagai bahasa yang Anda pahami, penerjemah seperti itu akan memiliki kebalikan dari efek yang diinginkan. Anda akan dibiarkan dengan kode cryptic, tidak intuitif dan tidak terbaca.

Ini karena hanya hal-hal yang paling sepele yang diterjemahkan langsung dari satu bahasa ke bahasa lain. Seringkali, apa yang sederhana dalam satu bahasa membutuhkan perpustakaan besar untuk yang lain - atau mungkin tidak mungkin sama sekali. Karena itu:

  1. Jika program ini sepele, Anda mungkin mendapatkan hasil yang layak. Tetapi kemudian, jika sesederhana itu, apa gunanya menjalankannya melalui penerjemah?
  2. Jika program tidak trivial, kodenya akan berkualitas rendah.

Pada akhirnya, satu-satunya cara untuk menulis kode yang baik adalah dengan benar-benar menulisnya. Komputer tidak bisa - setidaknya belum - menyamai manusia dalam hal keterbacaan, praktik terbaik, dan solusi elegan.

Singkatnya, itu tidak layak.

Maxpm
sumber
analogi Anda juga akan berlaku untuk kompilasi normal, dan kami tahu secara empiris tidak! Komputer melakukan 'menghasilkan' (tidak menulis) kode berkualitas baik. Apa yang sering mereka lakukan dengan buruk adalah keterbacaan / pemeliharaan. Jika seseorang memang membutuhkan proses seperti itu, yang kadang-kadang membuat saya percaya, tidak ada masalah yang menunjukkan penghentian. Jika ya, tentu saja, terjemahannya pada awalnya tidak pernah penting.
JM Becker
1

Tidak ada penerjemah bahasa untuk bahasa pemrograman karena bahasa pemrograman sangat kompleks. Meskipun secara hipotesis dimungkinkan, ada banyak tantangan.

Tantangan pertama hanyalah dalam praktik bahasa yang dapat diterima. Konversi antara dua bahasa berorientasi objek seperti Java dan C ++ sangat kompleks, dan keduanya berbasis C. Program penerjemah harus memiliki pengetahuan sempurna tentang perpustakaan standar untuk kedua bahasa dan dapat mengetahui perbedaan dalam perilaku. Anda harus membuat kamus besar dan bahkan kemudian, perbedaan gaya pemrograman dari programmer ke programmer akan berarti bahwa itu harus menebak bagaimana melakukan beberapa perubahan.

Setelah Anda mendapatkan terjemahan sintaksisnya, Anda kemudian harus mencari cara untuk mengkonversi suatu konstruk dalam bahasa pertama menjadi sebuah konstruk dalam bahasa kedua. Ini bagus jika Anda akan objek dalam C ++ ke objek di Jawa (relatif mudah itu) tapi apa yang Anda lakukan dengan C + + struct Anda? Atau fungsi di luar kelas C ++? Memutuskan bagaimana menangani ini bisa rumit karena dapat menghasilkan masalah lain, yaitu penciptaan objek gumpalan. Gumpalan adalah antipattern yang cukup umum.

Ini bukan daftar lengkap masalah, tetapi itu hanya dua dan itu adalah masalah besar. Salah satu profesor saya menyebutkan bahwa seseorang meyakinkan majikannya bahwa mereka dapat membuatnya dari kode mesin ke C di tahun 80-an, tetapi tidak berhasil saat itu. Saya ragu akan ada yang bekerja sepenuhnya.

indyK1ng
sumber
Saya pikir tidak perlu tahu perpustakaan yang ada, hanya bisa menerjemahkan perpustakaan saat berjalan (dengan asumsi mereka memiliki sumber yang tersedia).
serg
1
Itu sebenarnya meningkatkan kompleksitas masalah kedua itu. Dan itu dengan asumsi Anda memiliki akses ke kode sumber untuk menerjemahkannya. Bagaimanapun, itu masih agak tidak layak.
indyK1ng
Poin +1 tentang lib benar-benar valid, dan ada SELALU lib.
Dan Rosenstark
1

Inti dari kompilasi adalah untuk mendapatkan sesuatu yang bermanfaat bagi komputer. yaitu sesuatu yang bisa dijalankan. Mengapa mengkompilasi ke sesuatu yang bahkan mungkin tingkat yang lebih tinggi dari apa yang Anda tulis?

Saya suka strategi .NET yang lebih baik. Kompilasi semuanya dengan bahasa umum. Ini memberikan manfaat dari bahasa yang dapat berkomunikasi tanpa perlu membuat (N ^ 2) -N kompiler lintas bahasa.

Sebagai contoh jika Anda memiliki 10 bahasa pemrograman, Anda hanya perlu menulis 10 kompiler di bawah model .NET dan mereka semua dapat berkomunikasi satu sama lain. Jika Anda membuat semua kompiler lintas bahasa yang memungkinkan, Anda harus menulis 90 kompiler. Itu banyak pekerjaan ekstra untuk sedikit manfaat.

mike30
sumber