İki dil arasında kaynak kodlarını 'çevirebilen' programlar var mı?


28

Herhangi bir iki dil arasında kaynak kodunu 'çevirebilen' programlar var mı (çevirmenin gerekli kütüphanelere erişimi olduğunu varsayarsak)?

Varsa, nasıl çalışırlar (kullanılan teknikler, gerekli bilgi vb.)? Fizibil olarak nasıl inşa edilirler?

Olmazlarsa, gelişimlerini engelleyen kısıtlamalar nelerdir? Bu bir AI tam sorunu mu (doğal dil çevirisi bir tane olarak listeleniyor)?

DÜZENLEME Dönüşüm, yalnızca dilin aynı ifade gücüne sahip olması durumunda, aynı sorunları çözebilir ve dönüştürülecek kodhedef dilde ifade edilebilir . (Örneğin, bir kabuk betiğinden MATLAB'a dönüşüm beklenmiyor).



14
Herhangi bir iki dilde ne demek istiyorsun? Kesinlikle bir dilden diğerine çevrilebilecek programlar var. Bunlara "derleyiciler" denir. Bu tam anlamıyla bir derleyicinin tanımı: programları bir dilden diğerine çeviren bir program. Ama "herhangi iki dil"? Bunun mümkün olduğunu sanmıyorum. Tercüman hem kaynağı hem de hedef dili bilmek zorundadır ve genellikle belirli bir dil çiftine özgüdür.
Jörg W Mittag

Program kaynak ve hedef dilleri sağlanır. C ++ 'da Java, python, Perl, Ruby, Go, vb.' Ye çevirerek bir program yazmayı düşünüyorum. Bazı kısıtlamalar olabilir (örneğin, kabuk betiğinizi MATLAB'a dönüştürmesini beklemiyorum).
Tobi Alafin,

4
Evet, derleyiciler denir, derleyiciler gibi çalışırlar ve derleyiciler gibi oluşturulabilirler.
kullanıcı253751,

1
"Her iki dili" ile kelimenin tam anlamıyla (sonlu) programı okumak ve giriş dilleri sonsuz sayıda anlamak gerekir anlamına, cevap trivially olduğunu hiçbir . Ancak, sınırlı sayıda girdi dili alın ve tüm bu diller için bir derleyici bulabilirsiniz ..
Bakuriu

Yanıtlar:


57

TLDR; bu mümkün ama pratik değil.

(çevirmenin gerekli kütüphanelere erişimi olduğunu varsayarsak)?

Bu zor bir bit olmaktan çıkıyor ve bu gibi şeylerin pratikte neden kullanılmadığının bir parçası.

  1. Tüm derleyiciler çevirmendir. Bir dilden diğerine çeviri kesinlikle mümkündür ve bu kelimenin tam anlamıyla bir derleyicinin yaptığıdır. Bir derleyicinin çıktı olarak kullandığı dil genel olarak makine kodu veya derlemesidir, fakat bu sadece başka bir dildir ve iki dil arasında çeviri yapan derleyiciler (bazen transpiller veya trans derleyiciler olarak da adlandırılır) vardır . Örneğin, PureScript, Elm, ClojureScript, vb. Gibi bir Javascript dilleri dizisi var.

  2. İki Turing Complete dili arasında çeviri yapmak her zaman mümkündür. Kütüphane çağrıları, FFI ve buna engel olan diğer kötü pratik bitler gibi şeyleri görmezden gelmek. Eğer bir dil Turing Complete ise, o zaman:

    • Turing Makinesi'ni bu dilde kodlamaya dönüştüren bir çeviri
    • Bu dilden bir Turing Makinesi'ne çeviri

    Böylece, A dilinden B diline çevirmek için, A kodunu bir Turing Makinesi'ne, ardından o makineyi B koduna dönüştürürsünüz.

    Tabii ki, pratikte pratik bitler buna engel oluyor ve bu da sizin için çevirilerin erişilebilir olmasını gerektiriyor. Temelde her dil için varlar, ancak bu birisinin onları yazmak için zaman harcadığı anlamına gelmiyor.

  3. Bu çeviriyi verimli yapmak çok zor . Farklı dil farklı şeylere öncelik verir. Örneğin, C'den Python'a çeviri yaparsanız, muhtemelen C'nin belleğini bir Python sözlüğü olarak simüle etmek zorunda kalacaksınız, böylece işaretçi aritmetiğini yapabilirsiniz. Bununla ilgili bir ek yük olacak, çünkü şu anda tamamen metal bellek talimatlarına erişmiyorsunuz.

    Farklı dillerin farklı performans öncelikleri vardır, bu nedenle bir dilin optimize ettiği (veya bir dilin optimizasyonunun uygulanması) başka bir dilde hızlı bir şekilde yapılması imkansız olabilir. İşlevsel bir dilin uygun kuyruk çağrılarıyla çevrilmesi, uygun kuyruk çağrıları olmayan bir dile çevirirseniz yavaşlar.

  4. Bu çeviriyi yapmak kodu okunabilir yapmaz . B dilinde, A dilindeki kodla aynı şekilde hareket eden bir kod parçasını elde etmek kolaydır. Bir insanın B'de yazmış olduğu bir kod gibi görünmesini sağlamak, bir çok nedenden dolayı zor. A ve B'nin farklı soyutlama araçları olabilir ve bilgisayarın kodu neyin okunabileceği hakkında hiçbir fikri yok. Bu daha önce tarif ettiğim Turing Machine çevirisini kullanmanız durumunda ortaya çıkar.

    Bu şu soruyu gündeme getiriyor: böyle bir çevirinin amacı nedir? Sonunda hepiniz bize yavaş, okunamayan bir kod bloğu geliyorsa, neden sadece makine koduna derlenip parçaları birbirine bağlamak için bir çeşit FFI veya süreçler arası iletişim kullanmıyorsunuz?

    Bunun bazı istisnaları var. Bazen belirli bir dilde bazı şeylere ihtiyaç duyarsınız (JavaScript gibi). Bazen dil benzerdir ve mantıklı bir çeviri kolaydır. Bazen bir dilin çalıştırılması değil, kodunun başka bir dile (Coq gibi) eklenmesi gerekir.

    Ancak genel olarak, bu çok pratik bir şey değil.


5
Nokta 4 için bir örnek asm.js'dir . Bugün, Javascript Kaynak Haritaları ve Eleman Müfettişi kullanarak sorta okunabilir hale getirmek mümkündür , ancak kimse bunu yapmak istemeyecektir ...
Ismael Miguel

1
Modelica, başka bir dile derlenmek üzere tasarlanmış bir dilin örneğidir (bu durumda C).
Monica

C ++ 'dan javascript'e çevrilmiş web montajı.
16'da

X'ten Y'ye kadar sayısız transpil örneği vardır, ancak bu, evrensel bir şeyden herhangi bir derleyiciden farklıdır. Açıkça aktarmanın mantıklı olduğu durumlar vardır.
jmite

IMO eksik bir önemli istisna: C'ye derleme Sebebi, pek çok nadir sistemin, genellikle oldukça makul bir makine kodu yayabilecek mevcut bir C derleyicisine sahip olmasıdır. Dolayısıyla, bir dili C'ye derleyerek, bu nadir mimariler için arka uçlara ihtiyaç duymazsınız.
MSalters

2

Böyle programlar var. Örneğin, yaygın olarak kullanılan Lisp-Fortran tercümanları. Sole Lisp derleyicileri Lisp'i doğrudan derlemez, bunun yerine C kodu üretir, bunun yerine normal bir C derleyicisi tarafından derlenir. Başka bir örnek, doğrudan derlenmemiş ancak C ++ kodu derlenmeden önce ilk olarak C ++ 'a çevrilmiş olan Vala olacaktır. Qt, MOC'da, derlemek için C ++ 'a çevrilmiş bir dilde yazılmıştır (ancak MOC olduğu gibi, sadece "yeni bir dil" olarak adlandırılacaksa söylenebilecek birkaç ek komutla sadece C ++ olduğu gibi) - ve önce C ++ derleyicileri, C ++ - to-C çevirmenleriydi. Ve bazı projeler Pascal'da yazıldı ve daha sonra C'ye çevrildi. Ayrıca clang ve Java, C ++ ve Java kodlarını daha sonra işlenebilecek bir orta dile çevirecekleri gibi bir şey olma eğilimindedir.

Bir dil çevirmeninin çıktısından bekleyemeyeceğiniz şey, sonucun bir insan okuyucusu için bir anlam ifade etmesidir: Programın görevi, orijinal kodla aynı şeyi yapan bir programla sonuçlanan kod yazmaktır (deneyimlerime göre olabilir veya olabilir) dilin hangi özelliklerini ve hangi harici kütüphaneleri kullandığınıza bağlı olarak çalışmaz. Ancak, programın geri kalanının anlamının büyük bir kısmı için kaybedilmiş olabileceği için bu görevi gerçekleştirme amacını bilmediğinden.


0

Doğrudan bir cevap değil, ancak içinde .Net Framework için yazılmış olan ve bir .Net derlemesini C # veya VB.Net'e derlemenizi sağlayan bir araç çağrısı olan ILSpy var .

.Net'in yapısını iyi bilmiyorsanız, .Net kodunu birçok dilde yazabilirsiniz, ancak öncelikle C # veya VB.Net. Derleyici, uygulamayı derlediğinde, kodu bir "Orta Dil" e (ya da kısaca IL) koda çevirir. Bu kod daha sonra .Net ikili dosyalarına derlenir.

.Net uygulamaları IL kodundan derlenmiş ikililer olduğundan, ILSpy .Net uygulamasını alabilir, IL koduna geri döndürür ve ardından bir adım daha ileri götürür ve C # veya VB.Net'e geri döndürür.

Bu aracı kullanarak tek yapmanız gereken bir uygulamayı derlemek ve ardından derlenmiş dosyalara IL, C # veya VB.Net kodu olarak göz atabilirsiniz. Açıkça söylemek gerekirse, kodun ilk olarak hangi dilde yazıldığı önemli değildir. İkili bir .Net derlemesi olduğu sürece, derlenmiş dosyaların tersine mühendislik yapabilir ve içeriği bu üç dilden herhangi biri olarak çıkartabilir.

Bunun tam olarak bir derleyici olmadığını biliyorum, ancak aradığınız şeye benzer bir sonuç ortaya çıkaran bir araç. Aslında bunu VB.Net projelerini biraz çevirmek için kullandım. bana daha tanıdık - C #.


0

Kullanım durumunuz için (yorumlara dayanarak), SWIG yararlı olabilir gibi geliyor .

SWIG, C ve C ++ ile yazılmış programları çeşitli üst düzey programlama dilleriyle birleştiren bir yazılım geliştirme aracıdır. SWIG, Javascript, Perl, PHP, Python, Tcl ve Ruby gibi genel betik dilleri dahil olmak üzere farklı türlerdeki hedef dillerle kullanılır. Desteklenen dillerin listesi, C #, Ortak Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go dili, Android, Java, Java, Modula-3, OCAML, Octave, Scilab ve R gibi Java dillerini içerir. Ayrıca birkaç yorumlanmış ve derlenmiş Şema uygulaması (Guile, MzScheme / Racket, Chicken) desteklenmektedir.


0

Fortran 77'den C'ye kaynağından kaynağa çeviri yapan saygın f2c'yi hatırlıyorum .

Genellikle (on yıl ...) sayısal kodu bir on yıl öncesinden bir fortran derleyicisini alet zincirinize entegre etmek zorunda kalmadan çevirmek için kullanılıyordu.


0

Bu tür programların var olduğunu söyleyen teoriye prensipte kabuledilebilir numaralamalar denir . Bu iki numara arasında hesaplanabilir derleyiciler olduğunu kanıtlayabiliriz ve her Turing-complete formalizmi (veya programlama dili) özünde bir tanedir.

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.