2015-04-30 3 views
0

Я бы хотел задать этот вопрос на очень общем уровне: насколько поддерживается поддержка типов контейнеров boost :: spirit/boost :: fusion? Может ли кто-нибудь дать мне общее руководство относительно того, что возможно, а что невозможно?Какие типы контейнеров поддерживаются парсером boost :: spirit и boost :: fusion?

С «Поддержка» Я имею в виду следующее: При следующем определении парсера я могу разобрать непосредственно в std::pair<double,double>:

template <typename Iterator> 
struct pair_parser 
    :  qi::grammar<Iterator, std::pair<double,double>()> 
{ 
    pair_parser() : pair_parser::base_type(start) 
    { 
     start = pair; 
     pair = qi::double_ >> ":" >> qi::double >> ";" 
    } 
    qi::rule<Iterator, std::pair<double,double>()> pair; 
}; 

ли я правильно понимаю, что вся «магия» делается boost::fusion? Имея это в виду, позвольте мне определить, что: поддерживается пара парных разрядов.

Я нашел рабочие примеры для следующих целей:

std::vector<std::string> 
std::map<std::string, std::string> // the trick is not to forget the pair within 
std::vector<std::vector<int> > 
struct A{int, double, std::string} // with boost::fusion adaptor 

и я выработал следующее:

std::map<std::string, boost::variant<int, double, std::string> > 

Итак, я также сказать, что:

  • вектор строк
  • простого имя-значение карты
  • вектора вектора POD-типов
  • наддув :: варианта
  • Структуры

поддерживается по boost::spirit/boost::fusion.

Но он также работает с другими контейнерами STL? Как правило, все они поддерживаются или есть некоторые, которые не работают? Как насчет boost :: контейнеров? Как насчет вложенных контейнеров? Насколько глубоко они могут быть вложены? Как насчет вложенных структур? Что мне нужно понять, чтобы определить, можно ли использовать контейнер с boost::spirit/boost::fusion?

фона: Я пытаюсь разобрать на несколько более сложных типов, как это struct table с boost::multi_array и «вектор карты двойной и структуры»:

struct skewFactor{ 
    double horizontalSkew; 
    double verticalSkew; 
    double factor; 
}; 
struct table { 
    std::vector<std::vector<double> > index; 
    boost::multi_array<double,4> baseArray; // yes, this array is 4-dimensional 
    std::vector<std::map<double, skewFactor> > effect; 
}; 

В настоящее время я просто работаю это с пробной ошибкой.

+0

Очень непонятно, какую «поддержку» вы ожидаете от названных библиотек. Я для одного не знаю поддержки для любого контейнера за пределами 'array <>' от fusion. И вложенная поддержка никогда не существовала для Духа. Если вы не сможете прояснить, что вы подразумеваете под этим. – sehe

+0

@sehe, извините, что не понял. Английский язык не мой родной язык. Я постараюсь перефразировать его. – user23573

+0

Английский язык в порядке. Постарайтесь уточнить, что составляет поддержку – sehe

ответ

0

По-видимому, я являюсь единственным, кто заинтересован в использовании boost::multi_array вместе с boost::spirit. Был некоторый интерес к тому же вопросу еще в 2010 году Stephen Torri.

Я достиг прогресса с struct table; выше.Вложенные векторы, карты и структуры хорошо поддерживаются boost::fusion. Однако boost::multi_array все еще ждет решения. Одним из самых больших препятствий является пресловутый недостаток хороших примеров. (Я, возможно, добавлю несколько примеров позже)

Решения для вложенных векторов и карт были вызваны изучением раздела «Парсеры в глубине» документации boost::spirit. Я хотел бы еще раз подчеркнуть свое предыдущее заявление в комментарии выше: Пренебрежение советом в boost::spirit documentation: «Этот раздел не для слабонервных». Он содержит ценную информацию, которая абсолютно необходима, как только вы оставите очень тривиальные примеры. Другим важным моментом является то, чтобы понять отношения между форсирования библиотеки себе:

  • фьюжн: библиотека для сериализации любого типа данных. Он используется для «автоматического» распространения данных в духе грамматики.
  • phoenix: библиотека для функционального программирования.
  • дух: сама библиотека парсера. он построен с фениксом и поверх него. Функциональное программирование - это ключ к пониманию парсеров и семантических действий.

Для boost::multi_array Я решил пойти по другому пути: семантические действия. Хотя они недовольны сообществом boost::spirit, я решил использовать их, потому что мне также нужно выполнить некоторые преобразования в массивах. С boost::phoenix Я (почти) способен заполнить массивы, не полагаясь на boost::fusion.

0

boost::spirit обрабатывает произвольное вложение довольно хорошо, вы ограничены только вашими ограничениями на компилятор и оборудование.

Возможно, вам понадобится (не навязчиво) адаптировать свои классы и структуры, чтобы boost::spirit мог разобрать прямо в них. См. Пример Employee - Parsing into structs.

+0

Я знаю об этом примере, я изучал его вверх и вниз. Моя проблема заключается в более сложных типах: std :: vector >> '. У меня был слабый успех с помощью: std :: map > '. Но мне нужно идти дальше. – user23573

 Смежные вопросы

  • Нет связанных вопросов^_^