Hi Aaron, Aaron W. LaFramboise wrote:
Hi,
I've been learning about Boost Spirit from the documentation, and one big gap I'm finding is how Spirit knows to call a particular signature semantic action given a particular parser.
You can find it in the semantic actions documentation: http://www.boost.org/libs/spirit/doc/semantic_actions.html Basically, there's a transduction interface which expects a semantic action with a compatible signature: void f(IteratorT first, IteratorT last); and an attribute interface which expects a semantic action with a compatible signature: void func(T val); The semantic actions documentation lists a couple of primitives and its expected interface (e.g. int_p, ch_p, etc.). From then on, unless otherwise noted, all other parsers (e.g. alternative: a | b, sequence: a >> b) are of the transduction type.
I see this has something to do with the match type, but I'm not sure how to actually define the match type for rule. I've discovered by accident that semantic actions seem to be called with the type of the closure member of a single-member closure, but I don't see this documented, and
More accurately, the first closure member is the attribute. And yes, this is documented in: http://www.boost.org/libs/spirit/doc/closures.html <quote> Closure return value The closure member1 is the closure's return value. This return value, like the one returned by anychar_p, for example, can be used to propagate data up the parser hierarchy or passed to semantic actions. Thus, expression, term and factor, as well as the calculator grammar itself, all return a double. </quote>
I can't quite figure out how its supposed to work. Its difficult to deduce expected signatures by the compiler error approach because GCC is giving fairly nonsensical errors for the sorts of template constructs Spirit seems to use, when something goes wrong.
I have to admit that what's really missing is a formal documentation. It's easy to get lost in the User's Manual. Some information seem to be hidden somewhere. I do believe, however, that example code speak volumes. For that matter, I believe that by following the links in the manual to sample code you should be able to get a quick start. See http://tinyurl.com/2dqku for instance. This compilable code snippet provides a minimalist and easily understandable example of a parser that uses closures. There are lots of code examples in the docs. The closure documentation alone links at least three compilable samples.
In particular, I'd like to know specifically how I am supposed to be defining semantic actions for my rules. Perhaps this is something that would be nice to be included somewhere in the documenation. Maybe it is, but I missed it somehow, or it wasn't spelled out explicitly enough for me to catch on.
Any help or pointers would be greatly appreciated!
Please try to read the closure docs again and follow the examples.
(By the way, I have to repeat the almost obligatory comment that everyone seems to make about Spirit: it is one of the most beautiful examples of C++ I have ever seen!)
Music to my ears! Thanks for the compliment! HTH, and BTW, there's a spirit specific mailing list: Spirit-general mailing list Spirit-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spirit-general Please send subsequent replies and posts there. There's a bunch of really helpful Spirit-folks there who'd be glad to help you. Thanks! -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net