[boost] разбор описания функции
От: Lepsik Индия figvam.ca
Дата: 22.01.10 15:28
Оценка:
какими средствами в бусте можно разобрать сигнатуру функции и склеить ее тело по шаблону типа :


--- запихать каждое такое описание в глобальный список
START_DECLARE 

LONG PASCAL RegOpenKeyExA( HKEY hKey
                              , LPCSTR lpSubKey
                              , DWORD ulOptions
                              , REGSAM samDesired
                              , PHKEY phkResult );
END_DECLARE



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



FUNC::returntype  FUNC::stacktype FUNC::name ( FUNC::paramlist )
{
...
}



спасибо
Re: [boost] разбор описания функции
От: Chorkov Россия  
Дата: 22.01.10 16:23
Оценка: 1 (1)
Здравствуйте, Lepsik, Вы писали:

L>какими средствами в бусте можно разобрать сигнатуру функции и склеить ее тело по шаблону типа :



L>
L>--- запихать каждое такое описание в глобальный список
L>START_DECLARE 

L>LONG PASCAL RegOpenKeyExA( HKEY hKey
L>                              , LPCSTR lpSubKey
L>                              , DWORD ulOptions
L>                              , REGSAM samDesired
L>                              , PHKEY phkResult );
L>END_DECLARE
L>



L>чтобы дальше можно было развернуть с возможностью доступа для анализа и построения другой функции




L>
L>FUNC::returntype  FUNC::stacktype FUNC::name ( FUNC::paramlist )
L>{
L>...
L>}
L>



L>спасибо



Если речь о разборе строки препроцессором, то выражение
( HKEY hKey, LPCSTR lpSubKey)

уже слишком сложное для поледующего разбора.
Нельзяли упаковать функцию так:
DECLARE_FUNC(
 LONG, 
 PASCAL,
 RegOpenKeyExA,
 (HKEY)(LPCSTR  )(DWORD    )(REGSAM    )(PHKEY    ),
 (hKey)(lpSubKey)(ulOptions)(samDesired)(phkResult)
)

?
Re: [boost] разбор описания функции
От: Кодт Россия  
Дата: 22.01.10 16:36
Оценка: 1 (1)
Здравствуйте, Lepsik, Вы писали:

L>какими средствами в бусте можно разобрать сигнатуру функции и склеить ее тело по шаблону типа :


Боюсь, что только средствами языка (препроцессор + Си/С++) это сделать невозможно.
Но можно сделать собственный препроцессор, который будет рожать сишный код
// ищет объявления вида
DECLARE_PROTOTYPE( int __stdcall foo (int x, int y, int z) )
// и превращает их
#define RETTYPE_foo    int
#define CONVENTION_foo __stdcall
#define ARGUMENTS_foo  (int x, int y, int z)

// после чего
#define PP_CAT(x,y) PP_CAT_(x,y)
#define PP_CAT_(x,y) x##y

#define RETTYPE(f)    PP_CAT(RETTYPE_,f)
#define CONVENTION(f) PP_CAT(CONVENTION_,f)
#define ARGUMENTS(f)  PP_CAT(ARGUMENTS_,f)

#define USE_PROTOTYPE(f,g) RETTYPE(f) CONVENTION(f) g ARGUMENTS()
#define PROTOTYPE(f) USE_PROTOTYPE(f,f)

Можно вынести объявления прототипов в отдельный файл, на основе которого генерировать обычный .h — дальше всё будет просто.

Единственная заморочка — разбирать сигнатуру функции, с учётом сложностей объявления типа в Си.
Скажем, вот уже такое int(*foo(int x))[10] — функция, возвращающая указатель на массив из 10 интов.
Да ещё с учётом макроподстановок...
Видимо, придётся как-то себя ограничить — использовать typedef'ы и приводить объявление к красивому предсказуемому виду.
http://files.rsdn.org/4783/catsmiley.gif Перекуём баги на фичи!
Re[2]: [boost] разбор описания функции
От: Lepsik Индия figvam.ca
Дата: 22.01.10 17:21
Оценка:
C>Если речь о разборе строки препроцессором, то выражение
C>
C>( HKEY hKey, LPCSTR lpSubKey)
C>

C>уже слишком сложное для поледующего разбора.
C>Нельзяли упаковать функцию так:
C>
C>DECLARE_FUNC(
C> LONG, 
C> PASCAL,
C> RegOpenKeyExA,
C> (HKEY)(LPCSTR  )(DWORD    )(REGSAM    )(PHKEY    ),
C> (hKey)(lpSubKey)(ulOptions)(samDesired)(phkResult)
C>)
C>



как раз аргументы функции меня интересуют — достаточно что вставятся как есть.
Re[2]: [boost] разбор описания функции
От: Lepsik Индия figvam.ca
Дата: 22.01.10 17:40
Оценка:
К>Единственная заморочка — разбирать сигнатуру функции, с учётом сложностей объявления типа в Си.
К>Скажем, вот уже такое int(*foo(int x))[10] — функция, возвращающая указатель на массив из 10 интов.
К>Да ещё с учётом макроподстановок...
К>Видимо, придётся как-то себя ограничить — использовать typedef'ы и приводить объявление к красивому предсказуемому виду.


у меня задачка по-прозаичнее.

такое описание например :


    HMODULE WINAPI GetModuleHandleW  ( LPCWSTR lpModuleName );



мне надло превратить в такое:


    virtual HMODULE GetModuleHandleW  ( LPCWSTR lpModuleName ){...};
...
    HMODULE WINAPI GetModuleHandleW  ( LPCWSTR lpModuleName ){...}


то есть в первой копии вырезать convesion тип, а всю строку вставить как есть.
Это я делаю mock библиотеку для winapi библиотек и не хотелось бы усложнять тяжелыми конструкциями, остановившись на чем-то таком в описании:

_F( HMODULE WINAPI GetModuleHandleW ( LPCWSTR lpModuleName ) )

избегнув повторного описания с другой сигнатурой

в общем ясно что малой кровью не обойтись
Re[3]: [boost] разбор описания функции
От: alsemm Россия  
Дата: 22.01.10 20:23
Оценка: +1
Здравствуйте, Lepsik, Вы писали:

L>
L>    HMODULE WINAPI GetModuleHandleW  ( LPCWSTR lpModuleName );
L>



L>мне надло превратить в такое:



L>
L>    virtual HMODULE GetModuleHandleW  ( LPCWSTR lpModuleName ){...};
L>...
L>    HMODULE WINAPI GetModuleHandleW  ( LPCWSTR lpModuleName ){...}
L>


А зачем это на boost-е делать и вообще C++? imho проще на скрипте парсер написать. Я на python-е делал, например. Универсальный парсер, который понимает любой валидный синтаксис C городить нет смысла, заточить только под особенности тех исходников, которые надо разбирать. Чтобы с макроподстановками не связываться можно предварительно прогонять исходник через C-ый препроцессор, а потом скармливать его парсеру.
Re: [boost] разбор описания функции
От: TarasKo Голландия  
Дата: 26.01.10 23:17
Оценка:
Честно говоря не до конца понял задачу, однако ситуация по разбору типов WINAPI функций чем-то знакомая.
Можно использовать BOOST_TYPEOF из Boost.Typeof для извлечения типа функции


typedef BOOST_TYPEOF(RegOpenKeyExA) TRegOpenKeyExA;


И потом применительно к типу TRegOpenKeyExA использовать библиотеку Boost.FunctionTypes для декомпозиции параметров и композиции типа функций которая тебе будет нужна.

Далее всё это завернуть в макрос И будет в итоге что-то типа

DO_SOMETHING_SERIOUS(RegOpenKeyExA)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.