0

I'd like to ask this question on a very generic level: How far does the support of container types by boost::spirit / boost::fusion reach? Can anybody give me some generic guidance on what is possible and what is not possible?

With "support" I mean the following: With the following parser definition I can parse directly into a 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;
};

Do I understand it correctly that the whole "magick" is done by boost::fusion? With that in mind let me define that: pair of doubles is supported.

I have found working examples for the following:

 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

and I have worked out the following:

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

So, I further say that:

  • vector of strings
  • simple name-value maps
  • vector of vector of POD-types
  • boost::variant
  • structs

are supported by boost::spirit / boost::fusion.

But, does it also work with the other STL containers? Are generally all of them supported or are there some that don't work? What about the boost::containers? How about nested containers? How deeply can they be nested? How about nested structs? What do I need to understand to identify whether a container is possible to use with boost::spirit / boost::fusion?

Background: I'm trying to parse into slightly more complex types like this struct table with a boost::multi_array and a "vector of map of double and struct":

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;
};

Currently I'm just working it out with trial-and-error.

user23573
  • 2,479
  • 1
  • 17
  • 36
  • It is very unclear what "support" you expect from the named libraries. I for one don't know support for any container beyond `array<>` from fusion. And nested support never existed for Spirit. Unless you can clarify what you mean by that. – sehe Apr 30 '15 at 14:21
  • @sehe, sorry to be unclear. English is not my mother-tongue. I'll try to rephrase it. – user23573 Apr 30 '15 at 16:11
  • The English is fine. Try to be more specific about what constitutes support – sehe Apr 30 '15 at 16:16
  • Perhaps this question becomes obsolete; I'm slowly getting to understand the issues I brought up with this question. Disregarding the advice in the `boost::spirit` documentation **"This section is not for the faint of heart."** (in section "Parsers in Depth") actually helped quite a lot. – user23573 May 01 '15 at 14:47

2 Answers2

0

boost::spirit handles arbitrary nesting pretty well, you are only limited by your compiler and hardware limits.

You may need to (non-intrusively) adapt your classes and structures, so that boost::spirit can parse directly into them. See Employee - Parsing into structs example.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • I know about that example, I've studied it up and down. My problem are the more complex types like `std::vector>>`. I've had now a mild success with `std::map >`. But I need to get further. – user23573 Apr 30 '15 at 16:09
0

Apparently I am about the only person interested in using boost::multi_array together with boost::spirit. There was some interest int the same question back in 2010 by Stephen Torri.

I have made progress with the struct table; above. The nested vectors, map and structs are well supported by boost::fusion. However, boost::multi_array is still waiting for a solution. One of the biggest stumble blocks is the notorious lack of good examples. (I'll possibly add some examples later)

The solutions to nested vectors and maps were sparked by the study of the "Parsers in Depth" section of the boost::spirit documentation. I'd like to stress again my previous statement in a comment above: Disregard the advice in the boost::spirit documentation: "This section is not for the faint of heart." It contains valuable information that is absolutely required as soon as you leave the very trivial examples. Another important point is to understand the relations between the boost libraries itself:

  • fusion: a library for serializing any datatype. It is used for the "automatic" data propagation within the spirit grammar.
  • phoenix: a library for functional programming.
  • spirit: the parser library itself. it is built with and on top of phoenix. Functional programming is the key to understand the parsers and the semantic actions.

For the boost::multi_array I decided to follow another path: semantic actions. Although they are frowned upon in the boost::spirit community, I've decided to use them because I also have to perform some transformations in the arrays. With boost::phoenix I'm (nearly) able to populate the arrays without relying on boost::fusion.

user23573
  • 2,479
  • 1
  • 17
  • 36