Какие виды шаблонов, которые я мог бы применить в коде, чтобы упростить перевод на другой язык программирования? [закрыто]

Я собираюсь выполнить побочный проект, целью которого является перевод кода с одного языка программирования на другой. Языки, на которых я начинаю с PHP и Python (с Python на PHP должно быть проще начать), но в идеале я мог бы добавить другие языки с (относительной) легкостью.План следующий:

  • Это ориентировано на веб-разработку. Исходный и целевой код будут находиться поверх фреймворков (которые мне также придется написать). Эти платформы будут охватывать шаблон проектирования MVC и следовать строгим соглашениям о кодировании. Это должно несколько упростить перевод.

  • Я также смотрю на IOC и внедрение зависимостей, поскольку они могут упростить процесс перевода и снизить вероятность ошибок.

  • Я воспользуюсь модулем синтаксического анализатора Python , который позволяет мне возиться с абстрактное синтаксическое дерево. По-видимому, самое близкое, что я могу получить с PHP, - это token_get_all () , что является началом.

  • С этого момента я могу создавать AST, таблицы символов и поток управления.

Тогда я могу начать выводить код. Мне не нужен идеальный перевод . Мне все равно придется просмотреть сгенерированный код и исправить проблемы. В идеале переводчик должен отмечать проблемные переводы.

Прежде чем вы спросите: «Какого черта в этом смысл?» Ответ ... Это будет интересный опыт обучения. Если у вас есть какие-либо идеи о том, как сделать это менее пугающим, дайте мне знать.


РЕДАКТИРОВАТЬ:

Мне больше интересно знать, какие типы шаблонов я могу применить в коде, чтобы упростить перевод (т. Е. : IoC, SOA?) Код, чем как сделать перевод.

95
задан JasonMArcher 1 August 2015 в 17:41
поделиться

5 ответов

Я создавал инструменты (DMS Software Reengineering Toolkit) для выполнения универсальных программных манипуляций (с языковым переводом как особый случай) с 1995 года при поддержке сильной команды компьютерных ученых. DMS обеспечивает общий синтаксический анализ, построение AST, таблицы символов, управление и анализ потока данных, применение правил перевода, регенерацию исходного текста с комментариями и т. Д., Все это параметризуется явными определениями компьютерных языков.

Для этого хорошо требуется огромное количество оборудования (особенно, если вы хотите иметь возможность делать это для нескольких языков в общем случае), а затем вам нужны надежные парсеры для языков с ненадежные определения (прекрасный пример тому - PHP).

Нет ничего плохого в том, что вы думаете о создании языкового переводчика или пытаетесь это сделать, но я думаю, вы сочтете это гораздо более сложной задачей для реальных языков, чем вы ожидаете. Мы потратили около 100 человеко-лет только на DMS и еще 6-12 месяцев на каждое «надежное» определение языка (включая то, которое мы с трудом создали для PHP), и гораздо больше для неприятных языков, таких как C ++. Это будет «адский опыт обучения»; это было для нас. (Возможно, вам будет интересен раздел технических статей на указанном выше веб-сайте, чтобы начать обучение).

Люди часто пытаются построить какой-то универсальный механизм, начиная с некоторой части технологии, с которой они знакомы, которая выполняет часть работы. (Python AST - отличный пример). Хорошая новость в том, что часть работы сделана.Плохая новость заключается в том, что в машину встроен миллион предположений, большинство из которых вы не обнаружите, пока не попытаетесь заставить его сделать что-то еще. В этот момент вы обнаруживаете, что механизм настроен на то, что он делает изначально, и будет действительно, очень сопротивляться вашей попытке заставить его делать что-то еще. (Я подозреваю, что попытка заставить Python AST моделировать PHP будет очень весело).

Причина, по которой я изначально начал создавать DMS, заключалась в том, чтобы построить фундамент, в котором было бы очень мало таких допущений. В нем есть некоторые, которые доставляют нам головную боль. Пока нет черных дыр. (Самая сложная часть моей работы за последние 15 лет - попытаться предотвратить появление таких предположений).

Многие люди также ошибаются, полагая, что, если они могут анализировать (и, возможно, получить AST), они хорошо на пути к выполнению чего-то сложного. Один из трудных уроков состоит в том, что вам нужны таблицы символов и анализ потоков, чтобы проводить хороший анализ или преобразование программы. AST необходимы, но недостаточны. Это причина того, что книга компиляторов Ахо и Уллмана не ограничивается главой 2. (ОП имеет на это право в том смысле, что он планирует построить дополнительные механизмы помимо AST). Для получения дополнительной информации по этой теме см. Жизнь после анализа .

Замечание о том, что «мне не нужен идеальный перевод», вызывает беспокойство. Что делают слабые переводчики, так это конвертируют «легкие» 80% кода, оставляя сложные 20% делать вручную. Если приложение, которое вы собираетесь преобразовать, довольно маленькое, и вы собираетесь преобразовать его только один раз, то эти 20% в порядке.Если вы хотите преобразовать много приложений (или даже одно с небольшими изменениями с течением времени), это нехорошо. Если вы попытаетесь преобразовать 100K SLOC, то 20% - это 20 000 исходных строк кода, которые трудно перевести, понять и изменить в контексте еще 80 000 строк переведенной программы, которую вы уже не понимаете. Это требует огромных усилий. На уровне миллиона строк это просто невозможно на практике. (Удивительно, но есть люди, которые не доверяют автоматизированным инструментам и настаивают на ручном переводе систем из миллионов строк; это даже сложнее , и они обычно обнаруживают мучительно с длительными задержками, высокими затратами и часто откровенным отказом.)

Для перевода крупномасштабных систем вам нужно стремиться к высокому процентному уровню конверсии девяностых годов, иначе вы, вероятно, не сможете выполнить ручную часть работы по переводу.

Еще одно важное соображение - это размер транслируемого кода. Даже с хорошими инструментами для создания работоспособного надежного переводчика требуется много энергии. Хотя создание переводчика вместо простого ручного преобразования кажется привлекательным и крутым, для небольших баз кода (например, примерно до 100 000 SLOC по нашему опыту) экономия просто не оправдывает этого. Никому не нравится этот ответ, но если вам действительно нужно перевести всего 10K SLOC кода, вам, вероятно, лучше просто укусить пулю и сделать это. И да, это больно.

Я считаю, что наши инструменты очень хороши (но я довольно пристрастен). А создать хорошего переводчика по-прежнему очень сложно; на это у нас уходит 1,5–2 человеко-года, и мы знаем, как использовать наши инструменты.Разница в том, что с таким количеством машин мы добиваемся успеха значительно чаще, чем терпим поражение.

119
ответ дан 24 November 2019 в 05:52
поделиться

Мой ответ будет касаться конкретной задачи синтаксического анализа Python, чтобы перевести его на другой язык, а не аспектов более высокого уровня, которые Ира хорошо рассмотрел в своем ответе.

Вкратце: не используйте модуль синтаксического анализатора, есть способ попроще.

Модуль ast , доступный с Python 2.6, гораздо больше подходит для ваших нужд, так как он дает вам готовый AST для работы. В прошлом году я написал статью об этом , но, вкратце, используйте метод parse из ast для синтаксического анализа исходного кода Python в AST. Модуль парсера предоставит вам дерево синтаксического анализа, а не AST. Остерегайтесь разницы .

Теперь, поскольку AST Python достаточно подробны, для данного AST работа внешнего интерфейса не так уж и сложна. Я полагаю, у вас может быть простой прототип для некоторых частей функциональности, готовый довольно быстро. Однако получение полного решения займет больше времени, в основном из-за разницы в семантике языков.Простое подмножество языка (функции, базовые типы и т. Д.) Можно легко перевести, но как только вы перейдете на более сложные уровни, вам понадобится тяжелая техника для имитации ядра одного языка в другом. Например, рассмотрим генераторы Python и списки, которые не существуют в PHP (насколько мне известно, что, по общему признанию, плохо, когда задействован PHP).

Чтобы дать вам последний совет, рассмотрим инструмент 2to3 , созданный разработчиками Python для перевода кода Python 2 в код Python 3. Что касается внешнего интерфейса, в нем есть большинство элементов, необходимых для перевода Python на что-то . Однако, поскольку ядра Python 2 и 3 схожи, никаких механизмов эмуляции там не требуется.

13
ответ дан 24 November 2019 в 05:52
поделиться

Есть пара ответов, которые советуют вам не беспокоить. Насколько это полезно? Ты хочешь учиться? Ты можешь выучить. Это компиляция. Так уж случилось, что ваш целевой язык - это не машинный код, а другой язык высокого уровня. Это происходит постоянно.

Есть относительно простой способ начать работу. Сначала возьмите http://sourceforge.net/projects/lime-php/ (если вы хотите работать на PHP) или что-то подобное и просмотрите пример кода. Затем вы можете написать лексический анализатор, используя последовательность регулярных выражений, и передать токены в сгенерированный вами синтаксический анализатор. Ваши семантические действия могут либо выводить код непосредственно на другом языке, либо создавать некоторую структуру данных (мыслить объекты, человек), которые вы можете массировать и перемещаться для генерации выходного кода.

Вам повезло с PHP и Python, потому что во многих отношениях это один и тот же язык, но с другим синтаксисом. Труднее всего преодолеть семантические различия между грамматическими формами и структурами данных. Например, в Python есть списки и словари, а в PHP - только ассоциативные массивы.

Подход «ученика» состоит в том, чтобы создать что-то, что нормально работает для ограниченного подмножества языка (например, только операторы печати, простую математику и присвоение переменных), а затем постепенно снимать ограничения. Это в основном то, что делали все "большие" ребята в этой области.

Да, и поскольку у вас нет статических типов в Python, может быть лучше написать и полагаться на функции PHP, такие как «python_add», которые добавляют числа, строки или объекты в соответствии с тем, как это делает Python.

Очевидно, это может стать намного больше, если вы позволите этому.

3
ответ дан 24 November 2019 в 05:52
поделиться

Вы можете взглянуть на компилятор Vala , который переводит Vala (язык, похожий на C #) на C.

0
ответ дан 24 November 2019 в 05:52
поделиться

Написать переводчика невозможно, особенно учитывая, что стажер Джоэла сделал это за лето.

Если вы хотите работать на одном языке, это легко. Если вы хотите сделать больше, это немного сложнее, но не слишком много. Самая сложная часть состоит в том, что, хотя любой полный язык по Тьюрингу может делать то же, что и другой полный язык по Тьюрингу, встроенные типы данных могут феноменально изменить то, что делает язык.

Например:

word = 'This is not a word'
print word[::-2]

требует партии кода C ++ для дублирования (хорошо, ну, вы можете сделать это довольно быстро с некоторыми конструкциями цикла, но все же).

Думаю, это немного отступление.

Вы когда-нибудь писали токенизатор / парсер на основе языковой грамматики? Вы, вероятно, захотите узнать, как это сделать, если вы этого не сделали, потому что это основная часть этого проекта. Я бы придумал базовый полный синтаксис Тьюринга - что-то очень похожее на байт-код Python . Затем вы создаете лексический анализатор / анализатор, который принимает грамматику языка (возможно, используя BNF ) и на основе грамматики компилирует язык в ваш промежуточный язык. Тогда вам нужно сделать обратное - создать синтаксический анализатор вашего языка на целевые языки на основе грамматики.

Самая очевидная проблема, которую я вижу, заключается в том, что сначала вы, вероятно, создадите ужасно неэффективный код, особенно на более мощных * языках, таких как Python.

Но если вы сделаете это таким образом, вы, вероятно, сможете найти способы оптимизации вывода по мере продвижения.Подводя итог:

  • прочтите предоставленную грамматику
  • скомпилируйте программу в промежуточный (но также полный по Тьюрингу) синтаксис
  • скомпилируйте промежуточную программу в конечный язык (на основе предоставленной грамматики)
  • ...?
  • Прибыль! (?)

* под мощным я имею в виду, что это занимает 4 строчки:

myinput = raw_input("Enter something: ")
print myinput.replace('a', 'A')
print sum(ord(c) for c in myinput)
print myinput[::-1]

Покажите мне другой язык, который может делать что-то подобное, в 4 строчках, и я покажу вам язык, столь же мощный, как Python.

5
ответ дан 24 November 2019 в 05:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: