Boost logo

Boost :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2002-11-12 04:47:12


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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk