bison-patches
[Top][All Lists]
Advanced

[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)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]