Как парсеры обрабатывают препроцессоры и условную компиляцию? - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь выяснить, как парсеры обрабатывают препроцессор и условную компиляцию.Используя в качестве примера c ++, директивы препроцессора включены в правила грамматики c ++ или это отдельный язык, и перед синтаксическим анализом происходит предварительная обработка.В обоих случаях, как синтаксический анализатор может определить ошибки во всех возможных ветвях и получить информацию об исходной компоновке кода перед предварительной обработкой (например, номер строки, в которой произошла ошибка)?

1 Ответ

0 голосов
/ 28 ноября 2018

Взято из Документа препроцессора C :

Препроцессор C информирует компилятор C о местоположении в вашем исходном коде, откуда пришел каждый токен.

Так что в случае GCC парсер знает, где происходят ошибки, потому что препроцессор сообщает об этом.Я не уверен, относится ли эта цитата к токенам предварительной обработки или ко всем токенам C ++.

На этой странице есть еще несколько подробностей о том, как происходит волшебство.

Структура cpp_token содержит элементы line и col.Лексер заполняет их строкой и столбцом первого символа токена.Следовательно, но может быть неожиданно, токен из списка замены макроса раскрывает местоположение токена в директиве #define, потому что cpplib раскрывает макрос, возвращая указатели на токены в его списке замены.

[...] Таким образом, эта переменная однозначно перечисляет каждую строку в единице перевода.С некоторой простой инфраструктурой, прямо из этого можно отобразить исходный файл и пару номеров строк

Здесь является копией C ++ 14 (?)проект стандарта.Грамматика предварительной обработки приведена в Приложении A.14.Я не уверен, что имеет значение, хотите ли вы назвать это отдельным языком или нет.Согласно [lex.phases] (раздел 2.2), компиляторы C ++ ведут себя , как будто предварительная обработка происходит до того, как произойдет основной перевод / анализ.

...