Войти
ФлеймФорумПрограммирование

[С++] преобразователь сортов Code Style`ов [WIP] (2 стр)

Advanced: Тема повышенной сложности или важная.

Страницы: 1 2
#15
21:34, 23 янв. 2013

Adler
> Это штука не умеет вытаскивать реализацию методов из тела класса.

Как заметил =A=L=X=, это слишком интеллектуальная задача для переформатировщика кода. Не думаю, что есть готовые решения для такой узкой задачи.


Прошло более 2 лет
#16
21:41, 30 янв. 2015

Вверх!

#define мемберы методы/конструкторы/деструкторы/обычные_операторы/операторы_приведения
#define мемберов мемберы

Итак, отчёт:
Научился превращать строку с С++ кодом в AST. //пришлось написать больше сотни лексических анализаторов.
Научился находить в AST классы, а внутри них мемберы.
На namespace`ы пока забил.
Научился генерировать код с реализацией мемберов  в некоторых частных случаях.
Научился удалять реализацию мемберов из тела класса.
Научился удалять inline из объявления и реализации  и мемберов.
Научился удалять static из объявления статических функций.
Научился удалять static и explicit из реализации мемберов.
Научился удалять из списка параметров умалчиваемые значения в реализации мемберов.

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

struct A{
  struct B{
    struct D{struct E{};};
    struct C{
      D::E get(){return D::E();};
    };
  };
};
int main(){A::B::C c;c.get();return 0;}
генерировался вот такой код:
struct A{
  struct B{
    struct D{struct E{};};
    struct C{
      D::E get();
    };
  };
};
A::B::D::E A::B::C::get(){return D::E();}
int main(){A::B::C c;c.get();return 0;}
а не такой(сейчас так): http://ideone.com/4Mj8xs
+ Показать

такие дела.

ЗЫ: Тестирую пока так: беру QapLite.h и генерирую для него hpp/cpp файл, а затем компилирую.
#17
22:11, 30 янв. 2015

Adler
> Научился превращать строку с С++ кодом в AST. //пришлось написать больше сотни
> лексических анализаторов.
Я не понял - ты шаблонами не пользуешься или как-то ухитрился их тоже обработать?

#18
22:30, 30 янв. 2015

kipar
> Я не понял - ты шаблонами не пользуешься или как-то ухитрился их тоже
> обработать?
Пользуюсь. Я написал для них около пары десятков лексеров :)

#19
11:41, 31 янв. 2015

Научился указывать полное имя типа возвращаемого значения в реализации мемберов. //воткнул assert пропускающий только типы без шаблонных параметров.

Но пока преобразователь всё ещё не может разбить QapLite.h на hpp/cpp, есть проблемы, надо ещё вот с этим разобраться:

#if
#ifdef
#endif
#include
#define
#undef
using
static LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)

особенно хочу отметить WndProc c CALLBACK`ом:
  я могу заменить CALLBACK в исходнике QapLite.h на __stdcall.
  могу изменить лексер соглашений о вызовах так, чтобы он считал CALLBACK за соглашение о вызове. //костыль же, а вдруг у кого-то CALLBACK это тип?
  можно добавить стадию препроцессора. //но тогда в hpp файле не будет CALLBACK`а, а меня это как бы не устраивает.

короче проблема в том, что сейчас ни один лексер statement`ом не признаёт это объявление функции.

наверно я просто изменю в QapLite.h WndProc на вот такой код:

#define WndProc CALLBACK WndProc
static LRESULT WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
...
}
#undef WndProc
преобразователь будет игнорировать define`ы и undef`ы и успешно отработает на этом коде.

#20
8:53, 3 фев. 2015

Вверх!

Итак, отчёт:
Научился строить AST для SFINAE шаблонов. //запретил использование операторов <,<<,<=,>,>>,>= внутри параметров шаблонов.
Научил преобразователь разбивать QapLite.h на hpp/cpp автоматически.
Решил проблемы из предыдущего поста. // оказывается WndProc вызывается из WndProc, поэтому задефайнил LRESULT вместо него :)

Сейчас пробую преобразовать исходный код полной версии своего движка.

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

struct A{
  struct B{
    struct D{struct E{};};
    struct C:D{
      E get(){return E();};
    };
  };
};
int main(){A::B::C c;c.get();return 0;}
тут класс C наследуется от класса D и метод C::get возвращает тип E из предка класса C.
поэтому реализацию метода C::get нельзя вытащить наружу вот так:
struct A{
  struct B{
    struct D{struct E{};};
    struct C:D{
      E get();
    };
  };
};
E A::B::C::get(){return E();};
int main(){A::B::C c;c.get();return 0;}
http://ideone.com/oF92Pd

#21
18:54, 7 фев. 2015

Вверх!

Итак, отчёт:
научил преобразователь сортов Code Style`ов из вот этого:

struct A
{
  struct B{};
  static vector<B> foo(){return vector<B>();}
};
делать вот это:
struct A
{
  struct B{};
  static vector<B> foo();
};
vector<A::B> A::foo(){return vector<B>();}

+ Сложный тест:

Ещё нашёл код который требует разворачивать имена типов внутри параметров опрераторов:

struct t_kukarek{
  struct t_pocpoc{
    friend bool operator==(const t_pocpoc&a,const t_pocpoc&b){return true;}
  };
};
реализация должна быть вот такой:
bool operator==(const t_kukarek::t_pocpoc&a,const t_kukarek::t_pocpoc&b){return true;}

потестить на вашем коде?

#22
10:17, 8 фев. 2015

Как на счет clang-format?

#23
12:13, 8 фев. 2015

typedef
> Как на счет clang-format?
Посмотрел, похоже что не умеет.

Кстати, в Visual Assist - Refactor (VA X) есть такая штука как Move implementation to source file. И это примерно то что надо. Но он вроде как не работает из командной строки и ещё не умеет Move implementation to header file.
Страницы: 1 2
ФлеймФорумПрограммирование

Тема в архиве.