Да, вы можете иметь процедурный API для перевода исходного кода на источник. В абстрактной форме это довольно просто: определите основную структуру данных для представления узлов AST, затем определите API для «анализа файла в AST», «посещать узлы дерева», «проверить узлы дерева», «изменить узлы дерева», «выплюнуть» текст". Они становятся беспорядочными в конкретном, особенно если API специфичен для перевода языка; слишком много деталей этого языка попадают в API. В то время как традиционный, это действительно довольно неуклюжий способ определить переводчиков источника в источник, потому что тогда вам нужно написать тонны процедурного кода, вызывающего API, чтобы сделать перевод.
Вы можете определить их с помощью program transformation system (PTS) с использованием преобразования источника-источника на основе поверхностного синтаксиса; это шаблоны, написанные с использованием обозначений вашего скомпилированного языка и вашего целевого языка в форме «если вы видите этот, а затем замените его на , что», работающий на деревьях синтаксиса, а не на текстовые строки , Это означает, что вы можете проверить трансформации, просто глядя на них. Так может и ваш коллега программист.
правило один такой перевод может выглядеть следующим образом:
rule tranlate_add_to(t: access_path, u: access_path):COBOL -> Java
" add \t to \u "
-> " \object_for\(\u\).\u += \object_for\(\t\).\t; ";
с левой стороны «добавить \ т к \ и» указать фрагмент COBOL (это), чтобы заменить правой side "\ object_for ...", представляющий соответствующий Java-код (, который). Это правило использует вспомогательную функцию «object_for», чтобы решить, где в целевой Java-программе будет размещена глобальная переменная в исходной программе COBOL. (Нельзя писать такую функцию, если вы переводите Java на COBOL. Вы можете спорить о том, насколько сложны). На практике способ, которым работает такое правило, заключается в построении шаблонов АСТ каждой стороны, а затем шаблоны сопоставляются с анализируемым АСТ; совпадение приводит к объединению соответствующего поддерева на место, где совпадение было найдено. (Все эти сопоставления дерева с низким уровнем и сплайсинг должны быть выполнены ... процедурно, но кто-то еще уже реализовал это в PTS).
По нашему опыту, вам необходимо one to two thousand such rules to translate one language to another. Множество правил исходит из комбинаторики конструкций синтаксиса языка для исходного языка (и их, возможно, разных интерпретаций в соответствии с типами; «a + b» означает разные вещи, когда a является int vs, когда a является строкой) и целевым языком возможностей. Хорошим плюсом таких переписываний является то, что можно построить несколько более простой базовый перевод и применить дополнительные перезаписи с целевого языка к себе, чтобы очистить и оптимизировать переведенный результат.
Многие PTS основаны исключительно на перезаписываемых синтаксисах источника-источника.Мы обнаружили, что объединение как PTS, так и процедурного API, а также возможность переходов между ними делают очень приятным инструментом: вы можете использовать переписывающие приложения, где это удобно, и процедурные API, где они не работают так хорошо ("object_for" функция, предложенная выше, проще кодировать как процедуру).
Подробнее о том, как наши кодирует такие правила преобразования (тот, что выше, является кодом в стиле DMS), в языке агностик (ну, параметризованный). DMS предлагает «чистый» процедурный API, как запрошенный OP с некоторыми 400 функциями, но DMS рекомендует своим пользователям сильно опираться на перезаписи и только код, по мере необходимости, снова процедурный API. Было бы «прямолинейно» (по крайней мере так же просто, как практично), чтобы построить свою «4-языковую поддержку» таким образом.
Не стоит недооценивать объем усилий по созданию таких переводчиков, даже с большим количеством хорошей технической техники в качестве фундамента. Лангауги, как правило, являются сложными животными, и их переводы вдвойне. И вам нужно решить, хотите ли вы truly crummy translation или хороший.
Похоже, что вам нужно сначала построить компилятор 101. Вы, конечно, не найдете API для этого. Первое, что вам понадобится, это грамматика для исходных и целевых языков. В этой области есть коммерческие продукты. Нелегкое задание. – EJP
Итак, истинно, я собираюсь использовать некоторый онлайн-класс. Спасибо @EJP – Redcode
Если вас интересует преобразование кода (например, в C, C++, Fortran, Ada, ...), скомпилированном [GCC] (http: //gcc.gnu .org /) для этой цели вы можете использовать [MELT] (http://gcc-melt.org/). Но вам нужно понять внутренние представления GCC. –