If the inherited attributes are used in semantic actions, we can use x3::with
directive.
What if we want to use the attributes as part of the parser? For example a simple parser matches 1 or more alphabet characters except the character is from a parameter char set.
qi::rule<std::string::const_iterator, qi::unused_type(char const*)> rule =
+(qi::alpha - qi::char_(qi::_r1));
Or the parameter char set could be used as a lazy parser.
qi::rule<std::string::const_iterator, qi::unused_type(char const*)> rule =
+(qi::alpha - qi::lazy(qi::_r1));
x3::with directive put this local value in the context. I'm not sure if we could use this context outside a semantic action and eventually generate a parser.
Simply let go of the old habit of rule-ifying everything.
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
template <typename... Args>
auto negate(Args&&... p) {
return +(x3::char_ - x3::char_(std::forward<Args>(p)...));
};
int main() {
std::string input("all the king's men and all the king's horses"), parsed;
if (parse(input.begin(), input.end(), negate("horse"), parsed))
std::cout << "'" << input << "' -> '" << parsed << "'\n";
}
Live On Coliru, prints:
'all the king's men and all the king's horses' -> 'all t'
Second flavour:
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
template <typename Sub>
auto negate(Sub p) {
return +(x3::char_ - x3::as_parser(p));
};
int main() {
std::string input("all the king's men and all the king's horses"), parsed;
if (parse(input.begin(), input.end(), negate("horse"), parsed))
std::cout << "'" << input << "' -> '" << parsed << "'\n";
}
Live On Coliru, prints:
'all the king's men and all the king's horses' -> 'all the king's men and all the king's '
You can also aggregate sub parsers in a custom parser:
If you need resursive rules with passing around, I'd suggest x3::with<>
(although I'm not sure the contexts build re-entrant state for the with<>
, you need to test the precise semantics unless you can find documentation for it)