Парсерное восхитительное
Jul. 23rd, 2012 07:27 pmЗнающие язык Си, подумайте, что будет, если написать
#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
no subject
Date: 2012-07-24 05:09 am (UTC)И так далее. Пусть трудолюбивые реализуют препроцессор на человеческом языке. :-p
no subject
Date: 2012-07-24 05:20 am (UTC)Как видно из примера, не все так просто.
no subject
Date: 2012-07-24 05:50 am (UTC)no subject
Date: 2012-07-24 05:53 am (UTC)no subject
Date: 2012-07-24 05:34 am (UTC)no subject
Date: 2012-07-24 05:40 am (UTC)no subject
Date: 2012-07-24 05:41 am (UTC)no subject
Date: 2012-07-24 05:28 am (UTC)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.
Т.е. при виде // препроцессор должен начинать кушать и пропускать весь текст аж до конца строки
no subject
Date: 2012-07-24 05:38 am (UTC)no subject
Date: 2012-07-24 05:43 am (UTC)no subject
Date: 2012-07-24 05:51 am (UTC)no subject
Date: 2012-07-24 05:57 am (UTC)no subject
Date: 2012-07-24 06:09 am (UTC)no subject
Date: 2012-07-24 06:18 am (UTC)no subject
Date: 2012-07-24 06:00 am (UTC)Любительский GCC (G++) глючил на тимплейтах долго и нудно, годами.
no subject
Date: 2012-07-24 06:06 am (UTC)no subject
Date: 2012-07-25 12:55 am (UTC)no subject
Date: 2012-07-25 12:59 am (UTC)no subject
Date: 2012-07-25 01:04 am (UTC)no subject
Date: 2012-07-25 01:30 am (UTC)`define ONE 1 `define TWO 2 и понимает это "правильно", от другого - ругается на недопустимый `define в точке использования макро ONE (что логично), а от третьего - макро ONE определяется как "1 `define TWO 2", и TWO определяется при каждом использовании макро ONE как
"2 дальнейшее содержимое текущей строки", с очевидной руганью насчет повторных определений, если ONE использовано более чем однажды.
Ужас и безумие, одним словом.
no subject
Date: 2012-07-25 02:18 am (UTC)no subject
Date: 2012-07-25 02:23 am (UTC)