Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Кодогенераторы. Собираем. Делимся. 
:(
    Опции темы
borisbn
Дата 17.6.2012, 12:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Всем привет.

Захотелось создать такую тему, где можно было бы поделиться различными кодогенераторами.
Отчасти - чтобы потешить тщеславие, отчасти - поделиться, отчасти - найти что-то полезное, отчасти - заполучить тестеров нахаляву )))

Предлагаю собрать в теме либо свои наработки, либо ссылки на готовые кодогенераторы.
Начнём-с.

Программа, создающая имплементацию по данному ей интерфейсу. Представьте, Вы создали h-файл с таким вот классом
Код
class IFace
{
public:
    virtual ~IFace(){}
    virtual void foo() = 0;
    virtual int bar( int ) = 0;
// и ещё с десяток подобных ф-ций
};

Теперь, чтобы создать имплементацию, Вы делаете довольно много черновой работы:
1) создать h-ник с именем что-нибудь типа IFaceImpl.h
2) написать в нём
Код
#include "IFace.h"
class IFaceImpl : public IFace

3) скопировать из IFace.h все функции (кроме деструктора) и поудалять в них "=0"
4) создать cpp-к с именем что-нибудь типа IFaceImpl.cpp
5) написать в нём
Код
#include "IFaceImpl.h"

6) скопировать из IFaceImpl.h все функции и подабавлять к ним IFaceImpl:: плюс { и }

Предлагается автоматизировать эту работу таким вот скриптиком
Цитата
make_impl.py /path/to/file/IFace.h IFaceImpl

код - http://pastebin.com/dQsFF3DL
Параметры запуска:
Цитата
make_impl.py <h-file> [impl-class-name | :ask]

если в качестве второго параметра задать :ask, то скрипт спросит имя класса имплементации:
user posted image

Это сообщение отредактировал(а) borisbn - 17.6.2012, 12:32


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Dem_max
Дата 17.6.2012, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



выложи готовый EXE


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
alexvs11
Дата 17.6.2012, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



а flex/bison на что?
PM MAIL   Вверх
boostcoder
Дата 17.6.2012, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата

выложи готовый EXE 

это же пайтон.

Добавлено через 1 минуту и 25 секунд
Цитата(alexvs11 @  17.6.2012,  13:22 Найти цитируемый пост)
flex/bison

а разве они умеют выполнять подобную задачу без тонны Сишной обвязки? оО

Это сообщение отредактировал(а) boostcoder - 17.6.2012, 13:23
PM WWW   Вверх
alexvs11
Дата 17.6.2012, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



Цитата(boostcoder @  17.6.2012,  13:22 Найти цитируемый пост)
а разве они умеют выполнять подобную задачу без тонны Сишной обвязки? оО

для такой задачи из сишной обвязки там будет fopen и fprintf

Добавлено через 2 минуты и 1 секунду
точнее просто printf
PM MAIL   Вверх
borisbn
Дата 17.6.2012, 13:40 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(Dem_max @  17.6.2012,  13:13 Найти цитируемый пост)
выложи готовый EXE 

py2exe в руки

Цитата(alexvs11 @  17.6.2012,  13:22 Найти цитируемый пост)
а flex/bison на что? 

оно, возможно, и правильнее, но во-первых, я его почти не знаю, а во-вторых, там всё как-то сложно для такой простой задачки



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 17.6.2012, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(alexvs11 @ 17.6.2012,  13:28)
Цитата(boostcoder @  17.6.2012,  13:22 Найти цитируемый пост)
а разве они умеют выполнять подобную задачу без тонны Сишной обвязки? оО

для такой задачи из сишной обвязки там будет fopen и fprintf

Добавлено @ 13:30
точнее просто printf

раз все так просто - реквестирую реализацию с использованием flex|bison.

спасибо!

PM WWW   Вверх
borisbn
Дата 17.6.2012, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Attention!!!
Обратите внимание, что я ищу имя функции для вставки в cpp-шник как "какое-нибудь-слово" и затем открывающая скобка. Это не будет работать, если функция возвращает указатель на функцию, например
Код
bool (*)(int) getFunction() = 0;
или
std::function< bool(int) > getF() = 0;


и ещё не отслеживается такая ситуация (лень было)))
Код
/*
    virtual void foo() = 0;
*/


Добавлено через 2 минуты и 54 секунды
Господа, а чего только мой опус обсуждаем ? Что, нечем поделиться ? Можно своё, можно ссыль на готовое.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Randajad
Дата 17.6.2012, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



А нечем своим делиться!
Лично я не так часто пишу стопицот классов, так что эта тулза вряд-ли принесет какой-либо толк. :(
PM MAIL   Вверх
alexvs11
Дата 17.6.2012, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



Цитата(boostcoder @  17.6.2012,  13:42 Найти цитируемый пост)
раз все так просто - реквестирую реализацию с использованием flex|bison.спасибо!

сейчас попробуем забацать smile 
PM MAIL   Вверх
boostcoder
Дата 17.6.2012, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(alexvs11 @  17.6.2012,  14:35 Найти цитируемый пост)
сейчас попробуем забацать

очень хотелось бы взглянуть smile

Добавлено через 2 минуты и 55 секунд
Цитата(borisbn @  17.6.2012,  13:49 Найти цитируемый пост)
Это не будет работать, если функция возвращает указатель на функцию

и еще в нескольких случаях.
не зря же у С++ самый сложный синтаксис. к тому же, и контекстозависимый. так что, я не думаю что сходу можно реализовать парсер корректно обрабатывающий сабж во всех возможных комбинациях факторов.

libclang в руки!
PM WWW   Вверх
alexvs11
Дата 17.6.2012, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



ну примерно так

входной файл
IFace.h
Код

class IFace
{
public:
    virtual ~IFace(){}
    IFace(int a);
    virtual void foo(float, double) = 0;
    /*
     * bar function 
     */
    virtual int bar( int, double z ) = 0;
};


interf.l (flex)
Код

%{
#include <stdio.h>
#include <string.h>
#define YYSTYPE char *
#include "./interf.tab.h"
#if 0
#define _ printf("%d [%s]\n", __LINE__, yytext); 
#else
#define _
#endif
extern YYSTYPE yylval;
%}
%option yylineno
%option noyywrap
%%
"/*"([^\*]|\*[^/])*"*/"         { yylval=strdup(yytext); _; return COMMENT; }
[:(){};=~,]                     { _; return yytext[0];                      }
const|long|short|\*             { yylval=strdup(yytext); _; return MOD;     }
int|void|float|double|char      { yylval=strdup(yytext); _; return TYPE;    }
public|private|protected        { yylval=strdup(yytext); _; return ACCESS;  }
"class"                         { _; return CLASS;                          }
"virtual"                       { _; return VIRTUAL;                        }
"0"                             { _; return '0';                            }
[+\-0-9][0-9]*                  { yylval=strdup(yytext); _; return DIGIT;  }      
[_a-zA-Z][a-zA-Z0-9]*           { yylval=strdup(yytext); _; return IDENT;   }
[ \t\n]+                        { }

%%


interf.y (bison)
Код

%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define YYERROR_VERBOSE 1
#define YYSTYPE char*
#define IDENT_MAX (4)
#define IDENT_NAME_MAX (80)
#define ARGS_LIST_LENGTH (80)
#define BODY_LENGTH (10000)
#define eos(s) (s + strlen(s))

int yylineno;
char ident_name_table[IDENT_NAME_MAX][IDENT_MAX];
char class_name[IDENT_NAME_MAX];
char sub_class_name[IDENT_NAME_MAX];
char args_list[ARGS_LIST_LENGTH] = {};
char arg[50];
char body[BODY_LENGTH] = {};
YYSTYPE yylval;

typedef enum {
  HPP_FILE,
  CPP_FILE
} FILE_TYPE;

FILE_TYPE ftype;

void yyerror(const char *str) {
 fprintf(stderr, "\n error: string N  %u, %s\n", yylineno, str);
}

void add_arg(char* type, char* name) {
 if (strlen(args_list)) strcat (args_list, ", ");
 strcat (args_list, type);
 if (name) { strcat (args_list, " "); strcat (args_list, name); }
}

char* get_arg_list(void) {
 return strdup(args_list);
}

void clear_list(void) {
 args_list[0] = '\0';
}

%}

%token TYPE CLASS VIRTUAL ACCESS IDENT DIGIT COMMENT MOD
%start pro

%%

pro: CLASS IDENT '{' body '}' ';' { 
                                    if (ftype == HPP_FILE) {  
                                      printf ("#include \"%s.h\"\n\nclass %s : public %s {\n%s\n};\n", 
                                      $2, sub_class_name, $2, body); 
                                    } else {
                                      printf ("#include \"%s.h\"\n\n%s\n", 
                                      sub_class_name, body); 
                                    }
                                  }
      ;
body: | body ACCESS ':'                 { if (ftype == HPP_FILE) sprintf (eos(body), "%s: \n", $2); }
      | body method                     { }
      | body COMMENT                    { sprintf (eos(body), "\t%s\n", $2); }
      ;
method: TYPE IDENT '(' typelist ')' ';'                 { 
                                                           if (ftype == HPP_FILE) sprintf (eos(body), "\t%s %s (%s);\n", $1, $2 ,$4);
                                                           else sprintf (eos(body), "%s %s::%s (%s);\n\n", $1, sub_class_name, $2 ,$4);
                                                        }
      | VIRTUAL TYPE IDENT '(' typelist ')' ';'         { 
                                                           if (ftype == HPP_FILE) sprintf (eos(body), "\tvirtual %s %s (%s);\n", $2, $3 ,$5); 
                                                           else sprintf (eos(body), "%s %s::%s (%s);\n\n", $2, sub_class_name, $3 ,$5);
                                                        }
      | VIRTUAL TYPE IDENT '(' typelist ')' '=' '0' ';' { 
                                                           if (ftype == HPP_FILE) sprintf (eos(body), "\tvirtual %s %s (%s);\n", $2, $3 ,$5); 
                                                           else sprintf (eos(body), "%s %s::%s (%s){\n\n}\n\n", $2, sub_class_name, $3 ,$5); 
                                                        }
      | IDENT '(' typelist ')' ';'                      { 
                                                           if (ftype == HPP_FILE) sprintf (eos(body), "\t%s (%s);\n", sub_class_name, $3); 
                                                           else sprintf (eos(body), "%s::%s (%s){\n\n}\n\n", sub_class_name, sub_class_name, $3); 
                                                        }
      | VIRTUAL '~' IDENT '(' ')' '{' '}'               { 
                                                           if (ftype == HPP_FILE) sprintf (eos(body), "\tvirtual ~%s();\n", sub_class_name); 
                                                           else sprintf (eos(body), "%s::~%s(){\n\n}\n\n", sub_class_name, sub_class_name);  
                                                        }
      ;
typelist:         {$$ = ""}
      | tlist     {$$ = get_arg_list(); clear_list();}
      ;
tlist:  arg             { add_arg($1, NULL); }
      | tlist ',' arg   { add_arg($1, NULL); }
      ;
arg:    type IDENT   { sprintf (arg, "%s %s", $1, $2); $$ = arg; }
      | type         { sprintf (arg, "%s", $1);        $$ = arg; }
      ;
type: premodlist TYPE postmodlist {$$ = $2;}
      ;
premodlist: 
      | premodlist MOD
      ;
postmodlist: 
      | postmodlist MOD 
      ;

%%

int main(int argc, char* argv[]) {
  if (argc != 3) {
    printf ("bad command line\n");
    return 1;
  }

  strcpy (sub_class_name, argv[1]);
  char buff [IDENT_NAME_MAX+4];

  if (!strcmp(argv[2], "cpp"))    ftype = CPP_FILE;
  else if (!strcmp(argv[2], "h")) ftype = HPP_FILE;
  else {
    printf ("bad file type\n");
    return 1;
  }

  if (yyparse()) {
    printf ("error in compilation\n");
    return 1;
  } 
  
  return 0;
}


Код

bison -vtd interf.y
flex interf.l 
gcc -g interf.tab.c lex.yy.c -o interf


cat IFace.h | ./interf FaceImpl h
Код

#include "IFace.h"

class FaceImpl : public IFace {
public: 
    virtual ~FaceImpl();
    FaceImpl (int a);
    virtual void foo (int afloat, int afloatdouble);
    /*
     * bar function 
     */
    virtual int bar (int afloatdoubleint, int afloatdoubleintdouble z);

};


cat IFace.h | ./interf FaceImpl cpp
Код

#include "FaceImpl.h"

FaceImpl::~FaceImpl(){

}

FaceImpl::FaceImpl (int a){

}

void FaceImpl::foo (float, double){

}

    /*
     * bar function 
     */
int FaceImpl::bar (int, double z){

}


далеко не лучший код, просто по-быстрому набросал

Это сообщение отредактировал(а) alexvs11 - 17.6.2012, 19:25
PM MAIL   Вверх
boostcoder
Дата 17.6.2012, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



alexvs11, спасибо за пример, но выглядит страшно smile 
скажи, ты раньше с flex работал? ибо я думаю, что если с нуля, то потребовался бы не один день на это. (это к слову о простоте)

PM WWW   Вверх
alexvs11
Дата 17.6.2012, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



Цитата(boostcoder @  17.6.2012,  20:16 Найти цитируемый пост)
скажи, ты раньше с flex работал? ибо я думаю, что если с нуля, то потребовался бы не один день на это. (это к слову о простоте)

flex - это первая часть - там обыкновенные регулярки для вычленения лексем
с bison-ом посложнее - он по  БНФ строит синтаксический анализатор и выполняет соответствующие действия

я с ними действительно уже работал, и по мне там нужно просто иметь базовые представления о построении компиляторов и тогда легко освоить

так как оно предназначено для построения компиляторов - штука мощная, быстрая и расширяемая
неудобно, что генерит с-код, есть bison++ и flex++ - но я не пробовал


PM MAIL   Вверх
borisbn
Дата 17.6.2012, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



итого: скрипт на питоне - 100 строк. один файл
скрипт на flex|bison:
interf.l (flex) = 28 строк
interf.y (bison) = 132 строки
interf.l + interf.y = 160 строк
исчо: питон - кроссплатформенно, flex+bison - linux only

P.S. Господа-а-а-а-а.... просьба постить что-нить полезное. Спасибо


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1216 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.