Подтвердить что ты не робот

Как компилятор C анализирует следующий оператор C?

Рассмотрим следующие строки:

int i;
printf("%d",i);

Будет ли лексический анализатор идти в строку для разбора % и d в качестве отдельных токенов, или он будет анализировать "% d" как один токен?

4b9b3361

Ответ 1

Здесь работают два парсера: во-первых, компилятор C, который будет анализировать файл C и в основном игнорировать содержимое строки (хотя современные компиляторы C будут анализировать эту строку, а также помогать ломать строки неправильного формата - несоответствия между спецификатором преобразования % и соответствующим аргументом, переданным в printf() для преобразования).

Следующий синтаксический анализатор - это синтаксический анализатор строкового формата, встроенный в библиотеку времени выполнения C. Это будет вызываться во время выполнения, чтобы проанализировать строку формата, когда вы вызываете printf. Этот парсер, конечно, очень прост в сравнении.

Я не проверял, но я бы предположил, что компиляторы C, которые помогают проверять строки с неправильным форматированием, будут реализовывать парсер, похожий на printf, в качестве этапа последующей обработки (т.е. используя собственный лексер).

Ответ 2

Строковый литерал - это единственный токен. Вышеупомянутый код будет обозначаться следующим образом:

int     keyword "int"
i       identifier
;       semicolon
printf  identifier
(       open paren
"%d"    string literal
,       comma
i       identifier
)       closing paren
;       semicolon

Ответ 3

"%d" является строковым литералом, и он будет рассматриваться как один токен как с препроцессором C, так и компилятором, мы можем см. это, перейдя в черновик стандарта C99 раздел 6.4 Лексические элементы, которые определяют следующие токены:

token:
  keyword
  identifier
  constant
  string-literal
  punctuator

и следующие токены для обработки:

preprocessing-token:
  header-name
  identifier
  pp-number
  character-constant
  string-literal
  punctuator
  each non-white-space character that cannot be one of the above

и говорит:

A токен - минимальный лексический элемент языка в переводе фаз 7 и 8. Категории токенов: ключевые слова, идентификаторы, константы, строковые литералы и пунктуаторы. Ток предварительной обработки - это минимальный лексический элемент языка в переводах фаз 3 до 6. Категории токенов предварительной обработки: имена заголовков, идентификаторы, номера предварительной обработки, символьные константы, строка литералы, пунктуаторы и одиночные символы без пробела, которые делают не лексически соответствуют другим категориям токенов предварительной обработки .58) [...]

Различные этапы перевода описаны в разделе 5.1.1.2 Фазы перевода, и я остановлюсь на некоторых из них:

[...]

3 Исходный файл разбит на токеты предварительной обработки 6) и последовательности символы пробела (включая комментарии).

[...]

6 Сопряженные строковые литералы объединяются.

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

[...]

Различие между токенами и токенами перед процессором может показаться несущественным, но мы можем видеть, что по крайней мере в одном случае, например, в соседних строковых литералах, например "%d" "\n", у вас есть два токена перед процессором, а после фазы 6 будет только один токен.

Ответ 4

Требуется библиотечная функция #include 'stdio.h' в верхней части ур кода...