AST, который моделирует все семантические детали исходного языка - это все, что вам нужно.По определению, если он правильно моделирует семантику, а ваш язык содержит троичный оператор, то он также будет корректно моделировать конкретный порядок, в котором применяются операторы (например, результаты переопределений по модулю, такие как скобки).
Так что ваша проблема не в AST.Он генерируется на другом языке с использованием аналогичных (троичных) операторов, приоритет которых отличается.
Это давняя проблема в генерации кода: операторы цели не совсем соответствуют операторам источника,и поэтому вывод не может быть один к одному.В вашем случае вы сможете решить эту проблему, создавая троичные операторы PHP с круглыми скобками для управления порядком достижения исходной семантики, так что это не большая проблема.
В общем случаеГенерация последовательностей кода, которые достигают желаемого результата, может быть довольно сложной, и есть много способов сделать это.Вот почему книги компиляторов скорее толстые, чем тонкие.Вы, кажется, неявно остановились на «получить AST, пройти AST, плюнуть код»;это практически генератор кода на лету.И это работает адекватно, если вам все равно, является ли сгенерированный код особенно хорошим, а целевой язык довольно близок к исходному языку.
Если проблема с генерацией кода более сложная, обычно происходит следующее:AST используется для генерации того, что составляет модель потока данных вычислений, состоящая из операторов, которые производят результаты и используют результаты предыдущих операторов, основываясь на «операторах», которые выбирают значения и константы переменных.Затем выполняется представление потока данных для генерации кода;Преимущество этого заключается в том, что вы можете выбрать оператор в представлении потока данных, найти соответствующую кодовую последовательность на целевом языке, сгенерировать ее, а затем беспокоиться о том, как собираются операнды.Более совершенные схемы сопоставляют подграфы потока данных (представляющие эквивалентные составные конструкции целевого языка) с созданным графом потока данных;это может дать значительно лучший код.Часто можно применять специфические оптимизации для целевого языка после генерации исходного кода, чтобы получить еще лучший код.В обоих случаях вам нужно беспокоиться об управлении результатами оператора;могут ли они быть переданы непосредственно следующему оператору целевого языка, или они должны войти в какое-то временное хранилище (для машинного кода это может быть другой регистр или ячейка памяти).Делать все это не легко;опять же, именно поэтому книги по компиляторам не такие уж и тонкие.
Разновидностью этой идеи являются преобразования программ из исходного кода в исходный.Это сопоставляет конструкции в исходном коде «напрямую» с конструкциями в целевом коде, хотя это обычно делается за кулисами при работе с AST, поскольку трудно разбирать текст на непарсированном языке программирования.Наш DMS Software Reengineering Toolkit является примером такой системы.С помощью такого инструмента вы пишете шаблоны на исходном языке (которые неявно совпадают с деревом разбора) и соответствующие шаблоны на целевом языке (неявно производя AST на целевом языке).Вы можете написать сложные исходные или целевые конструкции, дающие большую часть эффекта сопоставления графа потока данных выше.Оптимизация после генерации состоит из большего количества правил переписывания, которые преобразуют целевой код в целевой код.
Итог: наличие AST на самом деле недостаточно, если ваш перевод не является действительно тривиальным.Вы можете прочитать больше о том, что вам нужно, в этом SO-ответе: https://stackoverflow.com/a/3460977/120163
ВНИМАНИЕ: следует громкое мнение.
Re "Транскодер": я очень предпочитаю термины "компиляция", "перевод" или "источник к источнику" компилятор.Я создавал инструменты анализа и манипулирования программами почти 40 лет.Я никогда не слышал термин «транскодер», пока не столкнулся с таким вопросом: Опыт миграции устаревшего Cobol / PL1 на Java и ответ, описывающий IMHO действительно ужасную схему перевода кода под названием NACA.С тех пор я слышал, что этот термин набирает силу;Я не понимаю, почему мы должны были изобрести другой термин, когда у нас есть совершенно адекватные.Обычно это признак того, что кто-то изобретает первосвященство;«Давайте изобретем новый блестящий термин, чтобы люди не понимали, что мы делаем».Я счастлив оставить этот термин в таких по-настоящему ужасных переводах.