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-10.5.0/cpp/Traditional-lexical-analysis.html