[QI] Alternate parser not using boost::variant

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[QI] Alternate parser not using boost::variant

peterkochlarsen
I have been struggling with adapting QI to return the result in something else than boost::variant, which for different reasons does not fit my problem domain.
The approaches I have used include specialising not_is_variant, attr_cast, as and transform_attribute in many different variations, all giving me compilation errors when one of the elements of my variant is a container.
Can anyone provide me in a direction as to how to proceed - e.g. a link to some documentation. The optimal solution would be to pass data directly to my variant, but going via a boost variant would also be a viable solution.
I might get the same problem with another type of structure, somewhat resembling boost::optional but having somewhat different semantics (the empty "optional" type represents a predefined type).

A somewhat different question relates to x3. What is the current status and could it be an advantage to port to X3? My software needs to compile with MSVC.

If needed I can provide source-code, but it might be difficult to get it sufficiently short considering I need to simulate my own variant to replicate the problem. If you can live with a somewhat large code block, I will be happy to provide the code.

Best regards
Peter
Reply | Threaded
Open this post in threaded view
|

Re: [QI] Alternate parser not using boost::variant

peterkochlarsen
In the unlikely case that anyone is interested in answer, I will answer my own question but need to provide some background first.
I use spirit::qi as a "type-parser", so that I, given a type T can get the parser for T by calling a parser-factory:
template<class T>
XXX get_parser<T>().

(It is a little bit more elaborate than that, but you get the idea).
Due to the difficulty of copying qi-parsers, I ended up returning a boost::proto::terminal<rule<Iterator,T()>, and using this approach and defining the parser for a variant<T1,T2,...,TN> as get_parser<T1>() | get_parser<T2>() | ... | get_parser<TN() and in that case my union parser did not work. I did solve it eventually by specialise not_is_variant<T> and not_is_variant<T,qi::domain> as mpl::false_. I did have to define both not_is_variant's;  defining one of them was not enough.
Fast forward to my last take of generating a parser-factory: get_parser now returns a const reference to the rule which is a static variable. As a result, I no longer have to specialize "not_is_variant" - it works right out of the box.
The current status of my project is that my parser-factory seems to work out of the box for tuples and almost out of the box for variants with the exception that I may have to reorder individual choice-items in the parser due to the greedy nature of qi. The order of elements in my variants is significant and can not be changed.