Boost logo

Boost Users :

Subject: Re: [Boost-users] [Spirit] Creating a vector of structs
From: OvermindDL1 (overminddl1_at_[hidden])
Date: 2009-09-01 22:35:48


On Tue, Sep 1, 2009 at 7:31 PM, Lindley M French<lfrench1_at_[hidden]> wrote:
>> On Tue, Sep 1, 2009 at 4:38 PM, Lindley M French<lfrench1_at_[hidden]>
>> wrote:> I'm playing around with Spirit for a particular parsing
>> task. I could do this manually, but I figured this was a good
>> chance to learn what Spirit had to offer.
>> >
>> > The trouble is this. While Spirit offers ready-made semantic
>> actions for parsing primitives, it doesn't seem to offer anything
>> terribly useful for compound statements. As far as I can tell, you
>> can define your own semantic actions but they simply take in the
>> matched string as an argument----there's no way to get at the
>> values parsed on that level.
>> >
>> > For example, let's say I have a type
>> > struct Person
>> > {
>> > ? string name;
>> > ? double height;
>> > ? int age;
>> > ? Person(string n, double h, int a)
>> > ? : name(n), height(h), age(a)
>> > };
>> >
>> > And I have a document containing
>> >
>> > 5.5 15 Henry
>> > 4.6 32 Jane
>> > 6.1 21 Bob
>> >
>> > I could parse this using
>> >
>> > rule<> personrule = strict_real_p >> int_p >> ~eol_p;
>> > parse(str, *(personrule[WhatGoesHere] >> eol_p) >> end_p);
>> >
>> > But how can I build a vector<Person> out of this? I can write my
>> own functor to do the push_back, but I need to get at the parsed
>> values of name, age, and height for each personrule somehow.
>> >
>> > I suppose I *could* just run another parse() on the input the
>> semantic action for that specific person....but that really seems
>> like it shouldn't be necessary.
>>
>> You are using Spirit.Classic, you should use Spirit.QI (Boost trunk,
>> docs are at:
>> http://svn.boost.org/svn/boost/trunk/libs/spirit/doc/html/index.html), then you can do it easy, like so:
>>
>> BOOST_FUSION_ADAPT_STRUCT(Person
>>                         (double,height)
>>                         (int,age)
>>                         (string,name)
>>                         )
>>
>> rule<YourIteratorType> personrule;
>> personrule %= double_ >> int_ >> raw[lexeme[*(char_-eol)]];
>> std::vector<Person> theVec;
>> parse(str.begin(),str.end(), *personrule, theVec);
>>
>> This is also better to ask on the spirit mailing list.  :)
>
> Unfortunately for the moment I'm stuck with Boost 1.35, which I don't believe has Spirit 2. I'll try asking on the Spirit list.

Ah, Spirit2.1 requires Boost 1.37 (or is that 1.38 now...) at minimum.

Ask on the spirit list though, they can help you with Spirit.Classic
questions quite well. :)


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net