Что означает #строка?

Что делает следующая строка?

#line 25 "CSSGrammar.y"

А что с расширением?


person Luchian Grigore    schedule 05.02.2012    source источник
comment
Просто из любопытства... Какой компилятор это ест?   -  person Vyktor    schedule 06.02.2012
comment
@Vyktor это часть стандарта   -  person Seth Carnegie    schedule 06.02.2012
comment
Я уверен, что это дубликат. См. это: gcc.gnu.org/onlinedocs/cpp/Line-Control.html   -  person Pubby    schedule 06.02.2012
comment
Duuude... Первая ссылка из Google: publib.boulder.ibm.com/infocenter/macxhelp/v6v81/   -  person Vyktor    schedule 06.02.2012
comment
@Vyktor при поиске чего? Я пробовал google, но безуспешно.   -  person Luchian Grigore    schedule 06.02.2012
comment
@LuchianGrigore Я просто набрал #line в Google и получил соответствующий результат   -  person Seth Carnegie    schedule 06.02.2012
comment
@Vyktor :)) Верно, я не думал, что Google принимает знаки решетки.   -  person Luchian Grigore    schedule 06.02.2012
comment
:))) сделайте себе фейспалм :P (чувак, я так смеюсь :D) и отметьте ответ Сета как ответ, он проделал отличную работу, собрав его вместе   -  person Vyktor    schedule 06.02.2012
comment
@Vyktor Я уже проголосовал, но все еще жду объяснений по расширению.   -  person Luchian Grigore    schedule 06.02.2012
comment
Разве это не очевидно из ссылки, которую я предоставил? I позволяет вам подделывать значения макросов __LINE__ и __FILE__, и ошибки будут отображаться в другой строке.   -  person Vyktor    schedule 06.02.2012
comment
@LuchianGrigore также ясно из того, что говорит стандарт: аналогично устанавливает предполагаемый номер строки и меняет предполагаемое имя исходного файла на содержимое литерала строки символов. Кто-то просто выбрал расширение .y, которое используется YACC IIRC (также оно называется грамматикой, так что это имеет смысл)   -  person Seth Carnegie    schedule 06.02.2012


Ответы (7)


Согласно Стандарту:

§16.4.3:

Предварительная обработка директивы формы

# line digit-sequence new-line

приводит к тому, что реализация ведет себя так, как если бы следующая последовательность строк исходного кода начинается со строки исходного кода, которая имеет номер строки, указанный последовательностью цифр (интерпретируемой как десятичное целое число). Если в последовательности цифр указан ноль или число больше 2 147 483 647, поведение не определено.

§16.4.4:

Предварительная обработка директивы формы

# line digit-sequence " s-char-sequenceopt" new-line

аналогично устанавливает предполагаемый номер строки и изменяет предполагаемое имя исходного файла, чтобы оно было содержимым литерала строки символов.

§16.4.5:

Предварительная обработка директивы формы

# line pp-tokens new-line

(который не соответствует ни одной из двух предыдущих форм) разрешен. Токены предварительной обработки после строки в директиве обрабатываются так же, как и в обычном тексте (каждый идентификатор, определенный в настоящее время как имя макроса, заменяется своим замещающим списком токенов предварительной обработки). Если полученная после всех замен директива не соответствует ни одной из двух предыдущих форм, поведение не определено; в противном случае результат обрабатывается соответствующим образом.

Расширение .y - это именно то, что автор решил использовать, возможно, чтобы показать, что это файл YACC (слово "грамматика" также указывает на это, хотя это всего лишь предположение).

person Seth Carnegie    schedule 05.02.2012

В нем просто указано, что текущая строка кода взята из строки 25 файла CSSGrammar.y, файла грамматики в стиле YACC, из которого был сгенерирован этот код.

Это может использоваться отладчиками для перехода к самой грамматике, а не к сгенерированному коду.

person user7116    schedule 05.02.2012
comment
Не только для отладчиков: это также помогает компиляторам указать вам правильные источники ошибок. - person R. Martinho Fernandes; 06.02.2012

#line изменяет позицию отчета для компилятора и используется программным обеспечением для генерации кода, чтобы помочь программисту идентифицировать проблему в исходном коде. Его может использовать любой, чтобы помочь перенаправить отчеты об ошибках, чтобы они были более информативными.

Так, например, ваш синтаксический анализатор генерирует файл CSSGrammar.cpp, скажем, который скомпилирован компилятором С++ и содержит фрагменты С++, директива #line 25 "CSSGrammar.y" указывает компилятору С++ обрабатывать эту конкретную точку в файле, как если бы это была строка номер 25. из CSSGrammar.y

Компилятор будет продолжать анализировать последующие строки и сообщать об ошибках в соответствии с начальными условиями этой директивы.

Поэтому, если ошибка произойдет через 3 строки, будет сообщено, что ошибка произошла в строке 28 в CSSGrammar.y.

Обратите внимание, что один исходный файл может иметь исходники из нескольких частей; и что эта директива может быть использована весьма эффективно для указания условий ошибки.

Как правило, вы увидите, что по пути есть несколько директив #line; они просто существуют для учета различных инъекций по пути (для сброса курсора отчетности, если хотите).

Обратите внимание, что директива #line может использоваться ЛЮБЫМ генератором, включая ваш собственный, и никоим образом не ограничивается генераторами парсеров.

person Ahmed Masud    schedule 05.02.2012

Это директива для компилятора полагать, что следующая строка является строкой номер 25 в файле CSSGrammar.y. Затем, если компилятор обнаружит ошибку во 2-й следующей строке, она будет сообщена как исходящая из строки 26 CSSGrammar.y.

Программы, генерирующие файлы C, такие как bison, или yacc, или flex, или ANTLR или даже (устаревший) MELT часто используют эту возможность.

Если генерируется отладочная информация (например, с помощью gcc -g), она будет указывать на файл CSSGrammar.y в вашем примере.

person Basile Starynkevitch    schedule 05.02.2012

Генератор синтаксического анализатора yacc использует файлы, оканчивающиеся на .y, и выдает файлы, содержащие C или C++. Он добавляет эти строки #line, чтобы позволить отладчику вернуться к старому исходному коду, не принимая никаких замен.

person bmargulies    schedule 05.02.2012

это вариант препроцессора c. Он говорит c-парсеру отбросить количество строк исходного файла, делая вид, что это строка № 25.

С этой информацией вам будет легче отлаживать исходный файл. Файл yacc будет транслирован в c-source, где это мнимая исходная строка.

person Jörg Beyer    schedule 05.02.2012

Использование #line заставляет компилятор испытывать амнезию относительно того, какой файл он компилирует и на какой строке он находится, и загружает новые данные.

Примечание. Компилятор по-прежнему компилирует строку, на которой он был.

person Nathan Kulzer    schedule 14.04.2019