Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing string, with Boost Spirit 2, to fill data in user defined struct

I'm using Boost.Spirit which was distributed with Boost-1.42.0 with VS2005. My problem is like this.

I've this string which was delimted with commas. The first 3 fields of it are strings and rest are numbers. like this.

String1,String2,String3,12.0,12.1,13.0,13.1,12.4

My rule is like this

qi::rule<string::iterator, qi::skip_type> stringrule = *(char_ - ',')
qi::rule<string::iterator, qi::skip_type> myrule= repeat(3)[*(char_ - ',') >> ','] >> (double_ % ',') ;

I'm trying to store the data in a structure like this.

struct MyStruct
{
   vector<string> stringVector ;
   vector<double> doubleVector ;
} ;

MyStruct var ;

I've wrapped it in BOOST_FUSION_ADAPT_STRUCTURE to use it with spirit.

BOOST_FUSION_ADAPT_STRUCT (MyStruct, (vector<string>, stringVector) (vector<double>, doubleVector))

My parse function parses the line and returns true and after

qi::phrase_parse (iterBegin, iterEnd, myrule, boost::spirit::ascii::space, var) ;

I'm expecting var.stringVector and var.doubleVector are properly filled. but it is not the case.

What is going wrong ?

The code sample is located here

Thanks in advance, Surya

like image 448
Surya Avatar asked Mar 18 '10 12:03

Surya


1 Answers

qi::skip_type is not something you could use a skipper. qi::skip_type is the type of the placeholder qi::skip, which is applicable for the skip[] directive only (to enable skipping inside a lexeme[] or to change skipper in use) and which is not a parser component matching any input on its own. You need to specify your specific skipper type instead (in your case that's boost::spirit::ascii:space_type).

Moreover, in order for your rules to return the parsed attribute, you need to specify the type of the expected attribute while defining your rule. That leaves you with:

qi::rule<string::iterator, std::string(), ascii:space_type> 
    stringrule = *(char_ - ',');
qi::rule<string::iterator, MyStruct(), ascii:space_type> 
    myrule = repeat(3)[*(char_ - ',') >> ','] >> (double_ % ',');

which should do exactly what you expect.

like image 143
hkaiser Avatar answered Oct 13 '22 20:10

hkaiser