In the grammar i'm implementing, there are elements separated by whitespace. With a skip parser, the spaces between the elements are skipped automatically, but this also allows no space, which is not what i want. Sure, i could explicitly write a grammar that includes these spaces, but it seems to me (with the complexity and flexibility offered by spirit) that there is a better way to do this. Is there? Here is an example:
#include <cstdlib>
#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main(int argc, char** argv)
{
if(argc != 2)
{
std::exit(1);
}
std::string str = argv[1];
auto iter = str.begin();
bool r = qi::phrase_parse(iter, str.end(), qi::char_ >> qi::char_, qi::blank);
if (r && iter == str.end())
{
std::cout << "parse succeeded\n";
}
else
{
std::cout << "parse failed. Remaining unparsed: " << std::string(iter, str.end()) << '\n';
}
}
This allows ab
as well as a b
. I want only the latter to be allowed.
Related to this: How do the skip parsers work, exactly? One supplies something like qi::blank, is then the kleene star applied to form the skip parser? I would like to get some enlightenment here, maybe this also helps on solving this problem.
Additional information: My real parser looks something like this:
one = char_("X") >> repeat(2)[omit[+blank] >> +alnum] >> qi::omit[+qi::blank] >> +alnum;
two = char_("Y") >> repeat(3)[omit[+blank] >> +alnum];
three = char_("Z") >> repeat(4)[omit[+blank] >> +alnum] >> qi::omit[+qi::blank] >> +alnum;
main = one | two | three;
which makes the grammar quite noisy, which i would like to avoid.