Hi Abel,
On Jun 3, 2015, at 6:38 PM, Abel Sinkovics
First, I started out defining my AST nodes like this:
template
struct edge_decl {}; Seems like a reasonable basic type-holder to me. As shown above, this is instantiated and returned by a helper metafunction invoked by the transform which pulls stuff out of an mpl::vector.
But then somewhere in metaparse, it tries to again "invoke" this result with ::type when appending it to another mpl::vector.
Really? So my transform needs to return not the value, but a metafunction which returns a value? It might be a bug. Do you still have the code that produced it?
Sure. I commented each of the places I had trouble in my gist, https://gist.github.com/gordonwoodhull/dcbb332eea06dd3279b9 ... which was only a few places, and very small changes a testament that your library is surprisingly easy to use once you get used to it.
I couldn't figure this out, so I gave each of my AST nodes a self-referential ::type in the way that mpl::vector has:
template
struct edge_decl { typedef edge_decl type; //why? }; Something is not right here! Note that when I was experimenting with lazy evaluation, then I came to the conclusion that adding such self-referential ::type to every class you intend to use as value in template metaprogramming makes life much easier. You don't need to worry about where you return a value and where you return a thunk.
However, this does not change the fact that Metaparse should not use ::type where it is not needed.
Ah, I hope that is it. I could not figure out what I was supposed to be returning, and felt lousy about adding a ::type just to move on.
the parser will greedily eat the epsilon and have nowhere to go (at least according to my amateur understanding of parsers).
I gave up here and made the separator mandatory. Again, this is probably not a flaw in the design, but the documentation should describe what kinds of grammars will work, and perhaps give pointers to other resources about disambiguating grammars. Probably there is a different construct which would help here. I'm not sure what error you ended up with in this case.
This is also commented in the gist.
The way you implement the optional semicolon seems to be right. What I'd change here is using last_of instead of sequence assuming that you only need the result of stmt and not the entire sequence of the (optional) semicolon and the stmt result.
... and that fixed it! Which shows that my "stuck eating epsilon" explanation is probably incorrect. I've updated the gist with last_of, that's a lot better.
"How you should implement different kinds of grammar elements" is difficult to present in the documentation. Currently the tutorial shows how things intended to be used (eg. it presents first_of and middle_of).
Yes, it certainly is not easy to document. Hopefully these best practices will emerge as Metaparse gets many more users! Cheers, Gordon