Какие типы шаблонов я могу применить в коде, чтобы было проще переводить на другой язык программирования?
Я собираюсь сделать побочный проект, целью которого является перевод кода с одного языка программирования на другой. Языки, с которых я начинаю, - это PHP и Python (с Python по PHP должно быть легче начать), но в идеале я мог бы добавить другие языки с (относительной) легкостью. План такой:
Это ориентировано на веб-разработку. Исходный и целевой код будут лежать поверх фреймворков (которые мне также придется написать). Эти структуры будут включать в себя шаблон проектирования MVC и следовать строгим соглашениям о кодировании. Это должно облегчить перевод.
Я также смотрю на IOC и внедрение зависимостей, поскольку они могут сделать процесс перевода более простым и менее подверженным ошибкам.
Я воспользуюсь модулем парсера Python, который позволяет мне возиться с абстрактным синтаксическим деревом. По-видимому, ближе всего я могу получить с PHP это token_get_all (), который является началом.
С тех пор я могу строить AST, таблицы символов и поток управления.
Тогда я верю, что могу начать выводить код. Мне не нужен идеальный перевод. Мне все еще придется просмотреть сгенерированный код и исправить проблемы. В идеале переводчик должен отмечать проблемные переводы.
Прежде чем спросить: "Какого черта, в чем смысл этого?" Ответ... Это будет интересный опыт обучения. Если у вас есть какие-либо идеи о том, как сделать это менее пугающим, пожалуйста, дайте мне знать.
РЕДАКТИРОВАТЬ:
Меня больше интересует, какие типы шаблонов я мог бы применить в коде, чтобы упростить перевод (то есть: IoC, SOA?) Код, чем как выполнять перевод.
6 ответов
С 1995 года я создаю инструменты (DMS Software Reengineering Toolkit) для управления программами общего назначения (в частности, языковым переводом), поддерживаемый сильной командой компьютерных специалистов. DMS обеспечивает общий синтаксический анализ, построение AST, таблицы символов, контроль и анализ потока данных, применение правил перевода, восстановление исходного текста с комментариями и т. Д., Все из которых параметризованы явными определениями компьютерных языков.
Количество механизмов, которые вам нужны для этого, огромно (особенно, если вы хотите сделать это для нескольких языков в общем виде), а затем вам нужны надежные парсеры для языков с ненадежными определениями (PHP является прекрасным примером этого).
Нет ничего плохого в том, что вы думаете о том, чтобы создать переводчик с языка на язык или попробовать его, но я думаю, что для реальных языков это будет гораздо более сложной задачей, чем вы ожидаете. У нас есть около 100 человеко-лет, потраченных только на DMS, и еще 6–12 месяцев на каждое "надежное" определение языка (включая то, которое мы мучительно создали для PHP), и гораздо больше на неприятные языки, такие как C++. Это будет "адский опыт обучения"; это было для нас. (Вы можете найти раздел технических документов на вышеуказанном веб-сайте интересным для начала обучения).
Люди часто пытаются создать какой-то обобщенный механизм, начав с некоторой технологии, с которой они знакомы, которая выполняет часть работы. (Python AST - отличный пример). Хорошей новостью является то, что часть работы выполнена. Плохая новость заключается в том, что в механизме заложено множество предположений, большинство из которых вы не откроете, пока не попытаетесь заставить его заняться чем-то другим. В этот момент вы обнаруживаете, что механизм подключен к тому, что он делает изначально, и будет действительно противостоять вашей попытке заставить его делать что-то еще. (Я подозреваю, что попытка заставить Python AST моделировать PHP будет очень интересной).
Причиной, по которой я начал создавать DMS, было создание основ, в которых было заложено очень мало таких предположений. Некоторые из них вызывают головную боль. Пока что черных дыр нет. (Самая трудная часть моей работы за последние 15 лет - попытаться предотвратить распространение таких предположений).
Многие люди также делают ошибку, полагая, что, если они смогут анализировать (и, возможно, получить AST), они находятся на пути к выполнению чего-то сложного. Один из трудных уроков заключается в том, что вам нужны таблицы символов и анализ потока, чтобы выполнить хороший анализ или преобразование программы. AST необходимы, но не достаточны. Это причина того, что книга компиляторов Aho&Ullman не останавливается на главе 2. (У ОП есть это право в том смысле, что он планирует построить дополнительное оборудование помимо AST). Для получения дополнительной информации по этой теме см. Жизнь после разбора.
Замечание о "мне не нужен идеальный перевод" вызывает беспокойство. Что делают слабые переводчики, так это конвертируют "простые" 80% кода, оставляя трудные 20% вручную. Если приложение, которое вы намереваетесь конвертировать, довольно маленькое, и вы собираетесь конвертировать его только один раз, тогда эти 20% - это нормально. Если вы хотите конвертировать много приложений (или даже одно и то же с незначительными изменениями со временем), это не очень удобно. Если вы попытаетесь преобразовать 100K SLOC, то 20% - это 20000 оригинальных строк кода, которые трудно перевести, понять и изменить в контексте еще 80000 строк переведенной программы, которую вы уже не понимаете. Это требует огромных усилий. На уровне миллионов строк это просто невозможно на практике. (Удивительно, что есть люди, которые не доверяют автоматизированным инструментам и настаивают на том, чтобы вручную переводить миллионы линейных систем; это еще сложнее, и они обычно сталкиваются с болезненными проблемами из-за длительных задержек, высоких затрат и часто просто неудач).
Для перевода крупномасштабных систем вам нужно сделать ставку на высокий процент конверсии в девяностых, или, скорее всего, вы не сможете выполнить ручную часть перевода.
Еще одним ключевым фактором является размер кода для перевода. Требуется много энергии, чтобы построить работающий, надежный переводчик, даже с хорошими инструментами. В то время как создание переводчика кажется просто и круто, а не просто выполнять ручное преобразование, для небольших баз кода (например, до 100K SLOC в нашем опыте) экономика просто не оправдывает этого. Никто не любит этот ответ, но если вам действительно нужно перевести всего 10K SLOC кода, вам, вероятно, лучше просто кусать пулю и делать это. И да, это больно.
Я считаю наши инструменты очень хорошими (но при этом я довольно предвзятый). И все еще очень трудно построить хорошего переводчика; у нас уходит около 1,5-2 человеко-лет, и мы знаем, как использовать наши инструменты. Разница в том, что с таким большим количеством машин мы преуспеваем значительно чаще, чем проваливаемся.
Мой ответ будет посвящен конкретной задаче синтаксического анализа Python с целью перевода его на другой язык, а не аспектам более высокого уровня, на которые Ира хорошо ответила в своем ответе.
Короче говоря: не используйте модуль парсера, есть более простой способ.
ast
Модуль, доступный начиная с Python 2.6, гораздо больше подходит для ваших нужд, поскольку предоставляет готовый AST для работы. Я написал статью об этом в прошлом году, но вкратце, используйте parse
метод ast
разобрать исходный код Python в AST. parser
Модуль даст вам дерево разбора, а не AST. Остерегайтесь разницы.
Теперь, так как AST в Python достаточно подробны, с учетом AST работа с интерфейсом не так уж сложна. Я полагаю, у вас может быть простой прототип для некоторых частей функциональности, готовый довольно быстро. Однако нахождение полного решения займет больше времени, главным образом потому, что семантика языков различна. Простое подмножество языка (функции, основные типы и т. Д.) Может быть легко переведено, но как только вы перейдете на более сложные уровни, вам понадобится тяжелая техника для эмуляции ядра одного языка в другом. Например, рассмотрим генераторы Python и списки, которые не существуют в PHP (насколько мне известно, что, по общему признанию, плохо, когда задействован PHP).
Чтобы дать вам последний совет, рассмотрим 2to3
инструмент, созданный разработчиками Python для перевода кода Python 2 в код Python 3. Во внешнем интерфейсе он содержит большинство элементов, необходимых для перевода Python во что-то. Однако, поскольку ядра Python 2 и 3 похожи, эмуляция там не требуется.
Написание переводчика не является невозможным, особенно если учесть, что стажер Джоэла делал это летом.
Если вы хотите сделать один язык, это легко. Если вы хотите сделать больше, это немного сложнее, но не слишком много. Самое сложное в том, что, хотя любой полный язык тьюринга может делать то же, что делает другой полный язык тьюринга, встроенные типы данных могут изменить то, что язык делает феноменально.
Например:
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.
Есть пара ответов, говорящих вам не беспокоиться. Ну, насколько это полезно? Ты хочешь учиться? Ты можешь научиться. Это сборник. Так получилось, что ваш целевой язык не машинный код, а другой язык высокого уровня. Это делается постоянно.
Есть относительно простой способ начать. Во-первых, найдите http://sourceforge.net/projects/lime-php/ (если вы хотите работать в PHP) или что-то в этом роде и пройдите через пример кода. Затем вы можете написать лексический анализатор, используя последовательность регулярных выражений и токенов фида в генерируемый вами анализатор. Ваши семантические действия могут либо выводить код непосредственно на другом языке, либо создавать некоторую структуру данных (объекты мышления, человек), которую вы можете обрабатывать и обрабатывать для генерации выходного кода.
Вам повезло с PHP и Python, потому что во многих отношениях они являются одним и тем же языком, но с разным синтаксисом. Сложная часть заключается в преодолении семантических различий между грамматическими формами и структурами данных. Например, в Python есть списки и словари, а в PHP - только ассоциированные массивы.
Подход "ученик" состоит в том, чтобы создать что-то, что работает нормально для ограниченного подмножества языка (такого как только операторы печати, простая математика и назначение переменных), и затем постепенно снимать ограничения. Это в основном то, что делали "большие" парни на местах.
Да, и поскольку у вас нет статических типов в Python, возможно, лучше написать и использовать функции PHP, такие как "python_add", которые добавляют числа, строки или объекты в соответствии с тем, как это делает Python.
Очевидно, что это может стать намного больше, если вы позволите.
Я поддержу точку зрения @EliBendersky относительно использования ast.parse вместо парсера (о котором я раньше не знал). Я также настоятельно рекомендую вам ознакомиться с его блогом. Я использовал ast.parse, чтобы сделать Python->JavaScript-переводчик (@ https://bitbucket.org/amirouche/pythonium). Я придумал дизайн Pythonium, несколько пересмотрев другие реализации и попробовав их самостоятельно. Я разветвлял Pythonium с https://github.com/PythonJS/PythonJS который я тоже начал. На самом деле это полное переписывание. Общий дизайн основан на статье PyPy и http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-89-1.pdf.
Все, что я пробовал, от начала до лучшего решения, даже если это выглядит как маркетинг Pythonium, на самом деле это не так (не стесняйтесь, скажите мне, если что-то не так в сетевом этикете):
Реализация семантики Python в простом старом JavaScript с использованием наследования прототипа: AFAIK Невозможно реализовать множественное наследование Python с использованием объектной системы-прототипа JS. Я попробовал сделать это позже, используя другие приемы (см. Getattribute). Насколько я знаю, в JavaScript нет реализации множественного наследования Python, лучшее, что существует, - это Single legtance + mixins, и я не уверен, что они обрабатывают алмазное наследование. Вид, похожий на Skulpt, но без Google Clojure.
Я попытался с Google Clojure, так же, как Skulpt (компилятор) вместо того, чтобы фактически читать код Skulpt #fail. Во всяком случае, из-за прототипа JS объектная система по-прежнему невозможна. Создание привязки было очень очень сложным, вам нужно написать JavaScript и много стандартного кода (см. https://github.com/skulpt/skulpt/issues/50 где я являюсь призраком). В то время не было четкого способа интегрировать привязку в систему сборки. Я думаю, что Skulpt - это библиотека, и вам просто нужно включить ваши файлы.py в html для выполнения, и разработчик не должен выполнять этап компиляции.
Попробовал pyjaco (компилятор), но создание привязок (вызов кода Javascript из кода Python) было очень трудным, слишком много шаблонного кода для создания каждый раз. Теперь я думаю, что Pyjaco больше похож на Pythonium. pyjaco написан на Python (также ast.parse), но многое написано на JavaScript и использует наследование прототипов.
Мне никогда не удавалось запустить пижаму #fail, и я никогда не пытался снова прочитать код #fail. Но, по-моему, пижама делала перевод API->API (или фреймворк на фреймворк), а не перевод с Python на JavaScript. Платформа JavaScript использует данные, которые уже находятся на странице, или данные с сервера. Код Python - это всего лишь "слесарное дело". После этого я обнаружил, что пижама на самом деле является настоящим переводчиком python-> js.
Тем не менее, я думаю, что возможно сделать перевод API->API (или framework->framework), и это в основном то, что я делаю в Pythonium, но на более низком уровне. Вероятно, пижамы используют тот же алгоритм, что и Pythonium...
Затем я обнаружил, что brython полностью написан на Javascript, как Skulpt, нет необходимости в компиляции и много пуха... но написан на JavaScript.
Так как начальная строка была написана в ходе этого проекта, я знал о PyPy, даже о JavaScript-бэкенде для PyPy. Да, вы можете, если найдете, напрямую сгенерировать интерпретатор Python в JavaScript из PyPy. Люди говорят, что это была катастрофа. Я не читал, где, почему. Но я думаю, что причина в том, что промежуточный язык, который они используют для реализации интерпретатора, RPython, является подмножеством Python, специально предназначенным для перевода на C (и, возможно, asm). Ира Бакстер говорит, что вы всегда делаете предположения, когда создаете что-то, и, вероятно, вы точно настраиваете его, чтобы быть лучшим в том, что оно должно делать в случае перевода PyPy: Python->C. Эти предположения могут быть неактуальными в другом контексте, хуже, чем они могут означать накладные расходы, в противном случае прямой перевод, скорее всего, всегда будет лучше.
Перевод интерпретатора на Python звучит как (очень) хорошая идея. Но я больше интересовался компилятором по соображениям производительности, и на самом деле проще компилировать Python в JavaScript, чем интерпретировать его.
Я начал PythonJS с идеей собрать подмножество Python, которое я мог бы легко перевести на JavaScript. Сначала я даже не удосужился внедрить ОО систему из-за прошлого опыта. Подмножество Python, которое мне удалось перевести на JavaScript:
- функция с полными семантическими параметрами как в определении, так и в вызове. Это та часть, которой я больше всего горжусь.
- в то время как / если / Элиф / другое
- Типы Python были преобразованы в типы JavaScript (нет никаких типов Python)
- for может перебирать только массивы Javascript (для массива in)
- Прозрачный доступ к JavaScript: если вы напишите Array в коде Python, он будет переведен в Array в javascript. Это самое большое достижение с точки зрения удобства использования по сравнению с конкурентами.
- Вы можете передать функцию, определенную в исходном коде Python, в функции javascript. Параметры по умолчанию будут приняты во внимание.
- Он добавляет специальную функцию new, которая переводится в JavaScript new. Например: new(Python)(1, 2, spam, "egg") переводится как "new Python (1, 2, spam," egg ").
- "var" автоматически обрабатывается переводчиком. (очень хорошая находка от Бретта (автора PythonJS).
- глобальное ключевое слово
- укупорочные
- лямбды
- список пониманий
- импорт поддерживается через requirejs
- наследование одного класса + mixin через classyjs
Это выглядит много, но на самом деле очень узко по сравнению с полноценной семантикой Python. Это действительно JavaScript с синтаксисом Python.
Сгенерированный JS является идеальным, т.е. нет никаких накладных расходов, их нельзя улучшить с точки зрения производительности путем дальнейшего редактирования. Если вы можете улучшить сгенерированный код, вы можете сделать это и из исходного файла Python. Кроме того, компилятор не полагался на какие-либо трюки JS, которые вы можете найти в.js, написанном http://superherojs.com/, поэтому он очень удобочитаем.
Прямым потомком этой части PythonJS является режим Pythonium Veloce. Полная реализация может быть найдена в @ https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/veloce/veloce.py?at=master 793 SLOC + около 100 SLOC общего кода с другим переводчиком.
Адаптированная версия pystones.py может быть переведена в режиме Veloce, см. https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pystone/?at=master
После настройки базового перевода Python->JavaScript я выбрал другой путь для перевода полного Python в JavaScript. Способ glib для создания объектно-ориентированного кода, основанного на классах, за исключением целевого языка, - это JS, так что у вас есть доступ к массивам, объектам, подобным карте, и многим другим трюкам, а также ко всей этой части, написанной на Python. IIRC нет никакого кода javascript, написанного в переводчике Pythonium. Получить одиночное наследование несложно. Вот те трудные части, которые делают Pythonium полностью совместимым с Python:
spam.egg
в Python всегда переводится наgetattribute(spam, "egg")
Я не описывал это, в частности, но я думаю, что там, где это теряет много времени, я не уверен, что смогу улучшить это с помощью asm.js или чего-то еще.- порядок разрешения методов: даже с помощью алгоритма, написанного на Python, его перевод на Python Veloce-совместимый код был большой задачей.
- getattributre: фактический алгоритм разрешения getattribute довольно сложен и не поддерживает дескрипторы данных
- основанный на классе метаклассов: я знаю, где подключить код, но все же...
- последнее, но не менее важное: some_callable(...) всегда переводится в "call(some_callable)". AFAIK переводчик вообще не использует умозаключения, поэтому каждый раз, когда вы делаете вызов, вам нужно проверить, какой это объект, чтобы называть его так, как он должен быть вызван.
Эта часть учтена в https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/runtime.py?at=master Она написана на Python, совместимом с Python Veloce.
Фактически совместимый переводчик https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/compliant.py?at=master не генерирует код JavaScript напрямую и, что наиболее важно, не выполняет преобразования ast->ast, Я попробовал ast->ast и ast, даже если лучше, чем cst, не очень приятно работать даже с ast.NodeTransformer и, что более важно, мне не нужно делать ast->ast.
Выполнение python ast в python ast в моем случае, по крайней мере, может быть улучшением производительности, поскольку я когда-нибудь проверяю содержимое блока, прежде чем генерировать код, связанный с ним, например:
- var / global: чтобы иметь возможность что-то изменять, я должен знать, что мне нужно, а не изменять. Вместо того, чтобы генерировать блок, отслеживающий, какая переменная создается в данном блоке, и вставлять его поверх сгенерированного функционального блока, я просто ищу присвоение переменной, когда я вхожу в блок, прежде чем фактически посетить дочерний узел, чтобы сгенерировать связанный код.
- В общем, генераторы имеют специальный синтаксис в JS, поэтому мне нужно знать, какая функция Python является генератором, когда я хочу написать "var my_generator = function"
Поэтому я не посещаю каждый узел по одному разу для каждой фазы перевода.
Общий процесс может быть описан как:
Python source code -> Python ast -> Python source code compatible with Veloce mode -> Python ast -> JavaScript source code
Встроенные Python написаны в коде Python (!), IIRC имеет несколько ограничений, связанных с типами начальной загрузки, но у вас есть доступ ко всему, что может перевести Pythonium в режим совместимости. Загляните на https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/builtins/?at=master
Чтение JS-кода, сгенерированного из Pythonium-совместимого, можно понять, но исходные карты очень помогут.
В свете этого опыта я могу дать вам ценный совет: старые добрые пердуны:
- Обширный обзор предмета как в литературе, так и в существующих проектах закрытого источника или бесплатно. Когда я рассмотрел различные существующие проекты, я должен был уделить этому больше времени и мотивации.
- задавать вопросы! Если бы я знал заранее, что бэкэнд PyPy был бесполезен из-за издержек из-за семантического несоответствия C/Javascript. Возможно, у меня была идея с Pythonium раньше, чем 6 месяцев назад, может быть, 3 года назад.
- знай, что ты хочешь делать, имей цель. Для этого проекта у меня были разные цели: немного поработать над javascript, узнать больше о Python и уметь писать код на Python, который будет работать в браузере (подробнее об этом ниже).
- неудача это опыт
- маленький шаг есть шаг
- начать с малого
- большая мечта
- делать демонстрации
- повторять
Только с режимом Python Veloce я очень счастлив! Но по пути я обнаружил, что то, что я действительно искал, - это освобождение меня и других от Javascript, но, что более важно, возможность создавать комфортно. Это привело меня к Scheme, DSL, Models и, в конечном итоге, к моделям, специфичным для предметной области (см. http://dsmforum.org/).
О чем Ира Бакстер ответит:
Оценки не помогают вообще. Я потратил более или менее 6 месяцев свободного времени на PythonJS и Pythonium. Так что я могу ожидать большего от полного рабочего дня 6 месяцев. Я думаю, что мы все знаем, что 100 человеко-год в контексте предприятия могут означать, а вовсе не означать...
Когда кто-то говорит, что что-то трудно или чаще невозможно, я отвечаю, что "требуется только время, чтобы найти решение проблемы, которая невозможна", в противном случае говорят, что нет ничего невозможного, кроме случаев, когда доказано невозможность в этом случае математического доказательства...
Если это не доказано невозможным, тогда это оставляет место для воображения:
- найти доказательство того, что это невозможно
а также
- Если это невозможно, может быть "неполноценная" проблема, которая может иметь решение.
или же
- если это не невозможно, найти решение
Это не просто оптимистичное мышление. Когда я запускал Python->Javascript, все говорили, что это невозможно. PyPy невозможно. Метаклассы слишком сложные. и т. д. Я думаю, что единственная революция, которая приводит PyPy к статье Scheme->C (которой 25 лет), - это автоматическое генерирование JIT (на мой взгляд, на основе подсказок, написанных в интерпретаторе RPython).
Большинство людей, которые говорят, что вещь "трудная" или "невозможная", не называют причины. С ++ сложно разобрать? Я знаю, что они все еще (бесплатные) C++ парсер. Зло в деталях? Я знаю это. Сказать, что невозможно в одиночку, не полезно, это даже хуже, чем "не полезно", это обескураживает, и некоторые люди хотят отговорить других. Я слышал об этом вопросе через https://stackru.com/questions/22621164/how-to-automatically-generate-a-parser-code-to-code-translator-from-a-corpus.
Что было бы для вас совершенством? Так вы определяете следующую цель и, возможно, достигаете общей цели.
Меня больше интересует, какие типы шаблонов я мог бы применить в коде, чтобы упростить перевод (то есть: IoC, SOA?) Код, чем как выполнять перевод.
Я не вижу шаблонов, которые нельзя перевести с одного языка на другой язык хотя бы менее чем идеально. Так как перевод с языка на язык возможен, лучше сначала нацелиться на него. Так как, я думаю, согласно http://en.wikipedia.org/wiki/Graph_isomorphism_problem, перевод между двумя компьютерными языками - это дерево или изоморфизм DAG. Даже если мы уже знаем, что они оба завершены, так что...
Framework-> Framework, который я лучше визуализирую как API-> API-перевод, может быть тем, что вы можете иметь в виду, как способ улучшить сгенерированный код. Например: Пролог как очень специфический синтаксис, но вы все равно можете выполнять вычисления, подобные Прологу, описывая тот же граф на Python... Если бы я должен был реализовать переводчик с Пролога на Python, я бы не реализовал объединение в Python, но в библиотеке C и пришел с "синтаксисом Python", который очень удобочитаем для Pythonist. В конце концов, синтаксис - это только "рисование", для которого мы придаем смысл (именно поэтому я и начал схему). Зло в деталях языка, и я не говорю о синтаксисе. Концепции, которые используются в хуке языка getattribute (вы можете жить без него), но требуются такие функции виртуальной машины, как оптимизация хвостовой рекурсии, могут быть трудны для понимания. Вам все равно, если исходная программа не использует хвостовую рекурсию, и даже если на целевом языке нет хвостовой рекурсии, вы можете эмулировать ее с помощью цикла greenlets / event.
Для целевых и исходных языков ищите:
- Большие и конкретные идеи
- Крошечные и общие общие идеи
Из этого выйдет:
- Вещи, которые легко перевести
- Вещи, которые трудно перевести
Вы также, вероятно, сможете узнать, что будет переведено в быстрый и медленный код.
Есть также вопрос о stdlib или любой библиотеке, но нет четкого ответа, это зависит от ваших целей.
Идиоматический код или читаемый сгенерированный код также имеют решения...
Ориентироваться на платформу, такую как PHP, гораздо проще, чем на браузеры, поскольку вы можете обеспечить C-реализацию медленного и / или критического пути.
Поскольку ваш первый проект переводит Python на PHP, по крайней мере, для подмножества PHP3, о котором я знаю, настройка veloce.py - ваш лучший выбор. Если вы можете реализовать veloce.py для PHP, то, вероятно, вы сможете запустить режим совместимости... Также, если вы можете перевести PHP в подмножество PHP, которое вы можете сгенерировать с помощью php_veloce.py, это означает, что вы можете перевести PHP в подмножество Python, которое может использовать veloce.py, что будет означать, что вы можете перевести PHP в Javascript. Просто говорю...
Вы также можете взглянуть на эти библиотеки:
Также вам может быть интересно это сообщение в блоге (и комментарии): https://www.rfk.id.au/blog/entry/pypy-js-poc-jit/
- Этот Google Tech Talk от Айры Бакстер интересен https://www.youtube.com/watch?v=C-_dw9iEzhA
Вы можете взглянуть на компилятор Vala, который переводит Vala (C#-подобный язык) на C.