[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: glr: include the created header
From: |
Akim Demaille |
Subject: |
Re: glr: include the created header |
Date: |
Wed, 12 Jul 2006 17:45:27 +0200 |
User-agent: |
Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) |
>>> "Joel" == Joel E Denny <address@hidden> writes:
Hi Joel,
> 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.
> If I declare a %union followed by a %{...%} followed by a %union,
> how can Bison possibly generate the target code in that order?
It can't, I agree.
> Bison has to concatenate the %union's together into a single
> YYSTYPE. So, how does Bison determine which %{...%} are placed
> before and which are placed after the YYSTYPE? Should the user
> have to learn that it's the *first* %union that divides the
> %{...%}'s? That's how it works now, but I think that's exposing
> the mess in a subtle way. For example, the following looks right,
> but it doesn't compile:
> %{ #include "type1.h" %}
> %union { type1 field1; }
> %destructor { free1 ($$); } <field1>
> %printer { print1 ($$); } <field1>
> %type <field1> a b c
> %{ #include "type2.h" %}
> %union { type2 field2; }
> %destructor { free2 ($$); } <field2>
> %printer { print2 ($$); } <field2>
> %type <field2> d e f
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. I'm not good at be rational here, but it's a strong feeling.
It's too low-level to be user level.
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.
> Another example is the C/C++ header. To simplify the discussion, assume
> the user declares only one %union. Should Bison insert every %{...%} from
> before the %union into the header, and should it insert every %{...%} from
> after the %union only into the code file?
Let's discuss the meaning of %{...%} in a second step. My proposal
for a new syntax is %public and %private.
> What if there is no %union? Does the user now lose the ability to
> put code in his header, or does he lose the ability to put code
> only in his code file?
No, %public is here for that. And if there is no union, there must be
something like %semantic-type anyway.
> How does either loss make any sense? It seems quite subtle. Then
> add multiple %union's and it gets even more subtle. Add
> %module... yikes.
> 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. 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".
> That is, I was thinking the generated order would be documented
> (for the user) as always something like:
> ----------------------
> enum yytokentype
> %location-type code
> #ifndef YYLTYPE
> typedef struct YYLTYPE {
> ...
> } YYLTYPE;
> #endif
> %semantic-type code
> #ifndef YYSTYPE
> typedef union YYSTYPE {
> ...
> } YYSTYPE;
> #endif
> %public code
> ----------------------
> %private or %{...%} code
I agree, this is a nice scheme.
> 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). 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?
Hum, that's the same as your proposal actually. So maybe I'm just
annoyed by the name of the keywords (the four %*-header ones). They
make it hard for simple cases with a single %union.
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
?
> 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! :-)
> 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. Also, I like the fact that we provide an
explicit form for %{...%}, what would you propose in symmetry to
%header?
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.
> Languages like Java will have no use for %header/%private, right?
No indeed. But public/private makes sense to them!
> %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?
> It seems compatible with your modular grammar proposal and your
> `%type {char *} a b c' (where there is no %union to divide the
> prologue, right?).
Right.
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
2. %semantic-type %public {...} %union {...} (unique construct)