Hi Joel, [I cc this email to you personally lest it should be lost in old threads]
I have yet another question. Suppose, I *already* have operator>> for something. Can I reuse that in Spirit? Something like:
'{' >> * ( int_p >> extractor_parser(My_type) >> ';' ) >> '}'
where 'extractor_parser' just tries to get My_type from stream. Well... from what?! We've got iterators only... Despite this technical difference, I think something like that is needed.
I'm not quite sure what you want to achieve here or the essence of your question. A Spirit grammar is declarative code and in general is lazily evaluated only at parse time. This is in contrast with say, iostream cin where the code is imperative and executed immediately. I'm not sure why you would want to mix the two in a single expression, if that's what you mean.
I want it for a simple reason. If I'm writing operator>> for a new class using Spirit, then I have existing classes, for which no grammar is available. It would be nice to reuse operators>> already written for them to do the parsing.
Ok, I understand you now. More questions. As I realize, rules by themself are not very usefull, because they are tied to particular scanner. Ok, I have class I, and defined Spririt grammar for it, I_grammar. Later on, I devised class O, and want to define grammar for it, which must reference instances of "I", for example:
'{' >> *( int_p >> ":" >> I_parser ) >> '}'
If I have I_grammar already, how to implement I_parser?
Here's a trivial example of a grammar using another grammar:
definition(const g2& self)
{
start_ = +line >> end_p;
}
g1 line; // USES g1
This is cool! So, the grammar can be used whenever rule can?
What's more interesting is that sometimes, you want to parameterize a grammar that's used by another
grammar. For example consider expressions and statements:
struct expression : public grammar<expression>
{
/** definition **/
};
template <typename ExpressionGrammarT>
struct statement : public grammar<statement>
{
template<typename ScannerT>
struct definition
{
definition(const statement& self)
{
statement = expr >> ';';
}
ExpressionGrammarT expr;
rule<ScannerT> statement;
const rule<ScannerT>& start() const { return statement; }
};
};
Using this idiom, one can write truly reusable grammars thanks
to the C++ template mechanism. A grammar is just a class!
Ooo! Things are getting cooler, I must admit!
And one question more.... if I assign a closure type to start rule for I, how can I access it from semantic actions? The docs say that semantic action take only a pair of iterators.
Generic semantic actions take iterator pairs (first/last). However, specialized semantic actions may take specialized args. For instance the real_p passes on the actual number to the action. Similarly, closures has a return value (the 0th member) that is its attribute. This attribute is the one that's passed to the semantic action.
Got you. I guess I'll try to take the time and try using Spirit for parsing some of my classes. I tried that during formal review, but did not finished. - Volodya _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
