----- Original Message -----
From: "Dan Nuffer" :
> joel de guzman wrote:
>
> >
> >It would have been more intuitive (following tradition) to integrate
> >attributes
> >with the rule. Yet, as we already know, the rule's dynamic nature
precludes
> >the implementation of static polymorphism techniques. The rule's abstract
> >"meta" pointer is an opaque wall. If you remember, I originally
implemented
> >closures inside the rule. Yet, that introduced unwanted coupling that
made
> >the rule less than ideal for generic parsing needs. Without the closure,
the
> >rule is still tied to the iterator. This was solved with the introduction
of
> >the
> >grammar class which essentially defers the coupling of the rules to its
> >iterator. I think now that the rule role is solely as a "place-holder".
> >
> >I suggested the integration of the grammar and the closure. A grammar
> >encapsulates one or more rules. In the traditional sense, a parser
defines
> >a single monolithic grammar. In Spirit, I'd like to push for the notion
of
> >factoring grammars into reusable sub-grammars. In that sense, I think
> >that the grammar is analogous to "function" with arguments and a return.
> >While the rules are the function's statements. Independent closures are
> >then like pascal style nested functions.
> >
>
>
> Okay, I follow you. I would like it if we change the name to something
> besides "grammar". When I hear "grammar" I think c++ grammar or XML
> grammar. A grammer is the set of all the rules that generate a given
> language. Maybe call it sub_grammar or attributed_rule?
You think so? In C/C++ we call main function and all "sub" functions
just, ummm, "functions". IMO, a sub-grammar *is-a* grammar.
Anyway more comments below...
> If one uses the grammar+closure to actually process a language such as
> pascal or XML, almost every single rule will have to be wrapped inside a
> 'grammar+closure'. That's why I suggested calling it attributed_rule.
You might have a point here. In fact I would love it very much if
all rules can have its own closure. Ain't it a pain... Those pesky
virtual functions.
But wait a minute, Hartmut, if you are reading this, a closure
*CAN* wrap a rule! I think we did the rule+closure inside-out.
Instead of rule-->closure, we can do closure-->rule. We don't need
to change the rules (no pun intended :-). We make a class
attribute_rule or attr_rule that is basically a closure wrapping
a rule.
Hmmm..... If my hunch is correct, thank you Dan for your nudging.
> Oh, one other thing: When I first heard your idea of splitting a
> grammar up, I thought it would be a good thing, and not too hard to do.
> I started trying in on XML, since it's quite a large grammar. I found
> I could not get very far at all, since all the rules are very
> inter-dependent. There was no easy chunk I could just break off and put
> in a separate piece. I would end up having to put almost every rule
> into it's own grammar. There are some that could be grouped together,
> such as the rules relating to DTD processing, but first I would have had
> to break out a TON of lower character and identifier rules that were
> used throughout all the grammar. I gave up; I didn't think there would
> be any benefit in splitting it up so much. Granted, XML may be a bad
> example, since it has no well-defined lexical/parser boundary. But I
> suspect a similar situation will arise when trying to break up a grammar
> like C or Pascal, for instance.
I've done some mind experiments with the Pascal grammar before
I thought of the grammar class. Pascal can be factored. There
are quite clear boundaries. Examples: expressions, statements
functions, etc. There are cases where one or more "sub"-grammars are
inter-dependent where a "sub"-grammar need one or more rules from
another sub-grammar. In this case, this can be done by 1) private
inheritance of the grammar's definition where the subclass defines
some rules of its superclass. 2) Provide access to the rules such that
other sub-grammars can define them.
I prefer 1), but then again, this remains to be seen until I come up with
something tangible.
> >>Also, I think that the way it's currently implemented will make it
> >>rather difficult to process some things. For example, try to think how
> >>to write spirit code that would do the same as this little yacc snippet:
> >>(a postfix calculator from the bison docs)
> >>
> >> exp: NUM { $$ = $1; }
> >> | exp exp '+' { $$ = $1 + $2; }
> >> | exp exp '-' { $$ = $1 - $2; }
> >> | exp exp '*' { $$ = $1 * $2; }
> >> | exp exp '/' { $$ = $1 / $2; }
> >> /* Exponentiation */
> >> | exp exp '^' { $$ = pow ($1, $2); }
> >> /* Unary minus */
> >> | exp 'n' { $$ = -$1; }
> >> ;
> >>
> >>
> >>yacc implements this using a stack. Maybe something similar could be
> >>done for spirit. var.get(m0) would remove the top item off the stack.
> >>var.set(m0, val) would put val onto the stack. This could be tricky for
> >>putting different types in the stack, but maybe boost::any could be of
> >>use here.
> >>
> >
> >Wrap 'exp' in a sub-grammar? I think a closure over 'exp' will do what
> >you want.
> >
>
> Yeah, I see! I wasn't thinking too fine-grained enough. I was trying
> to see how to accomplish this with $1, and $2 acessing the current
> context, but that won't work, they will have to access sub-grammars that
> return their own thing.
The issue I'm facing right now is how to make it usable. If my hunch is
correct
that we can have an attr_rule (a closure wrapping a rule), our problems
are solved.
Next step, Lambda!
Regards,
--Joel
|