Search code examples
c++boost-spiritboost-spirit-qi

In Boost Spirit Qi, how do I match every character up to the next whitespace (with pre-skip)


Within a boost::spirit::qi grammar rule, how do you match a string of characters up to and excluding the next whitespace character, as defined by the supplied skipper?

For example, if the grammar is a set of attributes defined as:

attributeList = '(' >> *attribute >> ')';
attribute     = (name : value) | (name : value units);

How do I match any character for name up to and excluding the first skipper character?

For example, for name, I would like to pre-skip, then match all characters except ':' or a skipper character. Do I have to instantiate a skipper within the grammar class, so that I can do something like:

name = +qi::char_ !(skipper | ':');

or can I access the existing supplied skipper object somehow and reference it directly? Also, I don't believe this needs to be wrapped in qi:: lexeme[]...

Thanks in advance for correcting the error of my ways


Solution

  • In order to do this, you'll need to suppress skipping, so qi::lexeme will have to be involved (or at least qi::no_skip, but you'd only use it to reimplement qi::lexeme), and to do precisely what you write you'll also need the skip parser. Then you could write

    qi::lexeme[ +(qi::char_ - ':' - skipper) ]
    

    The requirements seem rather lax, though. It is unusual to allow even non-printable characters such as the bell sign (ASCII 7) in identifiers. I don't know what exactly you're trying to do, so I can't answer such design questions for you, but to me it seems like there's a good chance you'd be happier with a more standard rule such as

    qi::lexeme[ qi::alpha >> *qi::alnum ]
    

    (for a very simple example. Your mileage may vary wrt underscores etc.)