I tried to encapsulate a X3 parser in a class, where the rules (and their definitions) are members, i.e. similar to the structure of a Qi parser where one had to derive from boost::spirit::qi::grammar.
What would be the advantages of this approach:
- better separation of code than the namespace approach used in the examples (e.g. to avoid namespace clash)
- the parser is only instantiated when an object of this class is generated instead of the parser (the individual rules) being static
- potential parameters (e.g. question Parser rule dependent on parameter) might be given to the constructor and integrated in a "direct" way instead of using the with<> directive
But this does not seem possible. Defining the rules (or rather rule definitions) in the form auto name = rule<class name, std::string>() = alpha >> *alnum;
is not an option as auto
is not possible for class members. On the other hand, stating the actual type does not seem practical either, apart from very small parsers.
A modeling alternative would be to have the rules as members and create the definitions in the constructor, but here the linking between them, usually done with BOOST_SPIRIT_DEFINE, is not possible and the rule alone is not enough to parse (static_assert failed "BOOST_SPIRIT_DEFINE undefined for this rule.").
Also, having the whole parser in a class method, e.g. ParseXYZ::parse()
, which creates the parser - probably via another method such that it is created only once - and parses the input, is not really an option when it comes to code reuse (apart from copy&paste).
Do you know whether it is possible to encapsulate an X3 parser in a class? Besides that, what are your suggestions to build reusable parsers in X3?