Как использовать boost::wave для расширения вложенных макросовC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как использовать boost::wave для расширения вложенных макросов

Сообщение Anonymous »

Я разрабатываю приложение boost wave для сопоставления нерасширенных экземпляров макросов в исходном файле C с соответствующим расширенным текстом макроса.
Сопоставление должно работать как для функции, так и для объекта. -подобные вызовы макросов. В случае макросов, похожих на функции, сопоставление должно обрабатывать вызовы вложенных макросов в аргументах макроса.
Простой пример
Рассмотрим следующий макрос определения (либо определенные в начале файла «C», либо включенные через включенный заголовок):
#define MIN(a, b) (((a) (b)) ? (a) : (b))

В примере ниже у нас есть код C, который вызывает макрос MIN 2 раза. Каждый случай вызова уникален (соответствует определенной строке в источнике (строки 4 и 5), и это также примеры вложенных вызовов макросов. Расширенный текст макроса (с удаленными пробелами для ясности) фиксируется в файле macro_rescanned обратный вызов (((1)(4))?(3):(4))))?(a):((((3)>(4))?(3) :(4)))). Я не знаю, где найти, из какого экземпляра (и соответствующих токенов исходного кода) он расширяется (строка 4 или 5).
1 #include "..." // definitions of MIN/MAX macros
2 int main()
3 {
4 int foo = MIN(1,MAX(3,4)); // line 4, col 15 file position (15 chars)
^-------------- // HELP: how to get this range & corresponding from line 4.
5 int bar = MIN(1,MAX(3,7)); // line 5, col 15 file position (15 chars)
^-------------- // HELP: how to get this range & corresponding from line 5.
6 return 0;
7 }

boost::wave позволяет приложению расширить класс [default_preprocessing_hooks][2] и перезаписать несколько методов, чтобы перехватить процесс расширения макроса. Процесс расширения макроса описан здесь. Интересующие функции:
template
bool expanding_object_like_macro(
ContextT const& ctx,
TokenT const& macro,
ContainerT const& macrodef,
TokenT const& macrocall);

template
bool expanding_function_like_macro(
ContextT const& ctx, TokenT const& macrodef,
std::vector const& formal_args,
ContainerT const& definition, TokenT const& macrocall,
std::vector const& arguments,
IteratorT const& seqstart, IteratorT const& seqend)
template
void expanded_macro(ContextT const &ctx, ContainerT const &result)

template
void expanded_macro(ContextT const &ctx, ContainerT const &result)

После полного раскрытия макроса (в случае вложенных макросов, когда ВСЕ аргументы были расширены), следующий перехватчик вызывается с полностью развернутым текст замены макроса. Это текст, который мне нужно захватить, однако мне также нужно знать соответствующие нерасширенные местоположения и исходный текст из исходного файла C (например, строки 3 и 4 во вводном примере).
Этот хук особенно интересен тем, что он вызывается только после того, как все аргументы макроса были полностью раскрыты. Насколько я могу судить, при раскрытии каждого из вложенных аргументов хук «expanded_macro» также вызывается повторно при обработке аргументов слева направо. Однако, к сожалению, я не могу найти способ связать исходный расширенный текст макроса и диапазон расположения исходного файла с расширенным текстом, содержащимся в параметре токенов:
template
void rescanned_macro(ContextT const &ctx, ContainerT const &tokens)

Тестовое приложение
Я создал приложение boost::wave на примере расширенных перехватчиков, который поставляется с библиотекой boost::wave.
Тестовые данные
Приложение использует исходный файл C C:\temp\test2.c в качестве тестовых данных. Это передается как единственный аргумент приложению. Это очень простой файл, не содержащий других файлов.
#define TWO (2) // object like macro
#define THREE() (3) // function like macro with 0 args
#define FOUR() (4) // function like macro with 0 args
#define NUMSQUARED(x) ((x)*(x)) // function like macro with 1 arg
#define MIN(a, b) (((a) (b)) ? (a) : (b))
#define FUNC_MACRO(x) ((x) + 1)
#define NESTED_MACRO(a, b) (FUNC_MACRO(a) + NUMSQUARED(b) + FUNC_MACRO(FOUR()) + TWO + THREE())
int main() {
int a = NESTED_MACRO(1, 2);
int b = MIN(1, TWO);
int c = MIN(1, 2);
int d = MIN(1, THREE());
int f = MIN(1, NUMSQUARED(3));
int g = MIN(MAX(1, 2), 3);
return 1;
}

Источник приложения
#include
#include
#include
#include
#include
#include
#include

using namespace boost::wave;
namespace fs = std::filesystem;

struct my_hooks : public context_policies::default_preprocessing_hooks {
my_hooks(const my_hooks& other) = default;
my_hooks(my_hooks&& other) noexcept = default;
my_hooks& operator=(const my_hooks& other) = default;
my_hooks& operator=(my_hooks&& other) noexcept = default;

explicit my_hooks()
: mSourcePath{}
, mCurrentMacro{}
, mExpandedMacros{}
{}

~my_hooks() {
if (!mExpandedMacros.empty()) {
std::cout


Подробнее здесь: https://stackoverflow.com/questions/788 ... ted-macros
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»