[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: glr: include the created header
From: |
Joel E. Denny |
Subject: |
Re: glr: include the created header |
Date: |
Wed, 12 Jul 2006 19:20:24 -0400 (EDT) |
On Wed, 12 Jul 2006, Akim Demaille wrote:
> > For example, multiple %union's (which, by the way, I *am* liking
> > more and more since it's really nice for separation of concerns).
>
> I agree on that too, but it's a can of worms, and I think it was
> introduced too soon. This debate is only triggered by it actually.
To be clear, I prefer your %type proposal over multiple %union's.
However, multiple %union's are nice in the meantime.
I agree that multiple %union's are a major culprit in this debate.
However, my feeling is that they're merely revealing a deeper issue
(declaration order) in the way we regard Bison directives, and that issue
will keep coming back. Like your gut feeling below, this feeling is one
I'll have a tough time arguing, but I did my best to explain it in both
specific and general terms in my previous post in this thread.
> You do make a point here. But still, I find the current proposal too
> explicit, too much connected to what I feel are implementation
> details.
Which proposal? %*-header? Or %semantic-type and %location-type? Or
both?
> I'm not good at be rational here, but it's a strong feeling.
> It's too low-level to be user level.
Especially after Anthony Heading's recent post, I don't feel that way
about %*-header for C/C++ users. I think they'll be asking questions
exactly like "How do I put code here?". I think %*-header will be the
straight-forward answer they're looking for. They're C/C++ users after
all. Surely they'll get it. Again, users of languages like Java could
just ignore these directives since declaration order is unimportant (as I
recall, anyway).
> As suggested earlier in the thread, it might be a form of scoping that
> we are looking for (and some of your proposals with %semantic-type are
> another example of such a scoping rule).
>
> {
> %public { #include "type1.h" }
> %union { type1 field1; }
> %destructor { free1 ($$); } <field1>
> %printer { print1 ($$); } <field1>
> %type <field1> a b c
> }
>
> {
> %public { #include "type2.h" }
> %union { type2 field2; }
> %destructor { free2 ($$); } <field2>
> %printer { print2 ($$); } <field2>
> %type <field2> d e f
> }
>
> We can help the user knowing scoping is needed by forbidding "free"
> multiple unions.
While this seems elegant, I just don't think most C/C++ users are going to
find this to be a straight-forward answer to the question "How do I put
code here?". Instead, it'll feel more like learning a new paradigm.
> > I early on proposed a %header{...%} instead of the 4 %*-header directives.
> > (This is similar to your %private and %public.)
>
> OK.
>
> > The problem then is, what if the user declares %header{...%}
> > followed by %{...%} followed by %header{...%}? Bison can't
> > possibly generate the code in that order since %header{...%} goes
> > in the header but %{...%} only goes in the code file. I tried
> > adding the restriction that you're just not allowed to declare in
> > that order, but I found that even more confusing...
>
> Why? I think this scheme is clear, and can be easily enforced by
> Bison.
Easy to implement in Bison, yes. But I found it difficult to explain the
rules of what was allowed especially when I threw %union into it. I felt
like I was adding subtleties when part of my goal was to remove them. In
general, order independence seems simpler to explain and more flexible to
use.
> Also, it helps pushing towards a normalized way to implement
> things. I like the Eiffel way (the programming language) where there
> is one construct for one issue, instead of Perl's "There Is More Than
> One Way To Do it".
I prefer one way to do things as well... but I don't want to be tied down
to the wrong way forever. Through %yacc, %require, and deprecation,
hopefully we will minimize the number of ways you can do things while
still evolving towards "the right way".
> > The user could also define YYLTYPE and YYSTYPE themselves in
> > %location-type and %semantic-type if he wished. Of course, in the above
> > proposal the user would have to then #define YYSTYPE YYSTYPE or #define
> > YYLTYPE YYLTYPE. That's ugly. To solve this, we could introduce a syntax
> > like the following:
>
> > %semantic-type "SemanticType" {
> > #include "type1.h"
> > #include "type2.h"
> > typedef union SemanticType {
> > type1 field1;
> > type2 field2;
> > } SemanticType;
> > }
>
> I like the idea, I dislike the syntax because it's a black-box for
> Bison (it's going to be even harder for Bison to glue multiple %unions
> for instance).
You misunderstood me, I think. If the user wants to use %union (or your
new %type), %semantic-type would be useful only for defining the
dependencies of %union. That is, he'd only use the braced code of
%semantic-type:
%semantic-type { #include "type1.h" }
%union { type1 field1; }
He'd only add the `"SemanticType"' parameter if he wanted to define the
semantic type himself. It would tell Bison to typedef SemanticType
YYSTYPE. Then he'd also define SemanticType in the braced code as in the
quote further above. In this case, maybe only one %semantic-type should
be allowed.
I'm now thinking %semantic-type-code might be a better name. I don't
know.
> How about something like:
>
> %union %{ #include "type1.h" %} { type1 field1; }
>
> ?
>
> It seems to address all our concerns, doesn't it? Maybe we need some
> separator for the long form?
>
> %semantic-type
> %public {...}
> %union {...}
>
> where this is a single construct with 3 keywords?
What if the user doesn't want a %union but wants other code in his header?
What if the user wants to define YYSTYPE or YYLTYPE himself? Is %{...%}
still used for the code file? What's the relationship between %{...%} and
the %union and %semantic-type?
> How about
>
> =>%requires { #include "type1.h" }
> %union { type1 field1; }
> =>%provides { type1 parse_field1 (void); }
> %destructor { free1 ($$); } <field1>
> %printer { print1 ($$); } <field1>
> %type <field1> a b c
> }
>
> =>%requires { #include "type2.h" }
> %union { type2 field2; }
> =>%provides { type2 parse_field2 (void); }
> %destructor { free2 ($$); } <field2>
> %printer { print2 ($$); } <field2>
> %type <field2> d e f
>
> ?
So, %requires = %start-header, and %provides = %end-header? What about
%before-header and %after-header? What about user-defined YYSTYPE and
YYLTYPE? What do %requires and %provides mean for languages like Java?
> > By the way, %public and %private sound like they're named after OO
> > concepts, which are similar but not exactly the same.
>
> That's not just OO! C users also refer to public vs. private
> definitions! :-)
I'm aware. However, public and private are very specific keywords in
well-known OO languages, so I felt we should stay away from that
confusion. %requires and %provides might have less of a conflict.
> > How about just %header {...} and %{...%}?
>
> Well, I feel that public/private is not merely an OO vocabulary (it
> turns out they used these words that preexisted them), while %header
> is definitely a C/C++ idiom.
I agree, but that's exactly why I like %header: I'm not sure that any
other language needs this declaration.
> Also, I like the fact that we provide an
> explicit form for %{...%}, what would you propose in symmetry to
> %header?
I shouldn't have proposed %{...%}, which already has a subtly different
functionality in Yacc: it's divided by %union. I should've proposed
%code, which Bison would always insert after the header. Also, %code
sounds fine for languages like Java that have no header concept.
> BTW, IMHO, %{...%} should be viewed just as {...}, i.e., as a
> different set of separators, with slightly different semantics (they
> are not counting the braces), so to me, %header {...} and %header
> %{...%} should both be accepted. %{...%} alone is "just" a form with
> a missing keyword.
In my mind, %{...%} is a declaration by itself. {...} is braced code used
as a parameter in a declaration. Why make them synonyms? I'd prefer to
just leave %{...%} as it is.
> > Languages like Java will have no use for %header/%private, right?
>
> No indeed. But public/private makes sense to them!
I probably just don't know what you're planning here. What would %public
and %private do exactly when Java is the target language?
> > %private might fool Java users, and %header should be more
> > explicitly useless to Java. With either name, we should probably
> > disallow it when it's useless.
>
> You lost me. What are you proposing? That some keywords are valid in
> some context and forbidden in others?
Context = target language? Then, yes: if the keywords don't have meaning,
they shouldn't be used. But maybe I'm just not seeing what you're
planning.
> To summarize, I am now convinced we need three places. It's too soon
> for me to have a real opinion about
>
> 1. %requires (heck, it's already used...), %provides, %private
%requires = %start-header
%provides = %end-header
%private = %after-header
And we drop %before-header? I can live with that for C/C++. I still
wonder what these 3 do for other target languages. What about
user-defined YYLTYPE and YYSTYPE since we don't like #define?
Joel