Есть ли способ написать фронтэнд компилятора без использования синтаксически-ориентированного перевода? - PullRequest
3 голосов
/ 10 июля 2011

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

Ответы [ 2 ]

7 голосов
/ 10 июля 2011

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

По сути, действия по синтаксическому анализу должны создавать представление программы, которое является «более компилируемым». Я знаю только несколько основных методов:

  • Создание набора инструкций виртуальной машины
  • Создание абстрактного синтаксического дерева для передачи остальной части компилятора
  • Создание некоторого вида кода управления / потока данных (например, «тройки»)

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

Теперь текст является представлением программы. Вы можете полностью избежать процесса "разбора" (своего рода), если решите реализовать свой компилятор как систему Post, набор правил перезаписи над строками. Они имеют вид «если вы видите эту строку, замените ее другой строкой». Почтовые системы способны провоцировать Turing, поэтому технически вы можете преобразовать свой исходный код в строку, представляющую целевую программу, с достаточно умным набором правил переписывания строк. Никто из тех, кого я знаю, не создает настоящие компиляторы таким образом; Я уверен, что если вы будете копать достаточно усердно, вы сможете найти неясную техническую статью, которая делает это.

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

Интересно отметить, что системы трансформации программ (я строю одну из них на коммерческой основе) обычно используют внешний интерфейс компилятора для создания AST, а затем применяют перезаписи AST от дерева к дереву для достижения своей цели. Причина, по которой они построены таким образом, заключается в том, что они действительно представляют собой почтовые системы; любой AST для вашей программы может быть тривиально преобразован в строку (например, S-выражения), а древовидные преобразования могут быть преобразованы в эквивалентные строковые преобразования. Таким образом, система переписывания деревьев - это просто система Post, но она делает ее очень мощной. Конечно, можно объединить эту возможность с другими более традиционными методами компилятора, что мы и делаем с нашим продуктом. Это делает это более удобным; Вы не должны делать все как почтовую систему.

0 голосов
/ 11 июля 2011

То, что вы описываете, на самом деле является стандартной конструкцией компилятора. Можно написать однопроходные компиляторы, и, действительно, я это сделал, которые генерируют объектный код во время синтаксического анализа, но норма для синтаксического анализатора - AST, а для последующего обхода AST - либо для вывода, либо во многих случаях дополнительная промежуточная форма, такая как тройки, RTL и т. д.

...