Главная arrow С++ (часть 3) arrow Зачем нужен транслятор?

Зачем нужен транслятор?

Вы можете спросить, зачем понадобился транслятор для испытания новых конструкций языка, когда есть хорошо знакомая альтернатива — стандартней препроцессор языка С++? Как известно всем читателям, препроцессор Вь1Полняет макроподстановки, в которых один текстовый фрагмент замещается другим. Долгое время макросы препроцессора использовались для вставки эКспериментальных элементов в язык С++. Например, общеупотребительная инструкция, реализуемая с помощью макроса, — цикл repeat/until. Этот ЧНКл подобен циклу do/while языка С++, за исключением того, что цикл tePeat/until выполняется до тех пор, пока некоторое условие не станет истинным (true). (Таким образом, цикл repeat/until выполняется, пока его логическое выражение равно false.) Именно это отличает его от цикла do/while, который функционирует до тех пор, пока некоторое условие не станет ложным. Благодаря подобию описанных циклов возможна реализация цикла repeat/until с помощью макроса, как показано в приведенном далее фрагменте кода, ttdefine repeat do #define until(exp) while(!(exp)) // ... int = 0; repeat {
cout « "i: " « I « endl;
i++;
} until(i == 10);
Макрос вызывает подстановку do вместо repeat и while вместо until. Условное выражение в while также меняется на противоположное. Таким образом, цикл repeat/until из предыдущего фрагмента преобразуется препроцессором в приведенный далее цикл do/while, do {
cout « "i:  " « I « endl; i++;
} while(!(i == 10));
Как показывает этот пример, применение макроса для реализации конструкции repeat/until — легкий и оправданный прием. Если существует многолетняя традиция применения макросов для создания новых элементов языка, захочет ли кто-нибудь разрабатывать транслятор для этой цели? Почему не использовать макрос, подобный тому, который применялся для цикла repeat/until? К сожалению, макроподстановки нельзя применять для встраивания всех типов экспериментальных конструкций языка. Более того, даже в тех случаях, когда подобные подстановки возможны, не все из них столь элегантны и концептуально чисты, как та, которая применялась в примере для цикла repeat/until. Несмотря на то, что программисты добились впечатляющих успехов с помощью макросов, в большинстве случаев они достигались за счет применения сложных и малопонятных директив #define Корректность подобных "макрохитростей", часто нарушающих структуру кода и не обладающих достаточной отказоустойчивостью, трудно проверить. Честно говоря, многие программисты на С++ (и автор в том числе) избегают использования сложных макросов по этим причинам.
К счастью, существует альтернатива применению сложных макросов, которая предназначена для экспериментов с разнообразными новыми элементами языка С++. Вы можете создать транслятор, который обеспечит преобразование под контролем программы экспериментальных конструкций в эквивалентный им код на языке С++. Использование подобного "пре-препроцессора" позволит вам добавить такие новые функциональные возможности в язык С++, которые трудно или невозможно реализовать с помощью макросов для Препроцессора. Предлагаемый транслятор интересен и сам по себе, а его основной каркас легко адаптировать для других целей.
Следует отметить, что хотя разрабатываемый в этой главе транслятор способен выполнять сложные текстовые подстановки, он не лишен ограничений. Поскольку транслятор реализует однопроходный алгоритм, читающий исходный файл один раз, он может применяться для экспериментирования только с теми языковыми средствами, которые можно обработать с помощью однопроходной подстановки (при желании вы можете изменить поведение транслятора). Помимо замещений сложного текста, транслятор находится в полном неведении относительно содержания программы. Он ничего не знает о типе переменной, о смысле операции и даже прочитанной ранее лексемы. Таким образом, предлагаемый транслятор не является синтаксическим анализатором языка С++. Это просто механизм или средство для специализированных текстовых подстановок; по существу, его можно назвать специализированным препроцессором. Несмотря на перечисленные ограничения, вы можете использовать этот транслятор для проверки разнообразных идей.
^   Примечание  ^
Если вас интересует синтаксический анализатор для С++, обратитесь к главе 9.
Экспериментальные ключевые слова
Перед тем как разрабатывать транслятор, следует определить, какие преобразования он будет выполнять. Транслятор, предлагаемый в этой главе, поддерживает следующие экспериментальные расширения для языка С++: О ЦИКЛ foreach; О оператор cases; О оператор cypeof; 0 Цикл repeat/until.
За исключением цикла repeat/until, включенного в список просто для Иллюстрации, остальные ключевые слова используют синтаксис, КОТОРЫЙ трудно (или невозможно) преобразовать с помошью макроподстановок. " Последующих разделах описывается каждое из перечисленных ключе-вЫх слов.