Большинство языков программирования являются полными по Тьюрингу, что означает, что любая задача, которая может быть решена на одном языке, может быть решена на другом или даже на машине Тьюринга. Тогда почему нет автоматических переводчиков, которые могут конвертировать программы с любого языка на любой другой язык? Я видел пару попыток для двух языков, но они всегда работают только на ограниченном подмножестве языка и вряд ли могут быть использованы для конвертации реальных проектов.
Можно ли, по крайней мере, теоретически, написать 100% правильный переводчик между всеми языками? Какие проблемы на практике? Существуют ли уже работающие переводчики?
Ответы:
Самой большой проблемой является не фактический перевод программного кода, а портирование API платформы.
Рассмотрим переводчик PHP на Java. Единственный реальный способ сделать это без встраивания части двоичного кода PHP - это переопределить все модули PHP и API в Java. Это включает в себя реализацию более 10.000 функций. По сравнению с этим работа по переводу синтаксиса очень проста. И даже после всей этой работы у вас не будет Java-кода, у вас будет какое-то чудовище, которое работает на платформе Java, но структурировано как PHP внутри.
Вот почему единственные такие инструменты, которые приходят на ум, - это перевод кода для его развертывания, а не для его последующего сопровождения. Google GWT «компилирует» Java в JavaScript. Хип-хоп Facebook компилирует PHP в C.
источник
Если у вас есть промежуточный формат, то вы могли бы реализовать что-то, что переводит программу на языке X в этот формат, а также из этого формата в язык Y. Выполните эти преобразования для всех языков, которые вас интересуют, и все готово, верно?
Ну знаешь что? Такой формат уже существует: сборка. Компилятор уже выполняет преобразование «Язык X в сборку», а дизассемблеры - в преобразование «Сборка в язык Y».
Теперь ассемблер - не такой уж хороший язык для обратного преобразования, но MSIL на самом деле не так уж и плох. Скачать рефлектор и вы увидите, что у него есть возможность разобрать сборку .NET на несколько языков (а плагины предоставляют еще больше). Таким образом, вполне возможно взять программу на C #, скомпилировать ее в DLL (то есть, MSIL), а затем использовать рефлектор, чтобы разобрать ее на VB, C ++ / CLI, F # и целый ряд других. Конечно, все остальные конверсионные работы тоже. Возьмите файл F #, скомпилируйте в DLL, используйте Reflector, чтобы преобразовать его в C #.
Конечно, вы обнаружите две большие проблемы:
Обойти # 2 действительно нечего, но вы, вероятно, могли бы обойти # 1 с некоторыми дополнительными аннотациями в MSIL (возможно, через атрибуты). Это была бы дополнительная работа, конечно.
источник
Microsoft.NET\Framework\v2.0.50727\en
например, вы можете увидеть всю документацию XML для системных библиотек. Это то, что Reflector (и другие) используют для отображения комментариев. Преобразование не является нечитаемым, все, что я говорил, это то, что это не 100% точность, которую вы могли бы ожидать от перевода на уровне источника.источник
Почему вы хотите конвертировать программу?
Оба языка, исходный и целевой языки в любом случае компилируются в (виртуальный) машинный код *, поэтому по техническим причинам нет необходимости иметь компилятор для другого языка высокого уровня.
Языки для людей. Итак, неявное требование вашего вопроса: «почему нет переводчика, который генерирует читаемый код» , и ответ будет (imho): потому что, если есть два языка, которые достаточно отличаются, пишется способ «читаемый код» отличается тем, что не только потребует перевода алгоритмов, но и других алгоритмов.
Например, сравните типичную итерацию в C и одну в lisp. Или питоны «одним из лучших способов» с идиоматическим рубином.
Здесь начинают появляться те же проблемы, что и у вас на реальных языках, например, когда вы переводите «Идет дождь с кошками и собаками» на что-то со значением «Это льется, как из ведер» при переводе с английского на немецкий, вы не можете переводить слово за словом больше, но вы должны искать смысл.
И «смысл» - не простая концепция для работы.
*) хорошо, есть coffeescript ...
источник
Это теоретически возможно, но в основном бесполезно. Возможна практически любая комбинация исходного и целевого языков, но в большинстве случаев никто никогда не захочет смотреть или использовать результат.
Изрядное количество компиляторов делают таргетинг на C просто потому, что компиляторы C доступны практически для каждой существующей платформы (и существуют автоматические генераторы компиляторов, которые позволят вам разработать процессор и автоматически сгенерировать компилятор C, ориентированный на ваш новый процессор). Конечно, существует также немало реализаций, предназначенных для языков, используемых различными виртуальными машинами, такими как .NET, JVM, C-- и LLVM.
Ключевым моментом, однако, является то, что это действительно полезно, только если вы рассматриваете цель как основной язык ассемблера, который используется только в качестве шага в процессе компиляции. В частности, вы обычно не хотите, чтобы обычный программист читал или работал с этим результатом; это обычно не будет очень читабельным.
источник
Кстати, есть переводчик с Java на D. Он называется TioPort и использовался в довольно серьезной попытке перенести SWT на D. Основная проблема, с которой он столкнулся, заключалась в том, что было бы необходимо портировать огромные части стандартной библиотеки Java. ,
источник
Хотя это не перевод кода как таковой, концепция языковых рабочих мест показывает, как можно реализовать что-то похожее на 100% правильный переводчик между всеми языками.
В нашем текущем подходе исходный код хранится в текстовом формате. Во время компиляции эти читаемые человеком текстовые файлы анализируются в абстрактном синтаксическом дереве, которое, в свою очередь, используется для генерации либо байт-кода, либо машинного кода. Это абстрактное представление, однако, является временным и внутренним для компилятора.
В подходе инструментальных средств языка аналогичное представление абстрактного синтаксического дерева является постоянным, хранимым артефактом. И машинный код, и текстовый «исходный» код генерируются на основе этого абстрактного представления. Одним из следствий такого метода является то, что абстрактное представление программы фактически не зависит от языка и может использоваться для генерации текстового кода на любом реализованном языке. Это означает, что один человек может свободно работать над различными аспектами системы, используя любой язык, который он считает наиболее подходящим, или что каждый член команды может работать над общим проектом на языке, который ему наиболее знаком.
Насколько я знаю, технология все еще далека от использования в основной разработке, однако есть несколько групп, которые работают над ней независимо. Трудно сказать, выполнит ли кто-нибудь из них свои обещания, но было бы интересно увидеть, как это произойдет.
источник
Там являются некоторыми автоматическими переводчиками. Если ваша цель - создавать скомпилированный код, а не читаемый код, это вполне возможно и иногда полезно, но не очень часто. Известно, что первый компилятор C ++ на самом деле не был компилятором, но преобразовал C ++ в (действительно сложный) источник C, который затем был скомпилирован компилятором C. Многие компиляторы могут генерировать ассемблерный код по запросу - но вместо того, чтобы выплевывать ассемблерный текст и затем переводить его в машинный код, они обычно могут генерировать машинный код напрямую.
Учитывая полную спецификацию языка A, в принципе не так сложно написать программу, которая выражает свои директивы на каком-то языке B. Но обычно любой, кто сталкивается с трудностями, выбирает что-то действительно низкое для «языка B»: Машинный код или в наши дни байт-код: Jython - это реализация python, которая генерирует Java-байт-код, который интерпретируется Java VM. Нет необходимости писать и компилировать иерархии классов Java!
источник
Это делается все время.
Каждый компилятор переводит «основной язык», такой как C ++, на родной язык ассемблера машины или независимый от архитектуры байт-код в случае интерпретируемых языков.
Я полагаю, что это не то, о чем вы говорите. Возможно, вам нужен переводчик, который преобразует C ++ во что-то вроде Java или Python. Но какой в этом смысл? В лучшем случае конечный результат будет иметь ту же эффективность, что и исходный источник. (Практически, это будет намного хуже.)
Если вы просто хотите, чтобы код был переведен, чтобы вы могли читать его на понятном вам языке, такой переводчик имел бы противоположность желаемому эффекту. Вы останетесь с множеством загадочного, не интуитивного и нечитаемого кода.
Это потому, что только самые тривиальные вещи переводятся непосредственно с одного языка на другой. Часто то, что просто в одном языке, требует массивных библиотек для другого - или может быть вообще невозможно. Следовательно:
В конце концов, единственный способ написать хороший код - это написать его. Компьютеры просто не могут - по крайней мере, пока - не сопоставлять людей по вопросам читабельности, лучших практик и элегантных решений.
Короче говоря, это просто не стоит.
источник
Для языков программирования нет языковых переводчиков, потому что языки программирования невероятно сложны. Хотя это гипотетически возможно, есть много проблем.
Первая проблема заключается только в приемлемой практике языка. Преобразование между двумя объектно-ориентированными языками, такими как Java и C ++, невероятно сложно, и оба они основаны на C. Программа переводчика должна была бы в совершенстве владеть стандартными библиотеками для обоих языков и уметь различать поведение. Вам придется создать огромный словарь, и даже тогда различия в стилях программирования от программиста до программиста означают, что ему придется угадывать, как выполнить некоторые изменения.
После того, как вы получили перевод синтаксиса, вы должны выяснить, как преобразовать конструкцию на первом языке в конструкцию на втором языке. Это нормально, если вы переходите от объекта в C ++ к объекту в Java (это сравнительно легко), но что вы делаете с вашими структурами C ++? Или функции вне классов C ++? Решить, как с этим справиться, может быть сложно, так как это может привести к другой проблеме, а именно к созданию объекта BLOB-объекта. BLOB-объект является достаточно распространенным антипаттерном.
Это не полный список проблем, но их всего две, и они большие. Один из моих профессоров упомянул, что кто-то убедил его работодателя, что в 80-х годах он может сделать его из машинного кода в C, но тогда он не работал. Я сомневаюсь, что когда-нибудь будет тот, который работает полностью.
источник
Смысл компиляции - получить что-то полезное для компьютера. то есть то, что может работать. Зачем компилировать что-то, что может быть даже более высокого уровня, чем вы написали?
Мне больше нравится стратегия .NET. Скомпилируйте все на общий язык. Это дает возможность языкам общаться без необходимости создавать (N ^ 2) -N кросс-языковых компиляторов.
Например, если у вас было 10 языков программирования, вам нужно было бы написать только 10 компиляторов в соответствии с моделью .NET, и все они могли бы общаться друг с другом. Если бы вы сделали все возможные кросс-языковые компиляторы, вам нужно было бы написать 90 компиляторов. Это много дополнительной работы за небольшую выгоду.
источник