Boost logo

Boost Users :

Subject: Re: [Boost-users] [spirit] first steps
From: Igor R (boost.lists_at_[hidden])
Date: 2010-02-18 14:22:22


> Spirit has a built-in construct for lists:
>
>    ~*char( ':' ) % ':'
>
> If you use attribute parsing you can simply perform the following:
>
>  std::vector< std::string > list_of_strings;
>
>         parse( begin, end,
>                ~*char( ':' ) % ':',
>                list_of_strings
>               );
>
> Nice huh?

Nice, but IUUC, it won't take into account the type of the elements, right?
I tried to do the following (but it doesn't match the input string):

//
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <string>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

namespace details
{
        struct sensor
        {
                int id;
                std::string type;
                int cam;
                int group;
                std::string name;
                int state;
                std::string regs;
        };
}

BOOST_FUSION_ADAPT_STRUCT
(
  details::sensor,
                (int, id)
                (std::string, type)
                (int, cam)
                (int, group)
                (std::string, name)
                (int, state)
                (std::string, regs)
)

namespace details
{
template <typename Iterator>
struct sensor_parser : qi::grammar<Iterator, details::sensor(),
ascii::space_type>
{
  sensor_parser() : sensor_parser::base_type(start)
  {
    using qi::int_;
    using qi::lit;
    using qi::double_;
    using qi::lexeme;
    using qi::eol;
    using ascii::char_;

                text %= lexeme[+(char_ - ':')];

    start %=
                        int_ >> ':'
>> text >> ':'
>> int_ >> ':'
>> int_ >> ':'
>> text >>
                        -(':' >> int_) >>
                        -(':' >> text) >>
                        eol
      ;
  }

  qi::rule<Iterator, std::string(), ascii::space_type> text;
  qi::rule<Iterator, sensor(), ascii::space_type> start;
};
}

int main()
{
        using boost::spirit::ascii::space;
        typedef std::string::const_iterator iterator_type;
        typedef details::sensor_parser<iterator_type> sensor_parser;

        sensor_parser g;
        std::string str = "3:abcd:3:3:My name:1:33333333333\r\n";
        details::sensor emp;
        std::string::const_iterator iter = str.begin();
        std::string::const_iterator end = str.end();
        bool r = phrase_parse(iter, end, g, space, emp);
        if (r && iter == end)
                return 1;
}


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