10.1 Традиционный лексический анализ
Традиционный препроцессор не разбивает свой входной поток на токены так же, как это делает препроцессор, соответствующий стандартам. Входной поток просто обрабатывается как поток текста с минимальной внутренней формой.
Эта реализация не обрабатывает триграфы (см. триграфы) специально, так как они были изобретены комитетом по стандартам. Она корректно обрабатывает произвольно расположенные экранированные новые строки и склеивает строки так, как вы ожидаете; многие традиционные препроцессоры этого не делали.
Форма горизонтальных пробелов во входном файле сохраняется в выходном файле. В частности, жесткие табуляции остаются жесткими табуляциями. Это может быть полезно, например, при предварительной обработке файла Makefile.
Традиционный CPP распознает только комментарии в стиле C и обрабатывает последовательность ‘/*’ как начало комментария только если она находится вне кавычек. Кавычки вводятся обычными одинарными и двойными кавычками, а также начальной ‘<’ в директиве #include.
Традиционно комментарии полностью удаляются и не заменяются пробелом. Поскольку традиционный компилятор сам выполняет токенизацию результата работы препроцессора, это означает, что комментарии могут эффективно использоваться как операторы склеивания токенов. Тем не менее, комментарии ведут себя как разделители для текста, обрабатываемого самим препроцессором, поскольку он не пере-лексирует свой вход. Например, в
#if foo/**/bar
‘foo’ и ‘bar’ являются различными идентификаторами и расширяются отдельно, если они оказываются макросами. Другими словами, эта директива эквивалентна
#if foo bar
а не
#if foobar
В общем случае в традиционном режиме открывающая кавычка не обязана иметь соответствующую закрывающую кавычку. В частности, макрос может быть определен с текстом подстановки, содержащим несовпадающую кавычку. Конечно, если вы попытаетесь скомпилировать предварительно обработанный вывод, содержащий несовпадающую кавычку, вы получите синтаксическую ошибку.
Однако все директивы предварительной обработки, кроме #define, требуют совпадения кавычек. Например:
#define m This macro's fine and has an unmatched quote
"/* This is not a comment. */
/* This is a comment. The following #include directive
is ill-formed. */
#include <stdio.h Так же, как и для препроцессора ISO, закрывающая кавычка может быть экранирована обратной косой чертой, чтобы предотвратить закрытие цитируемого текста.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/cpp/Traditional-lexical-analysis.html