Чому немає автоматизованих перекладачів з однієї мови програмування на іншу? [зачинено]


37

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

Чи можливо, принаймні теоретично, написати 100% правильний перекладач між усіма мовами? Які проблеми є на практиці? Чи є якісь перекладачі, які працюють?


5
Пам'ятайте, що "всі мови" включають навіть дурні, як Oook! (Завершення повноти - це не вся історія; вам потрібні також систематичні дзвінки на практиці.)
Дональд стипендіатів

Є деякі. Перекладачі з C до Паскаля та Pascal до C були досить поширеними в один момент. Як свідчать відповіді нижче, висновок зазвичай не був начитаний без принаймні ручного прибирання. І це відносно прості мови з відносно простими бібліотеками - виконувати цю роботу, наприклад, для C ++ до Haskell або наочно, було б неможливо.
Стів314,

Ознайомтеся з компілятором .net Roslyn як службою, яка має можливість перекладати C # на VB і навпаки.
Даніель Літтл

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

Переконавшись у точності Google translate, я переконаний, що побачу універсального перекладача у своєму житті. Так, це буде складним зусиллям і може зажадати великих зусиль, як у випадку аналізу великої бази кодів, наприклад, github або stackoverflow, але це станеться, і попит на такий інструмент теж зросте в наступних віках, особливо зараз що є велика кількість програмістів для вивчення AI та ML. Можливо, не знайдеться жодної людини, яка сама розробляє такий інструмент. Однак можна розробити бота для розробки ботів для вирішення цієї проблеми.
Ганеш Камат - 'Код несамовитості'

Відповіді:


32

Найбільшою проблемою є не власне переклад програмного коду, а перенесення API платформи.

Розгляньте перекладач PHP на Java. Єдиний можливий спосіб зробити це без вбудовування частини бінарного PHP - це повторне впровадження всіх модулів та API PHP на Java. Це передбачає реалізацію понад 10 000 функцій. Порівняно з цим, робота з перекладу синтаксису є легкою як пиріг. І навіть після такої роботи у вас не було б коду Java, у вас би була якась жахливість, яка трапляється на платформі Java, але вона була структурована як PHP всередині.

Ось чому єдині такі засоби, які приходять на думку, - це переклад коду для його розгортання, а не підтримка його згодом. GWT Google "компілює" Java в JavaScript. Хіпшоп у Facebook збирає PHP на C.



Схоже, хтось створив перекладач PHP на Java і насправді вбудовував бінарний PHP. Домовились, хоча це не змінює вашу точку зору. runtimeconverter.com/single-post/2017/09/15/…
користувач1122069

20

Якщо у вас проміжний формат, ви можете реалізувати щось, що переводить програму на мову X на цей формат, а також з цього формату на мову Y. Здійсніть ці перетворення на всіх мовах, які вас цікавлять, і ви закінчили, правда?

Ну ви знаєте що? Такий формат вже існує: збірка. Компілятор вже здійснює перетворення "Мова X у збірку", а розбиральники перетворює "Збір на мову Y".

Тепер, збірка не настільки чудова мова для зворотного перетворення, але MSIL насправді не так вже й погано. Завантажте Reflector, і ви побачите, що у нього є варіанти розібрати .NET-збірку на купу різних мов (а плагіни забезпечують ще більше). Тож цілком можливо взяти програму в C #, скласти її до DLL (тобто MSIL), а потім використовувати рефлектор, щоб розібрати її на VB, C ++ / CLI, F # та ще цілу купу інших. Звичайно, всі інші перетворення теж. Візьміть файл F #, компілюйте в DLL, використовуйте Reflector для перетворення його в C #.

Звичайно, дві великі проблеми, які ви знайдете, це:

  1. Код в основному нечитабельний. MSIL (навіть з інформацією про налагодження) видаляє багато інформації з початкового джерела, тому перекладена версія не має 100% вірності (теоретично виконання конверсії C # -> MSIL-> C # повинно повернути вам початковий код, але це не буде).
  2. Багато мов .NET мають власні власні бібліотеки (наприклад, бібліотека виконання VB, бібліотека F # тощо). Вони повинні бути включені (або перетворені), коли ви також здійснюєте конверсію.

Тут насправді нічого не можна обійти, але ви, мабуть, могли обійти №1 з додатковими примітками в MSIL (можливо, через атрибути). Це, звичайно, буде додатковою роботою.


Дуже багато метаданих з оригінального джерела включено до MSIL (включаючи коментарі XML та оригінальний метод, властивості та імена членів), тому я не думаю, що перетворення на C # не є настільки нечитабельним, як ви кажете. Спробуйте розібрати частини рамки .NET; це дуже легко читається. Звичайно, ситуація може бути різною для перетворення F # в C #.
Роберт Харві

@Robert: коментарі XML не включаються до MSIL. Якщо ви шукаєте, Microsoft.NET\Framework\v2.0.50727\enнаприклад, ви можете побачити всю документацію XML для системних бібліотек. Це те, що Reflector (та ін.) Використовують для відображення коментарів. Перетворення не є нечитабельним, все, що я говорив, - це не 100% вірність, якої ви можете очікувати від перекладу на рівні джерела.
Дін Хардінг

2
Розбирач перетворює виконаний на машині двійковий файл назад в асемблер для конкретного типу процесора (Не весь світ - це x86). Ви дійсно маєте на увазі декомпілятор, щоб повернути скомпільований код до джерела. Це жахливо складне завдання, оскільки кожен компілятор, від кожного виробника, на кожному рівні оптимізації буде перетворювати вихідні рядки в іншу вихідну бінарну форму.
uɐɪ

20

Чи можливо, принаймні теоретично, написати 100% правильний перекладач між усіма мовами? Які проблеми є на практиці?

  • Переведення з більш структурованої мови на менш структуровану мову, яка все ще є повною Тюрінгом, завжди можлива.
    • Цю претензію слід розглядати в суворому технічному сенсі: Це означає, що перекладена програма дасть точно такий же результат при її виконанні.
    • Нічого не мається на увазі щодо читабельності перекладеного коду чи збереження оригінальних програмних структур.
  • Переклад з менш структурованої мови на більш структуровану мову можливий, але перекладений код залишиться у менш структурованому вигляді.

1
Ти вдарився цвяхом по голові. Спробуйте прочитати код, який виходить із резервного файлу C LLVM. Це технічно законний код C, але це не досить (TM).
dimimcha

1
@dsimcha: читабельність у бік того, що бекенд C робить вихід набагато простішим для читання, ніж налагодження чи розбирання. Я так радий, що вони повернули цей бекенд знову, після того, як він ненадовго вийшов з обслуговування.
Дж. М. Бекер

10

Чому ви хочете перетворити програму?

Обидві мови, вихідна та цільова мова будь-коли компілюються у (віртуальний) машинний код *, тому з технічних причин немає необхідності мати компілятор на іншій мові високого рівня.

Мови для людей. Отже, неявна вимога вашого запитання: «чому не існує перекладача, який би генерував читабельний код» , і відповідь буде (imho): адже якщо є дві мови, які досить різняться, записуються способи "читабельного коду" відрізняється тим, що не просто потрібно було б перекласти алгоритми, але взяти різні алгоритми.

Наприклад, порівняйте типову ітерацію в C і одну в lisp. Або пітони "один найкращий спосіб" з ідіоматичним рубіном.

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

І «сенс» - це непроста концепція, над якою працювати.

*) ну, є coffeescript ...


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

6

Теоретично це можливо, але здебільшого марно. Можливе практично будь-яке поєднання мов джерела та мови перекладу, але в більшості випадків ніхто ніколи не захоче переглянути або використовувати результат.

Значна кількість компіляторів націлює на C, просто тому, що компілятори C доступні майже для кожної існуючої платформи (а також є автоматичні генератори компіляторів, які дозволять проектувати процесор і автоматично генерувати компілятор C, орієнтований на ваш новий процесор). Звичайно, існує досить велика кількість реалізацій, орієнтованих на мови, якими користуються різні віртуальні машини, такі як .NET, JVM, C-- та LLVM.

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


5

FWIW, є перекладач з Java на D. Він називається TioPort і використовувався в досить серйозній спробі передати SWT на D. Основна проблема, з якою він зіткнувся, полягав у тому, що необхідно було б перенести масивні частини стандартної бібліотеки Java .


4

Хоча це не переклад коду сам по собі, концепція мовних робочих груп показує, як можна реалізувати щось подібне до 100% правильного перекладача між усіма мовами.

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

У мовному підході до роботи аналогічне абстрактне зображення синтаксису є постійним, що зберігається артефактом. І машинний код, і текстовий 'вихідний' код створюються на основі цього абстрактного подання. Одним із наслідків такого методу є те, що абстрактне представлення програми насправді є мовно-агностичним і може використовуватися для генерації текстового коду на будь-якій реалізованій мові. Це означає, що одна людина може вільно працювати над різними аспектами системи, використовуючи ту мову, яку вони вважають найбільш підходящою, або кожен член команди може працювати над спільним проектом мовою, якою він найбільше знайомий.

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


Чи можете ви назвати деякі з цих груп?
Qwertie

4

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

З огляду на повну специфікацію мови A, в принципі не так складно написати програму, яка виражає свої директиви якоюсь мовою B. Але зазвичай кожен, хто піде на проблему, обере щось дійсно низький рівень для "мови B": машинний код або байт-код цих днів: Jython - це реалізація python, що генерує байт-код Java, який інтерпретується Java VM. Не потрібно займатись написанням та складанням ієрархій класів Java!


3

Це робиться весь час.

Кожен компілятор перекладає "первинну мову", як C ++, на рідну мову збірки машини або байт-код незалежний від архітектури у випадку інтерпретованих мов.

Я думаю, що це не те, про що ти говориш. Ви, мабуть, хочете перекладача, який перетворює C ++ на щось на зразок Java чи Python. У чому сенс цього? У кращому випадку кінцевий результат матиме таку саму ефективність, як і оригінальний джерело. (Практично, це буде набагато гірше.)

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

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

  1. Якщо програма тривіальна, ви можете отримати гідний результат. Але тоді, якщо це все просто, який сенс запускати його через перекладача?
  2. Якщо програма нетривіальна, код буде низької якості.

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

Словом, просто не варто.


Ваша аналогія також застосовуватиметься до звичайної компіляції, і ми емпірично знаємо, що це не так! Комп'ютери "генерують" (не записують) код хорошої якості. Те, що вони часто роблять погано, - це читаність / ремонтопридатність. Якщо комусь потрібен був такий процес, який, на мій погляд, люди періодично роблять, жодні проблеми не показують пробки. Якщо вони є, ну, очевидно, що переклад ніколи не був важливим.
Дж. М. Бекер

1

Немає мовних перекладачів для мов програмування, оскільки мови програмування надзвичайно складні. Хоча це гіпотетично можливо, є багато проблем.

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

Після того, як ви перенесли переклад синтаксису, вам доведеться розібратися, як перетворити конструкцію з першої мови на конструкцію на другій мові. Це добре, якщо ви збираєтесь об'єктом в C ++ до об’єкта на Java (це порівняно просто), але що ви робите зі своїми C ++ структурами? Або функції поза класами C ++? Вирішити, як впоратися з цим, може бути складним, оскільки це може призвести до виникнення іншої проблеми, а саме до створення об'єкта, що випадає. Кліщ - антипатерн, який досить поширений.

Це не повний перелік проблем, але їх всього дві, і вони великі. Один з моїх професорів згадав, що хтось переконав свого роботодавця, що він може зробити його з машинного коду до C у 80-х, але це тоді не спрацювало. Я сумніваюся, що колись знайдеться той, який працює повноцінно.


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

1
Це фактично збільшує складність другої проблеми тоді. І це припускаючи, що для перекладу у вас є доступ до вихідного коду. Так чи інакше, це все ще досить нездійсненно.
indyK1ng

+1 бал щодо губ цілком справедливий, і ВИНАГА існують.
Dan Rosenstark

1

Сенс компіляції - отримати щось корисне для комп’ютера. тобто щось, що може працювати. Навіщо компілювати на щось, що може бути навіть вищого рівня, ніж те, про що ви написали?

Мені подобається стратегія .NET краще. Складіть усе на загальну мову. Це дає перевагу мовам спілкування без необхідності створення (N ^ 2) -N компіляторів міжмовних мов.

Наприклад, якщо у вас було 10 мов програмування, вам потрібно було б написати лише 10 компіляторів за моделлю .NET, і всі вони могли спілкуватися один з одним. Якщо ви зробили всі можливі компілятори між мовами, вам потрібно було б написати 90 компіляторів. Це багато зайвої роботи за малу користь.

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