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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> чем парсить С/С++ код? 
V
    Опции темы
boostcoder
Дата 22.11.2010, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



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

спасибо.

PM WWW   Вверх
azesmcar
Дата 22.11.2010, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



их не пишут, их генерируют.
http://en.wikipedia.org/wiki/Comparison_of_parser_generators
PM   Вверх
A5uKa
  Дата 22.11.2010, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


TЋ♥s F1rȜ iƧ BurȠiƞg
***


Профиль
Группа: Awaiting Authorisation
Сообщений: 1928
Регистрация: 30.8.2008

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



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


pattern`щик
****


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

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



Цитата(azesmcar @  22.11.2010,  12:55 Найти цитируемый пост)
их не пишут, их генерируют.

что-то там много всего) не понял что из этого выбрать?
вот мой синтаксис:
Код


class client_impl: client_side { // client_side - ключевое слово
   void set_int(int);
   void set_string(const std::string&);
   int get_int();
   int get_int(int);
};

class server_impl: server_side { // server_side - ключевое слово
   void set_int(int);
   void set_string(const std::string&);
   int get_int();
   int get_int(int);
};

class test_service: service("statistic service") { // service - ключевое слово
   test_service( // конструктор
      std::pair<int, int>& _pair,
      int _class_id,
      int _method_id
   );
   void any_method(int); // обычный метод
   void for_inkom_method() // метод, подключаемый к роутеру входящих команд. вызывается при вызове удаленной стороной методов перечисленных в []
      :incoming[
         client_impl::set_string,
         client_impl::get_int
      ];
   void for_outgo_method(): outgoing; // вызывается при любой исходящей команде
};

из этого мне нужно получить структуры которые я могу использовать в с++ коде чтоб сгенерировать метакод.

A5uKa, не очень понял, чем мне может помочь ваша ссылка...

Добавлено через 4 минуты и 18 секунд
up.

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


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Цитата(boostcoder @  22.11.2010,  13:08 Найти цитируемый пост)
что-то там много всего) не понял что из этого выбрать?

например antlr

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


pattern`щик
****


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

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



Цитата(azesmcar @  22.11.2010,  13:13 Найти цитируемый пост)
например antlr

посмотрел и понял, сходу не напишешь smile 
прям целая наука..

Добавлено через 36 секунд
напишу ка я по старинке smile 
PM WWW   Вверх
azesmcar
Дата 22.11.2010, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Цитата(boostcoder @  22.11.2010,  13:26 Найти цитируемый пост)
посмотрел и понял, сходу не напишешь  
прям целая наука..

Добавлено через 36 секунд
напишу ка я по старинке   

то, что имеет смысл писать на генераторах парсеров "по старинке" не напишешь smile 
PM   Вверх
MAKCim
Дата 22.11.2010, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



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

самое сложное как раз грамматика


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
boostcoder
Дата 22.11.2010, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(azesmcar @  22.11.2010,  13:49 Найти цитируемый пост)
то, что имеет смысл писать на генераторах парсеров "по старинке" не напишешь

ну да smile 
но у меня задача простая.

всем спасибо. вопрос закрыт.

Добавлено через 1 минуту и 22 секунды
Цитата(MAKCim @  22.11.2010,  13:52 Найти цитируемый пост)
для начала нужна грамматика
потом любой генератор взять и реализовать грамматику на нем

самое сложное как раз грамматика 

а что в моем случае является грамматикой? smile 
PM WWW   Вверх
MAKCim
Дата 22.11.2010, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(boostcoder @  22.11.2010,  13:52 Найти цитируемый пост)
а что в моем случае является грамматикой?

это я должен знать?  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
baldina
Дата 22.11.2010, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



boostcoder, тебе ведь не парсер, а шаблонизатор нужен. потому и уверенность, что "по старинке" будет проще.
а не проще ли будет стандартными средствами языка воспользоваться: контейнерами, шаблонами?
а если эти "метаструктуры" - результат нечеловеческого труда (т.е. генерируются программно), почему бы сразу не генерить С++.
PM MAIL   Вверх
boostcoder
Дата 22.11.2010, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(baldina @  22.11.2010,  15:39 Найти цитируемый пост)
а не проще ли будет стандартными средствами языка воспользоваться: контейнерами, шаблонами?

контейнерами и шаблонами из с++ ?

Цитата(baldina @  22.11.2010,  15:39 Найти цитируемый пост)
а если эти "метаструктуры" - результат нечеловеческого труда (т.е. генерируются программно), почему бы сразу не генерить С++

сразу с++ и генерится. но из некоторого метасинтасиса. с++ подобного. с моими наваротами smile 
PM WWW   Вверх
baldina
Дата 22.11.2010, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



да. контейнеры, шаблоны, перегрузка операций - все это в с++ позволяет расширить синтаксис. в известных пределах, конечно, но для многих задач хватает.
неплохие примеры - boost::spirit, boost::signal. интересно сравнить последнюю с сигналами в qt


PM MAIL   Вверх
boostcoder
Дата 22.11.2010, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(baldina @  22.11.2010,  17:01 Найти цитируемый пост)
да. контейнеры, шаблоны, перегрузка операций - все это в с++ позволяет расширить синтаксис. в известных пределах, конечно, но для многих задач хватает.

гм... вы наверное меня не правильно поняли...прочтите тему сначала.

Цитата(baldina @  22.11.2010,  17:01 Найти цитируемый пост)
boost::signal. интересно сравнить последнюю с сигналами в qt

а чего там сравнивать? boost::signals сделаны для людей smile 
PM WWW   Вверх
baldina
Дата 22.11.2010, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



типа
Код

class test_service: service("statistic service") { // service - ключевое слово
   test_service( // конструктор
      std::pair<int, int>& _pair,
      int _class_id,
      int _method_id
   );
   void any_method(int); // обычный метод
   void for_inkom_method() // метод, подключаемый к роутеру входящих команд. вызывается при вызове удаленной стороной методов перечисленных в []
      :incoming[
         client_impl::set_string,
         client_impl::get_int
      ];
   void for_outgo_method(): outgoing; // вызывается при любой исходящей команде
};

vs
Код

struct outgoing_base {
  virtual void operator()()=0;
};

template<...>
struct incoming {
  virtual void operator()()=0;
};

class test_service: service<statistic_service_tag> { // service - шаблонный класс
   test_service( // конструктор
      std::pair<int, int>& _pair,
      int _class_id,
      int _method_id
   );

   struct outgoing : public outgoing_base {
       void operator()() { ... }
   };

   template<>
   struct incoming : public incoming_base <clir_ouent_impl::set_string, client_impl::get_int> {
       void operator()() { ... }
   };

   void any_method(int); // обычный метод
   incoming for_inkom_method;
   outgoing fotgo_method; // outgoing::operator()() вызывается при любой исходящей команде
};

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


pattern`щик
****


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

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



baldina, вы точно меня не правильно поняли.
PM WWW   Вверх
baldina
Дата 22.11.2010, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



читал
Цитата

пишу метагенератор для своего проекта

может и не понял. поясните плиз.
как я понимаю, метагенератор нужен для преобразования чего-то в С++
тут два варианта:
1. метакод генерируется автоматически (например, программой-визуальным конструктором). зачем тогда генерить метакод, если можно сразу С++
2. метакод пишется вручную (т.е. полагается, что метакод проще и выразительней). в этом случае предлагаю рассмотреть языковые возможности С++ как альтернативу метакоду

Добавлено через 4 минуты и 12 секунд
(есть еще третий вариант, когда метакод генерится не Вами. тогда странно, что генерилка не комплектуется искомым генератором)

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


pattern`щик
****


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

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



Цитата(baldina @  22.11.2010,  17:16 Найти цитируемый пост)
метакод пишется вручную

ага.

Цитата(baldina @  22.11.2010,  17:16 Найти цитируемый пост)
в этом случае предлагаю рассмотреть языковые возможности С++ как альтернативу метакоду

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

из того фрагмента что я привел, генерируется 841 строка smile 
ощущаете разницу? smile 
PM WWW   Вверх
baldina
Дата 22.11.2010, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

ощущаете разницу?

ощущаю. 
в boost::spirit грамматика записывается например так:
Код

template <typename Iterator>
    struct calculator : qi::grammar<Iterator, ascii::space_type>
    {
        calculator() : calculator::base_type(expression)
        {
            using qi::uint_;

            expression =
                term
                >> *(   ('+' >> term)
                    |   ('-' >> term)
                    )
                ;

            term =
                factor
                >> *(   ('*' >> factor)
                    |   ('/' >> factor)
                    )
                ;

            factor =
                uint_
                |   '(' >> expression >> ')'
                |   ('-' >> factor)
                |   ('+' >> factor)
                ;
        }

        qi::rule<Iterator, ascii::space_type> expression, term, factor;
    };

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

Добавлено через 2 минуты и 10 секунд
ЗЫ: начните с макросов, тут ваще ниче писать не надо.
PM MAIL   Вверх
boostcoder
Дата 22.11.2010, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



baldina, мне знаком спирит. но в том, что пытаюсь сделать я, спирит мне сильно не поможет. посмотрите внимательней на мой пример синтаксиса, и скажите, чем спирит мне поможет, кроме как извлекать лексемы?

Добавлено через 20 секунд
или я чего-то не понимаю...или второе..
PM WWW   Вверх
baldina
Дата 22.11.2010, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



я не предлагал использовать spirit. я предлагал вместо отдельной программы-метагенератора написать классы, шаблоны и т.п. для расширения функций языка под свои нужды. как мог бы выглядеть результат "для конечного пользователя" я привел.
а spirit и signals всего лишь примеры такого подходя к решению задач, а не решение Вашей
PM MAIL   Вверх
xvr
Дата 22.11.2010, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Лично я для таких целей использую bison. Но у любого генератора парсеров есть некоторый порог вхождения  smile 
Но в любом случае сначала нужна грамматика, MAKCim абсолютно прав.

В вашем случае (для bison'а) она будет выглядеть как то так (это только кусок, не вся грамматика):
Код

%token tCLASS
%token tCLIENT_SIDE
%token tSERVER_SIDE
%token tSERVICE

%token vID
%token vNUM
%token vSTR

%%

parser: class_def | parser class_def ;
class_def: tCLASS vID ':' kind '{' class_body '}' ';' ;
kind: tCLIENT_SIDE | tSERVER_SIDE | tSERVICE '(' vSTR ')' ;
class_body: | class_body class_body_item ;
class_body_item: constructor | member  ;

constructor: и т.д. и т.п.

member: и т.д. и т.п.

Если у вас используется большое подмножество С++ - то проще будет сразу застрелится  smile 

PM MAIL   Вверх
baldina
Дата 22.11.2010, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



вы сделали вывод 
Цитата

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

тут одно из двух, либо Вы правы, либо недостаточно представляете возможности С++  smile 
PM MAIL   Вверх
boostcoder
Дата 22.11.2010, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(baldina @  22.11.2010,  18:01 Найти цитируемый пост)
я предлагал вместо отдельной программы-метагенератора написать классы, шаблоны и т.п. для расширения функций языка под свои нужды

в результате получится что я напишу еще один спирит smile 
испорченный телефон...я вам о том, что мне нужно распарсить мой синтаксис чтоб из него сгенерировать с++ код. вы же мне предлагаете написать классы+шаблоны для этого...невъезжаю smile 
Цитата(baldina @  22.11.2010,  18:05 Найти цитируемый пост)
либо недостаточно представляете возможности С++

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


ладно..пока общались, написал.
всем спасибо.

Добавлено через 1 минуту и 56 секунд
xvr, отдельное спасибо за помощь.
PM WWW   Вверх
baldina
Дата 22.11.2010, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



boostcoder, Вы не поняли. Не для распарсивания Вашего синтаксиса, а для отказа от него. (щас пойдем плясать по кругу)
ладно, решили задачу - и хорошо. хотя жаль...
PM MAIL   Вверх
mes
Дата 22.11.2010, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(baldina @  22.11.2010,  17:23 Найти цитируемый пост)
 Не для распарсивания Вашего синтаксиса, а для отказа от него..

поддерживаю smile

Это сообщение отредактировал(а) mes - 22.11.2010, 18:25


--------------------
PM MAIL WWW   Вверх
xvr
Дата 22.11.2010, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



2 ТС - а почему бы не взять стандартный для RPC синтакс (IDL) и не изобретать велосипед?

PM MAIL   Вверх
boostcoder
Дата 22.11.2010, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(xvr @  22.11.2010,  18:28 Найти цитируемый пост)
а почему бы не взять стандартный для RPC синтакс (IDL) и не изобретать велосипед?

в этом-то и смысл - поизобретать охота smile

Добавлено через 2 минуты и 36 секунд
Цитата(baldina @  22.11.2010,  18:23 Найти цитируемый пост)
Не для распарсивания Вашего синтаксиса, а для отказа от него.

я только ЗА!
но к пониманию того что нужно писать метагенератор я не с фонаря пришел smile 
давайте пообщаемся на эту тему. наверное я что-то недопонимаю..
PM WWW   Вверх
baldina
Дата 22.11.2010, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



тогда опишите задачу - во что (в общем, конечно  smile ) преобразуется 
Код

class test_service: service("statistic service")

Код

void for_inkom_method()
      :incoming[
         client_impl::set_string,
         client_impl::get_int
      ];

и
Код

void for_outgo_method(): outgoing;

?
PM MAIL   Вверх
mes
Дата 22.11.2010, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



и две конечные точки общения (два простых класса между которыми происходит общение без учета возможной реализации) [как раз на этом мы вроде остановились в прошлой теме]

Это сообщение отредактировал(а) mes - 22.11.2010, 18:59


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 22.11.2010, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(baldina @  22.11.2010,  18:53 Найти цитируемый пост)
в общем, конечно

это сложно..
вам нужно прочесть эту тему: http://forum.vingrad.ru/forum/topic-311688.html
 smile 

и глянуть исходники: http://code.google.com/p/discoly/source/checkout

правда.. сложно это все объяснить..
мы с mes`ом много на эту тему наобщались.

Добавлено через 9 минут и 25 секунд
Цитата(mes @  22.11.2010,  18:56 Найти цитируемый пост)
и две конечные точки общения (два простых класса между которыми происходит общение без учета возможной реализации) [как раз на этом мы вроде остановились в прошлой теме]

вот: http://code.google.com/p/discoly/source/br...client/main.cpp
сейчас еще пишу однопользовательский чат. как минималистичный пример.

Добавлено через 9 минут и 46 секунд
Цитата(boostcoder @  22.11.2010,  18:57 Найти цитируемый пост)
минималистичный

странное слово получилось smile

Добавлено через 11 минут и 12 секунд
baldina, хотя...mes Вам сможет лучше это все объяснить. если у него есть желание, конечно.
PM WWW   Вверх
mes
Дата 22.11.2010, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



или можно зайти с другой стороны.. 
Код

struct auth_agent 
{
    void identify (const std::string& wish_name);
    void quit ();

    std::string ident_name () const { return _name; }
    bool has_ident () const { return _has_ident; }

   protected:
       void on_ident (const std::string& name) { has_ident = true; _name = name; }
       void on_quit  () { has_ident = false; _name = ""; }

   private:
      std::string    _name;
      bool _has_ident;
};

Код

struct auth_service 
{
     void on_ident_query (const std::string& wish_name)
     {
          agent().on_ident(wish_name);
     }
     void on_quit_query (const std::string& wish_name)
     {
          agent().on_quit();
     }
};

вот простой пример.. допустим оба класс входят в состав одного приложения.. что надо сделать чтоб они заработали ?

При этом должна остаться возможность исключить класс auth_service  путем замыкания методов auth_agent`a друг на друга..

Добавлено через 2 минуты и 28 секунд
Цитата(boostcoder @  22.11.2010,  17:57 Найти цитируемый пост)
хотя...mes Вам сможет лучше это все объяснить. если у него есть желание, конечно.

на том моменте, где мы закончили тему.. я сам не до конца понимаю в какую сторону Вы тяните smile

Добавлено через 3 минуты и 11 секунд
Цитата(boostcoder @  22.11.2010,  17:57 Найти цитируемый пост)
вот: http://code.google.com/p/discoly/source/br...client/main.cpp
сейчас еще пишу однопользовательский чат. как минималистичный пример.

уже скоро уходить.. гляну чуть позже.. 

Это сообщение отредактировал(а) mes - 22.11.2010, 19:13


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 22.11.2010, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(mes @  22.11.2010,  19:11 Найти цитируемый пост)
допустим оба класс входят в состав одного приложения.. что надо сделать чтоб они заработали ?

присвоить классам/методам ID`ы. зарегать методы по ID`ам.

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


Эксперт
****


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

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



boostcoder, я ту тему читал. местами. слишком многа букаф))
если я правильно понял, ведется разработка чего-то клиент-серверного, типа RPC: сервер умеет методы, клиент должен их вызывать, причем заранее все методы неизвестны, но вызов на клиенте должен органично вписываться в код.
подобное уже делали, напр. CORBA, COM.

то, что в том топике, мне ясно. и ответы на заданные вопросы тоже (скажу тут, что бы туды-сюды не бегать):
Цитата

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

сервер. что ему знать зависит от реализации. например, уникальный ID метода. ну, это Вы сами ответили.
клиент. ему надо знать перечень ID и передавать их на сервер.
это просто, но не могу не удержаться от замечания. подобные вещи - "сервер публикует список идентификаторов методов; клиент передает идентификатор для вызова метода сервера; сервер по идентификатору определяет метод и вызывает его; сервер проверяет корректность вызова по числу и типу параметров" и т.д. определяются до реализации, это часть постановки задачи.

теперь к нашим баранам. я чуть догадываюсь, к чему код примера в этом топике, но хотелось бы послушать первоисточник.

соображение, которое есть сразу:
допустим есть код
Код

// декларация интерфейса некоторого типа.
INTERFACE_BEGIN(transaction_type)
   METHOD(
      std::string, // ret
      login, // method name
      std::string, // method arg
      std::string // method arg
   )
   METHOD(
      std::string, // ret
      get_balance, // method name
      std::string, // method arg
      std::string // method arg
   )
INTERFACE_END()
// код клиента
client<transaction_type> client(host, port);
std::string ret = client.login("nick", "pass");
ret = client.get_balance("date from", "date to");

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

struct transaction_type : public interface {
  method<std::string(std::string,std::string)> login;
  method<std::string(std::string,std::string)> get_balance;
};


Добавлено через 6 минут и 31 секунду
забыл: методы надо с сервером связывать. значит как-то указывать идентификатор, типа
Код

method<RPID_LOGIN, std::string(std::string,std::string)> login;

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


Эксперт
****


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

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



кажись не там я читал. вот оно:
Цитата

предполагаю реализовать раздельную генерацию кода для клиента и сервера. будут использоваться два зарезервированных ключевых слова: server_side и client_side

а что если
Код

template <int id>
struct method {
  method ()
  {
     register (id); // реализация register отличается для сервера и клиента
  }
};

struct interface; // реализация interfaceотличается для сервера и клиента
struct some_interface : public interface {
  method<1> m1;
  method<2> m2;
};

заголовок один, сервер это или клиент определяется во время компиляции

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


pattern`щик
****


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

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



Цитата(baldina @  22.11.2010,  20:20 Найти цитируемый пост)
подобное уже делали, напр. CORBA, COM.

угу.

Цитата(baldina @  22.11.2010,  20:20 Найти цитируемый пост)
определяются до реализации, это часть постановки задачи

определяются кем? прогером? вручную? smile 
у меня же, это обязанность метагенератора.

Цитата(baldina @  22.11.2010,  20:20 Найти цитируемый пост)
допустим есть код

от этого кода я давно ушел.
да, когда-то метагенератор был написан на препроцессоре. но с расширением потребностей, от препроцессорного метагенератора пришлось отказаться. некоторые моменты с его помощью не реализуемы.

Цитата(baldina @  22.11.2010,  20:20 Найти цитируемый пост)
не вижу абсолютно ничего, что мешало бы так делать клиенту.

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

Добавлено через 4 минуты
Цитата(baldina @ 22.11.2010,  20:37)
кажись не там я читал. вот оно:
Цитата

предполагаю реализовать раздельную генерацию кода для клиента и сервера. будут использоваться два зарезервированных ключевых слова: server_side и client_side

а что если
Код

template <int id>
struct method {
  method ()
  {
     register (id); // реализация register отличается для сервера и клиента
  }
};

struct interface; // реализация interfaceотличается для сервера и клиента
struct some_interface : public interface {
  method<1> m1;
  method<2> m2;
};

заголовок один, сервер это или клиент определяется во время компиляции

Добавлено @ 20:38
мысль забурлила  smile 
пойду полезным займусь, вернусь позже

а теперь представьте...5-20 классов(каждого от 5ти методов), и соответственно 5-20 интерфейсов. и еще не забудьте, что все это назначать вам придется в ручную.
PM WWW   Вверх
boostcoder
Дата 22.11.2010, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



вот общий пример.
все просто. ничего лишнего.
Код


#include "decl1.hpp"

/***************************************************************************/

namespace discoly {
namespace impl {

struct client_side: i_client_side {
   client_side(detail::distributor& d):i_client_side(d) {}

   void set_int(int i) {
      std::cout << "client_side::set_int(" << i << ");" << std::endl;
   }

   void set_string(const std::string& s) {
      std::cout << "client_side::set_string(" << s << ");" << std::endl;
   }

   int get_int() {
      std::cout << "client_side::get_int();" << std::endl;
      return time(0);
   }
};

/***************************************************************************/

struct server_side: i_server_side {
   server_side(detail::distributor& d):i_server_side(d) {}

   void set_int(int i) {
      std::cout << "server_side::set_int(" << i << ");" << std::endl;
   }

   void set_string(const std::string& s) {
//      std::cout << "server_side::set_string(" << s << ");" << std::endl;
   }
};

} // namespace impl;
} // namespace discoly

typedef boost::mpl::vector<discoly::impl::client_side> client_metacontainer;
typedef boost::mpl::vector<discoly::impl::server_side> server_metacontainer;
/***************************************************************************/

void ping_time(boost::uint32_t pt) {
   std::cout << "ping time = " << pt << std::endl;
}

void query_timeout() {
   std::cout << "query_timeout" << std::endl;
}

std::string mega_string(boost::uint32_t size) {
   std::string res;
   for ( boost::uint32_t idx = 0; idx < size; ++idx ) {
      res += "abcdefghi1234567890k";
   }
   return res;
}

/***************************************************************************/

void client_disconnect() {
   std::cout << "client receive disconnect" << std::endl;
}
void server_disconnect() {
   std::cout << "server receive disconnect" << std::endl;
}

void as_callback() {
   std::cout << "as_callback()" << std::endl;
}

/***************************************************************************/

using namespace discoly;
int main() {
   try {
      const boost::uint16_t port = 44550;
      net_server<server_metacontainer> server(port);
      server.set_ping_callback(ping_time);
      server.set_on_disconnect(server_disconnect);
      ifaces::client_side::shared_ptr c = server.get<ifaces::client_side>();

      net_client<client_metacontainer> client("127.0.0.1", port);
      client.set_ping_callback(ping_time);
      client.set_on_disconnect(client_disconnect);
      ifaces::server_side::shared_ptr s = client.get<ifaces::server_side>();
      for ( size_t count = 0; true; ++count ) {
         s->set_int((int)time(0));
         s->set_string("33");

         c->set_int((int)time(0)+10);
         c->set_string("44");

         if ( count == 10 ) {
            client.disconnect();
         }

         if ( count == 5 ) {
            std::vector<std::string> services = client.query_services(query_timeout);
            std::copy(services.begin(), services.end(), std::ostream_iterator<std::string>(std::cout, ", "));
            std::cout << std::endl;
         }
         if ( count % 3 ) {
            s->set_string(mega_string(100));
         }

         if ( count % 7 ) {
            client.disconnect();
            server.disconnect();
         }

         c->get_int();
//         int v1 = c->get_int().as<int>(as_callback);
//         std::cout << "v = " << v1 << std::endl;

//         boost::uint64_t v2 = c->get_int();
//         boost::uint32_t v3 = c->get_int();

         boost::this_thread::sleep(boost::posix_time::milliseconds(1));
      }
   } catch ( const std::exception& e ) {
      std::cout << "int main(): " << e.what() << std::endl;
   } catch ( ... ) {
      std::cout << "int main(): unknown exception" << std::endl;
   }
}

/***************************************************************************/

вверху реализации классов клиента и сервера.
так же, обратите внимание на:
Код

ifaces::client_side::shared_ptr c = server.get<ifaces::client_side>();

так получаем интерфейс для реализации client_side. т.е. работаем с полученным интерфейсом, как будто с указателем на реализацию.
но сами интерфейсы тоже генерит метагенератор. и там не мало кода. пусть и не сложного, но рутинного. и писать его для кучи классов/методов мало кому интересно.
PM WWW   Вверх
mes
Дата 23.11.2010, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(boostcoder @  22.11.2010,  20:21 Найти цитируемый пост)
все просто. ничего лишнего.

наличие net_servera и net_clienta уже лишнее.. библиотека не должна зависить от того находятся ли два класса в одном приложении или на концах сети.. 

Цитата(boostcoder @  22.11.2010,  20:21 Найти цитируемый пост)
так получаем интерфейс для реализации client_side. т.е. работаем с полученным интерфейсом, как будто с указателем на реализацию.

но почему client_side является, как вы говорите, зарезервированным ? допустимее что будет 
client_facet_1, client_facet_2, client_facet_3.. 

сам код пока не смотрел.. 



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 23.11.2010, 01:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(mes @  23.11.2010,  00:09 Найти цитируемый пост)
наличие net_servera и net_clienta уже лишнее.. библиотека не должна зависить от того находятся ли два класса в одном приложении или на концах сети.. 

она и независит. укажите этим классам другие IP/port и поведение будет то же.

Цитата(mes @  23.11.2010,  00:09 Найти цитируемый пост)
но почему client_side является, как вы говорите, зарезервированным ?

это просто ключевое слово. можно назвать по другому. не в этом суть.

Цитата(mes @  23.11.2010,  00:09 Найти цитируемый пост)
client_facet_1, client_facet_2, client_facet_3.. 

ну и?
PM WWW   Вверх
mes
Дата 23.11.2010, 01:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(boostcoder @  23.11.2010,  00:41 Найти цитируемый пост)
она и независит. укажите этим классам другие IP/port и поведение будет то же.

а если совсем без сокетов ?

Цитата(boostcoder @  23.11.2010,  00:41 Найти цитируемый пост)
это просто ключевое слово. можно назвать по другому. не в этом суть.

ну так я и не к самому названию цепляюсь.. у вас деление на клиент/сервис идет между объектами или приложениями ?





--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 23.11.2010, 01:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(mes @  23.11.2010,  01:52 Найти цитируемый пост)
а если совсем без сокетов ?

как тогда им общаться?
Цитата(mes @  23.11.2010,  01:52 Найти цитируемый пост)
у вас деление на клиент/сервис идет между объектами или приложениями ?

ни так, и ни так.
эти ключевые слова используются только для раздельной генерации.
PM WWW   Вверх
boostcoder
Дата 23.11.2010, 04:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



baldina, в контексте данной темы, обсуждение RPC/CORBA выглядит свалившимся с луны.
если есть желание, присоединяйтесь: http://forum.vingrad.ru/forum/topic-311688.html

PM WWW   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1029 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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