Search code examples
c++boost-spiritboost-spirit-qiboost-phoenix

How can I extract a std::string with boost.spirit?


Using boost.spirit I try to parse simple command line of the form command:param1 param2...

to do so I created this parser:

(+(char_ - ':'))[ref(cmd) = _1]
>> ':'
>> (*char_)[ref(params) = _1]

The attribute types of the two compounds parser is vector, so if cmd and params are of type vector this work. However if they are of type std::string it doesn't. While searching for this solution on the web I found hint that it should also work with string. Is there anyway I can make this work with string?


Solution

  • Sure, when you use semantic actions no automatic attribute propagation will happen. Both your parsers (+(char_ - ':') and *char_) expose a std::vector<char> as their attribute. Therefore, _1 refers to a std::vector<char> as well. If cmd and params are instances of std::string it will not compile as no assignment from a std::vector<char> to a std::string is defined.

    However, if you get rid of the semantic actions it will work:

    std::string s("command:param1 param2");
    std::string cmd, params;
    parse(s.begin(), s.end(), +~char_(':') >> ':' >> *char_, cmd, params);
    

    This is not only simpler, but faster as well. The parser will place the matched characters directly into the supplied strings.