Должен ли я написать компилятор языка Direct3D Shader Model, используя flex / yacc? - PullRequest
0 голосов
/ 10 февраля 2010

Я собираюсь создать компилятор для языка модели шейдеров Direct3D. Целевая платформа компилятора и среда разработки находятся на Windows / VC ++. Для тех, кто не знаком с языком моделей шейдеров, вот примеры инструкций, из которых состоит язык (некоторые инструкции немного устарели, но синтаксис в основном такой же, как и версия, которую я буду использовать).

Здесь

А здесь

Я рассматриваю flex / yacc как основу для разработки компилятора. Подходят ли они для работы? Есть ли лучшая платформа для разработки на родном C ++?

1 Ответ

3 голосов
/ 11 февраля 2010

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

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

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

Конечно, есть несколько мест, с которыми он должен справиться. Где / когда вы определяете что-то вроде метки, оно должно записывать название и позицию этой метки в таблице символов. Когда он сталкивается с чем-то вроде ответвления по этому адресу, он должен найти цель и соответствующим образом закодировать свой адрес.

Только когда / если вы решите поддерживать макросы, вы сильно отойдете от этой базовой модели. В зависимости от того, насколько тщательно вы их освоите, может быть целесообразно использовать генератор синтаксических анализаторов и тому подобное для средства расширения макросов. Опять же, учитывая, что шейдеры в основном довольно маленькие, макросы вряд ли будут иметь высокий приоритет для такого ассемблера.

Редактировать: перечитывая его, я, вероятно, должен уточнить / исправить одну точку. Использование генератора синтаксического анализатора не так много, когда сама грамматика становится сложной, как когда грамматика допускает сложные операторы. Рассмотрим действительно тривиальную грамматику:

expression := expression '+' value
            | expression '-' value
            | value

Несмотря на то, что это допускает только сложение и вычитание, оно все же определяет операторы, которые являются произвольно сложными (или, по крайней мере, произвольно длинные строки значений, которые добавляются или вычитаются). Конечно, даже для довольно тривиального реального языка у нас обычно есть умножение, деление, вызовы функций и т. Д.

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

...