spamsink: (Default)
[personal profile] spamsink


Знающие язык Си, подумайте, что будет, если написать
#define FOO 1 // comment \
#define BAR 2
int baz() { return FOO + BAR; }
Естественно, после препроцессора получится
int baz() { return 1 + BAR; }
потому что слияние строк через \ в конце строки всегда и везде выигрывает у комментария до конца строки, т.е. исходный текст эквивалентен
#define FOO 1 // comment #define BAR 2
int baz() { return FOO + BAR; }


А теперь - дискотека!

Есть язык Верилог с очень похожим на Си синтаксисом команд препроцессора (отличается тем, что вместо # пишется гравис (`) и нужно писать гравис перед именами макросов), с продолжением строк с помощью \, с идентичным Си синтаксисом комментариев (есть точно такие же комментарии до конца строки, записываемые через //, и многострочные с помощью /* и */), но с совершенно вычурной семантикой сочетания комментария и продолжения строк. В терминах Си это выглядело бы так:
#define ONE 1  // comment \
#define TWO 2
#define SUM 3 + // comment \
4
int foo() { return ONE + TWO + SUM; }

И это компилируется и работает, возвращая 10 (на первый взгляд кажется, что // попросту выигрывает у \, но это не так). Попробуйте объяснить на человеческом языке, как это должно работать, и реализовать препроцессор, который бы это обеспечивал. :)
Для вериложцев:
`define ONE 1  // comment \
`define TWO 2
`define SUM 3+ // comment \
4 
module foo;
initial $display(`ONE + `TWO + `SUM);
endmodule

Date: 2012-07-24 05:09 am (UTC)
From: [identity profile] fatoff.livejournal.com
Ну что, в обязаности гражданина Препроцессора входит чтение символов, которые в него льются неважно откуда. Как только гражданин Препроцессов встречает знак # или ` он далее ожидает некоторое выражение, которое или цензурно, или гражданин Препроцессор громко возмущается и завершает свою работу. Закон С99 заставляет гражданина Препроцессора также определять "комментарий" блочный /**/ или строчный //, то есть выражение, не имеющие практического значения. Любая порция символов, которую читает гражданин Процессор, может либо завершаться в текущей строке, либо продолжаться на следующей, при наличии символа '\'. Выражения, которые начинаются после # или ` определены законом C99, сам гражданин Препроцессор знает его очень поверхностно, так что часто советуется с гражданином Компиллятором, но некоторые выражения, как define, хорошо понятны гражданину Препроцессору, и он ожидает две разделённые пробелами сущности после #define, первая - имя, вторая - значение, при чём, вторая может быть сама по себе выражением, которое может быть снова рассмотрено гражданином Препроцессором...

И так далее. Пусть трудолюбивые реализуют препроцессор на человеческом языке. :-p
Edited Date: 2012-07-24 05:11 am (UTC)

Date: 2012-07-24 05:50 am (UTC)
From: [identity profile] fatoff.livejournal.com
Тема вложенных выражений из продолжающейся строки не раскрыта.

Date: 2012-07-24 05:34 am (UTC)
From: [identity profile] panchul.livejournal.com
Я не знаю про стандарт C99, но я уверен что ANSI C (C89) не требовал, чтобы препроцессор "советовался" с компилятором. Препроцессор был самодостаточной программой, содержащей простой парсер для некоторых константных expressions в #if.

Date: 2012-07-24 05:41 am (UTC)
From: [identity profile] fatoff.livejournal.com
В общем вы правы, для обоих стандартов гражданин Препроцессор просто передаёт то, что за пределами его понимания, Компиллятору. А C99 потому, что строчные комментарии есть.

Date: 2012-07-24 05:28 am (UTC)
From: [identity profile] panchul.livejournal.com
Нашел

http://www.veripool.org/papers/Preproc_Good_Evil_SNUGBos10_paper.pdf

The Verilog LRM (reference [1]) requires that block comments (/**/) inside define values become part of the defines, while // comments at the end of a define do not. If the comment represents a meta-comment, this can be a source of bugs. Be sure to use /**/ block comments for all meta-comments.

Т.е. при виде // препроцессор должен начинать кушать и пропускать весь текст аж до конца строки

Date: 2012-07-24 05:43 am (UTC)
From: [identity profile] panchul.livejournal.com
Так как я сам очень кратко работал в команде VCS, то я не удивлен. Там народ перемещают случайно с участка кода на другой участок, стремясь всех сделать взаимозаменяемыми (без clear ownership), а главным критерием качества есть пройдет ли результат регрессию. Такие формалисты как ты там непопулярны.

Date: 2012-07-24 05:57 am (UTC)
From: [identity profile] panchul.livejournal.com
Один из ведущих инженеров в ModelSim заодно президент орегонского общества камелий.


Date: 2012-07-24 06:18 am (UTC)
From: [identity profile] panchul.livejournal.com
Не, не он. Меня на камелии подсадила CFO в C Level Design.

Date: 2012-07-24 06:00 am (UTC)
From: [identity profile] fatoff.livejournal.com
В целом Microsoft C++ стабильнее прочих, тем не менее.
Любительский GCC (G++) глючил на тимплейтах долго и нудно, годами.
Edited Date: 2012-07-24 06:02 am (UTC)

Date: 2012-07-24 06:06 am (UTC)
From: [identity profile] panchul.livejournal.com
Насколько я смутно помню, самые правильные темплейты в году эдак 1995-м были у Watcom C++, все остальные - с глюками.

Date: 2012-07-25 12:55 am (UTC)
stas: (Default)
From: [personal profile] stas
Я так понимаю, у него комментарий заканчивается на \, а то, настоящий это конец строки или поддельный, никого не волнует. Если проверка, где заканчивается комметарий, и проверка, а не на \ ли заканчивается данная строка, написаны в разных местах, и первый делается до второго, я легко представляю себе, как такое получается.

Date: 2012-07-25 01:04 am (UTC)
stas: (Default)
From: [personal profile] stas
Хм. Специальный случай для строк, начинающихся с `?

Date: 2012-07-25 02:18 am (UTC)
From: [identity profile] kcmamu.livejournal.com
Verilog-XL ругается, NCverilog ест.
Page generated Mar. 8th, 2026 04:43 am
Powered by Dreamwidth Studios