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

Извлечение символов препроцессора из источника

Я ищу способ извлечь все символы препроцессора, используемые в моем коде.
Например, если мой код выглядит так:

#ifdef FOO
#endif

#if ( BAR == 1 && \
      defined (Z) )
#endif

Я хотел бы получить список [FOO,BAR,Z] в качестве вывода.

Я нашел несколько сообщений, предлагающих gcc -E -dM, но это отображает все символы, которые препроцессор будет применять к коду.
То, что я хочу, напротив, представляет собой список всех символов , фактически используемых в коде.

Любые предложения?

4b9b3361

Ответ 1

Это довольно просто. Вы должны просто проанализировать исходный код точно, как будет соответствовать соответствующий препроцессор, и с правильной версией C или С++. Хорошо, я шучу, если вы поддерживаете только более позднюю версию, ваш код, скорее всего, даст правильные результаты в более старых версиях, но даже это следует тщательно контролировать.

Теперь серьезно. Поскольку вы можете попросить препроцессор предоставить вам список всех определенных символов, вы можете просто токенизировать источник и идентифицировать все токены из этого списка, которые не сразу следуют за начальным #define или #undef. Эта часть должна быть разумно выполнима с помощью lex + yacc.

Единственная альтернатива, которую я могу себе представить, - это использовать код реального компилятора (Clang должен быть проще, чем gcc, но не уверен) отбрасывать все генерации кода и постоянно сохранять каждое использование макроса.

TL/DR: однако вы берете его, это будет тяжелая работа: если вы можете обойтись, держитесь подальше от этого...

Ответ 2

Вы можете получить половину пути, используя библиотеку препроцессора, такую ​​как Boost.Wave. Он может действовать как лексер, поэтому вам не придется писать эту часть самостоятельно. Вам нужно будет предоставить грамматику для бит, о котором вы заботитесь (define, ifdef, ifndef, if, elif).