Чи є програми, які можуть "перевести" вихідний код між будь-якими двома мовами?


28

Чи є програми, які можуть "перевести" вихідний код між будь-якими двома мовами (якщо припустимо, що перекладач має доступ до необхідних бібліотек)?

Якщо вони є, як вони працюють (використовувані методи, необхідні знання тощо)? Як вони могли б бути побудовані?

Якщо їх немає, які обмеження перешкоджають їх розвитку? Це повна проблема AI (переклад на природну мову вказаний як один)?

Перетворення EDIT очікується лише тоді, коли мова має однакову силу вираження, може вирішити такі ж проблеми і код, який потрібно перетворити, може бути виражений мовою призначення. (Наприклад, не очікується перетворення з сценарію оболонки в MATLAB).



14
Що ви маєте на увазі під «будь-якими двома мовами»? Звичайно, є програми, які можуть перекладати з однієї мови на іншу. Їх називають "компіляторами". Це буквально визначення компілятора: програма, яка перекладає програми з однієї мови на іншу. Але "якісь дві мови"? Я не думаю, що це можливо. Перекладач повинен знати як вихідну, так і мову цільового, і зазвичай він характерний для певної пари мов.
Йорг W Міттаг

Програма надається мовами джерела та цільовими мовами. Я думаю про те, щоб написати програму на C ++, перекласти її на Java, python, Perl, Ruby, Go і т.д. Можуть бути деякі обмеження (я не очікую, що вона перетворить ваш скрипт оболонки в MATLAB, наприклад).
Тобі Алафін

4
Так, їх називають компіляторами, вони працюють як компілятори, і вони можуть бути сконструйовані як компілятори.
користувач253751

1
Якщо під "будь-якими двома мовами" ви буквально маєте на увазі, що (кінцева) програма повинна вміти читати та розуміти нескінченну кількість мов введення, відповідь тривіально " ні" . Однак візьміть обмежений набір мов введення, і ви зможете знайти компілятор для всіх цих мов ..
Bakuriu

Відповіді:


57

TLDR; це можливо, але не практично.

(якщо припустити, що перекладач має доступ до необхідних бібліотек)?

Це в кінцевому підсумку є складним шматочком і є частиною того, чому подібні речі не використовуються на практиці.

  1. Усі компілятори - перекладачі. Переклад з однієї мови на іншу, безумовно, можливий, і це буквально все, що робить компілятор. Мова, яку компілятор викладає як вихід, - це, як правило, машинний код або збірка, але це просто інша мова, і є компілятори (іноді їх називають транспіляторами або транскоміляторами), які перекладаються між двома мовами . Наприклад, існує гама мов компіляції до Javascript, таких як PureScript, Elm, ClojureScript тощо.

  2. Переклад між будь-якими двома мовами Turing Complete завжди можливий. Ігнорування таких речей, як дзвінки в бібліотеку та FFI та інші неприємні практичні біти, які заважають, тобто. Якщо мова є Turing Complete, то у вас є:

    • Переклад, який перетворює машину Тьюрінга на код цією мовою
    • Переклад з цієї мови на машину Тюрінга

    Отже, щоб перевести з мови A на мову B, ви перетворите код А в машину Тьюрінга, а потім перетворите цю машину в код B.

    Звичайно, на практиці практичні шматочки заважають, і це також вимагає, щоб ви мали доступні переклади. Вони існують для кожної мови, але це не означає, що хтось знайшов час, щоб виписати їх.

  3. Робити цей переклад ефективно, важко . Різні мови надають пріоритет різним речам. Наприклад, якщо ви перекладете з C на Python, вам, ймовірно, доведеться в кінцевому підсумку імітувати пам'ять C як словник Python, щоб ви могли робити арифметику вказівника. З цим буде пов’язано накладні витрати, тому що ви зараз не маєте доступу до інструкцій з чистого металу.

    Різні мови мають різницькі пріоритети продуктивності, тому щось, що оптимізує одна мова (а точніше, оптимізація однієї мови), неможливо зробити швидко на іншій мові. Переклад функціональної мови на належні хвостові дзвінки уповільниться, якщо ви перекладете її на мову без належних викликів хвоста.

  4. Здійснення цього перекладу не робить код читабельним . Легко дістати фрагмент коду на мові B, який поводиться так само, як код з мови A. Важко зробити так, щоб він виглядав так, як код, який людина написав би на B, з ряду причин. A і B можуть мати різні інструменти абстрагування, і комп'ютер не має уявлення про те, що робить код читабельним. Це буде особливо вірно, якщо ви в кінцевому підсумку скористаєтеся перекладом машини, який я описав раніше.

    Тут виникає питання: який сенс такого перекладу? Якщо все, що ви отримуєте в кінці, нам блок повільного, нечитабельного коду, чому б просто не скласти його до машинного коду і використовувати якусь FFI або міжпроцесорну комунікацію, щоб з'єднати шматки разом?

    З цього є деякі винятки. Іноді потрібні речі певною мовою (наприклад, JavaScript). Іноді мова схожа, і розумний переклад легкий. Іноді мова призначена не для запуску, а для того, щоб її код був вилучений на іншу мову (наприклад, Coq).

    Але загалом це не дуже практична річ.


5
Одним з прикладів є точка 4 asm.js . Сьогодні це можна зробити сортованим для читання, використовуючи джерела Javascript Maps and Element Inspector, але ніхто не захоче цього робити ...
Ісмаель Мігель

1
Modelica - це ще один приклад мови, призначеної для компіляції в іншу мову (в даному випадку C).
Відновіть Моніку

Веб-збірка, що перекладається з C ++ на javascript.
Сурт

Існує чимало прикладів транспіляторів від X до Y, але це відрізняється від універсального компілятора до всього, що завгодно. Очевидно, є випадки, коли транслідування має сенс.
jmite

Одним важливим винятком відсутнього IMO: компіляція до C. Причиною є те, що у багатьох незвичайних системах є існуючий компілятор C, який, як правило, може випромінювати досить розумний машинний код. Отже, компілюючи мову на C, вам не потрібно мати пропуски для тих рідкісних архітектур.
MSalters

2

Є такі програми. Наприклад, перекладачі Lisp-to-Fortran, які широко використовувались у свій час. Індивідуальні компілятори Lisp не компілюють Lisp безпосередньо, а генерують код C замість цього, а потім компілюється звичайним компілятором C. Іншим прикладом може бути Vala, який не компілюється безпосередньо, а спочатку переводиться на C ++ до того, як буде зібраний код C ++. Qt написано на MOC, мові, що перекладається на C ++ для того, щоб компілювати її (але оскільки MOC - це просто C ++, за допомогою декількох додаткових команд можна сперечатися, чи справді її потрібно назвати "новою мовою") - і перед тим були компіляторами C ++, були C ++ - до-C-перекладачі. А деякі проекти були написані на Паскалі, а потім перекладені на C. Також кланг та Java мають тенденцію бути подібними до таких речей, як вони перекладають C ++ та Java-код на якусь проміжну мову, яка потім може бути оброблена далі.

Те, чого ви не можете очікувати від виводу мовного перекладача, - це те, що результат має будь-який сенс для людського читача: Завдання програми - написати код, який призводить до того, що програма робить те саме, що і оригінальний код (який, на мій досвід, може чи може не працює, залежно від того, які особливості мови та які зовнішні бібліотеки ви використовували). Але оскільки невідомо, яка мета цього завдання виконується для решти значення програми, можливо, буде втрачено значною мірою.


0

Не пряма відповідь, але в ньому є виклик інструменту ILSpy , який був написаний для .Net Framework, і дозволяє декомпілювати збірку .Net на C # або VB.Net.

Якщо ви незнайомі з природою .Net, ви можете написати код .Net багатьма мовами, але в першу чергу C # або VB.Net. Коли компілятор компілює додаток, він переводить код на код «Проміжний мова» (або короткий ІЛ). Потім цей код компілюється у бінарні файли .Net.

Оскільки програми .Net - це бінарні файли, складені з коду IL, ILSpy може прийняти додаток .Net, повернути його назад до коду IL і, згодом, зробити його на крок далі та повернути назад до C # або VB.Net.

За допомогою цього інструменту все, що вам потрібно зробити, - це скласти програму, а потім ви можете переглянути компільовані файли у вигляді коду IL, C # або VB.Net. Щоб було зрозуміло, неважливо, на якій мові код був спочатку написаний. Поки двійковий файл є збіркою .Net, він може реінжинірувати складені файли та виводити вміст будь-якою з цих трьох мов.

Я знаю, що це не зовсім компілятор, але це інструмент, який пропонує кінцевий результат, подібний до того, що ви шукаєте, і, власне, я використовував це для "перетворення" проектів VB.Net у щось невелике більш знайомий мені - C #.


0

Для вашого випадку використання (на основі коментарів) звучить, що SWIG може бути корисним.

SWIG - це інструмент розробки програмного забезпечення, який з'єднує програми, написані на C і C ++, з різними мовами програмування високого рівня. SWIG використовується з різними типами цільових мов, включаючи поширені мови сценаріїв, такі як Javascript, Perl, PHP, Python, Tcl та Ruby. У список підтримуваних мов також входять мови, що не використовують сценарії, такі як C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go мова, Java, включаючи Android, Lua, Modula-3, OCAML, Octave, Scilab та R Також підтримується кілька інтерпретованих та складених реалізацій схеми (Guile, MzScheme / Racket, Chicken).


0

Я пригадую поважний f2c , який робить переклад від джерела до джерела з Fortran 77 на C.

Він (іноді буває ...) використовується в основному для перекладу числового коду з десятиліть тому назад без необхідності інтегрувати компілятор fortran у свою ланцюжок інструментів.


0

Теоретичний фрагмент, який говорить вам про те, що такі програми існують, в принципі, називається допустимою нумерацією . Ми можемо довести, що між будь-якими двома такими нумераціями є обчислювані компілятори, і кожен формалізм-повний Тьюрінга (або мова програмування), по суті, один.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.