I'm trying to learn boost::spirit
. As an example, I'm trying to parse a sequence of words into a vector<string>
. I tried this:
#include <boost/spirit/include/qi.hpp>
#include <boost/foreach.hpp>
namespace qi = boost::spirit::qi;
int main() {
std::vector<std::string> words;
std::string input = "this is a test";
bool result = qi::phrase_parse(
input.begin(), input.end(),
+(+qi::char_),
qi::space,
words);
BOOST_FOREACH(std::string str, words) {
std::cout << "'" << str << "'" << std::endl;
}
}
which gives me this output:
'thisisatest'
but I wanted the following output, where each word is matched separately:
'this'
'is'
'a'
'test'
If possible, I'd like to avoid having to define my own qi::grammar
subclass for this simple case.
Just in case someone else run into my problem of leading spaces.
I had been using ildjarn's solution, until I ran into a string that starts with some spaces.
It took me a while to figure out that the leading space leads to a failure of function qi::parse(...). The solution is to trim the input leading spaces before calling qi::parse().
You're fundamentally misunderstanding the purpose of (or at least misusing) a skip parser –
qi::space
, used as a skip parser, is for making your parser whitespace agnostic such that there is no difference betweena b
andab
.In your case, the whitespace is important, as you want it to delimit words. Consequently, you shouldn't be skipping whitespace, and you want to use
qi::parse
rather thanqi::phrase_parse
:(Now updated with G. Civardi's fix.)
I believe this is the minimal version. qi::omit applied on the qi list parser separator is not necessary - it does not generate any output attribute(s). For details see: http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/operator/list.html