2

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?

Community
  • 1
  • 1
sapi
  • 111
  • 5

1 Answers1

1

Yes it is possible, Instead of auto name = rule<class name, std::string>() = alpha >> *alnum; you do decltype(rule<class name, std::string>() = alpha >> *alnum) name; in the definition, and name{rule<class name, std::string>() = alpha >> *alnum} in the constructor.

Mohammad Alaggan
  • 3,749
  • 1
  • 28
  • 20