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