c++ - Boost Spirit Qi Re-Establish Skipping with custom skip grammar -
i have grammar has, until now, been using standard boost::spirit::ascii::space
/boost::spirit::ascii::space_type
skipper.
i have rules use skipper , don't, like
qi::rule<iterator, ptr<expression>(), ascii::space_type> expression; qi::rule<iterator, ptr<term>()> term;
when use non-skipping nonterminal (like term
) inside of skipping nonterminal (like expression
), works expect - whitespace matters inside term
nonterminal.
further, until now, have been fine including nonterminals use skipper inside of nonterminals don't using qi::skip
restablish skipping, such as
index = (qi::lit('[') >> qi::skip(ascii::space)[explist >> qi::lit(']')]);
this way, whitespace not significant inside of []
braces, outside.
however, want add own custom skipper (i want make newlines significant , later add comment-skipping). skipper grammar looks like:
struct skip_grammar : qi::grammar<iterator> { qi::rule<iterator> start; skip_grammar() : skip_grammar::base_type(start) { start = qi::char_("\t\r "); } };
i have been able add rule definitions fine like
qi::rule<iterator, ptr<expression>(), skip_grammar> expression;
but can't seem figure out how use skip grammar argument qi::skip
(and replace ascii::space
). i've tried using type, local instance variable, , global instance variable. farthest i've gotten clang complain skip_grammar needs copy constructor. tried adding copy constructor skip grammar, apparently boost::noncopyable
base class there reason, because binary segfaulted immediately.
how should using this?
thanks
a qi::grammar
container qi::rules
. not have copy constructor because inadvertently create dangling references in parser expressions on right hand side of rules.
using grammar skipper want bit tricky , amounts passing start rule of grammar skip parser. might easier create rule instance (especially if have single rule skipper).
in case, rule needs passed skipper reference (by calling rule's member function alias()
):
skip_grammar skippper; index = '[' >> qi::skip(skipper.start.alias())[explist >> ']'];
or simply:
rule<iterator> skipper = qi::char_("\t\r "); index = '[' >> qi::skip(skipper.alias())[explist >> ']'];
the aliasing necessary because of specifics of means copy rule. described in more detail in spirit's faq here.
Comments
Post a Comment