Just use a separate skipper for the relevant portions.
It's a bit of a fixture from tutorials only to "bake" the skipper into the outward interface of a grammar. In 99% of the cases, that makes no sense at all: changing the skipper can wreck the grammar. So, I've taken to encapsulating the skipper the way it was intended by the gods (joke):
Instead of
template <typename It>
struct MyGrammar : qi::grammar<It, Attribute(), qi::space_type> {
MyGrammar() : MyGrammar::base_type(start) {
start = /*....*/;
}
private:
qi::rule<It, Attribute(), qi::space_type> start;
};
I write
template <typename It>
struct MyGrammar : qi::grammar<It, Attribute()> {
MyGrammar() : MyGrammar::base_type(start) {
start = qi::skip(qi::space) [ mainRule ];
mainRule = /*....*/;
}
private:
qi::rule<It, Attribute()> start;
qi::rule<It, Attribute(), qi::space_type> mainRule;
};
This means you can write
bool ok = qi::parse(f,l, MyGrammar<It>{});
and it will still use the correct skipper. Even if you did
bool ok = qi::phrase_parse(f, l, MyGrammar<It>{}, qi::char_);
it would still use the correct skipper!
Different Skippers For Different Rules
You will have to decide what will be your main skipper, but you can use the qi::skip()[]
directive to switch arbitrary skippers. So let's assume that, like in most programming languages, newlines are usually insignificant whitespace, so you'd have
qi::rule<It, qi::space_type> a_whole, bunch_of, rules;
And then in your bunch_of
rule you want to use differentRule
which does have significant whitespace:
qi::rule<It, qi::blank_type> differentRule;
And you switch it like so:
bunch_of = "stuff" >> '{' >> qi::skip(qi::blank) [ differentRule ] >> '}';
That's all. Of course, if you wanted NO skipping at all inside differentRule
you could have used qi::lexeme[]
as always, or indeed just have dropped the skipper from the rule's declaration:
// implicit lexeme
qi::rule<It> differentRule;
Background
All of the above are detailed in this more broad answer: Boost spirit skipper issues