bug-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Default rule


From: Hans Aberg
Subject: Re: Default rule
Date: Sat, 19 Oct 2002 11:56:09 +0200

At 17:54 -0700 2002/10/18, Paul Eggert wrote:
>> the current implementation invites sloppy programming: One can drop
>> some $$.field = $1.field assignments in the grammar, even when the
>> rule is not default....
>
>True.  Perhaps it would be better to move the yyval assignment into
>the default case of the yyn switch.  That would cause the GCC warning
>to be generated for the sloppy grammars that you mention.
>
>> -- I think it would be safer to do nothing in the case of rule length zero
>> than producing some ad hoc garbage.
>
>But doing nothing also produces ad hoc garbage.

The main point here is that under C++ one has to do it, because a class may
have a copy constructor where two application is not the same as one:

This happened to me when I tried to use std::auto_ptr, which might be tried
instead of using a reference count. (It is a class that maintains a pointer
and transfers the ownership of that pointer in copying.) If one tries to
use that class with the Bison generated parser and the traditional skeleton
file that does the double assignment, then in the first assignment $$ = $1,
the pointer that std::auto_ptr maintains is transferred over to $$ and the
one that $1 maintains is set to NULL! So when one tries to use the $1
object one believes should be there, one gets mysterious errors because it
is now NULL in the rule action code.

That is how I discovered the problem. I then immediately stopped
experimenting with std::auto_ptr, using instead a reference count which
does not have that problem. But that illustrates the problem one can have
under C++.

So the C++ skeleton file must be changed in order to be correct. I just
moved the stuff into the switch state. -- Bison seems to write no case at
all if {} is excluded in the .y grammar, as well checking for all errors
before the switch statement, so I could see no problem with that easy
change.

Then there is another problem, what to do under C: Clearly, the C++ problem
cannot happen under C as all copy constructors are default (two
applications are equivalent to one).

If one should write the code strict semantically correct, as in C++, then
it should be moved within the switch statement.

Then the second question is what to do with a zero length default rule
default action:

There C++ is different from C in that one often does have default copy
constructors. Thus it makes sense setting
  $$ = semantic_type();

I have no feeling whether it is worth doing anything about that under C, as
I do not use Bison under C: I only notice that the C++ things might be
emulated under C. It might be convenient, in might not, under C.

>> -- When using %union, YYSVALDEFAULT would need an extra argument:
>> #ifndef
>> #define YYSVALDEFAULT(yyval, type) /* yyval.type = ... */
>> #endif
>
>This issue arises only for untyped grammars, since an error message is
>generated for typed grammars if the default action has the wrong type
>(which is the case here).  I don't think it's worth making it
>configurable for the untyped-grammar case, as those grammars tend to
>be pretty simple and don't need configuration.
>
>Perhaps it's simpler just to zero out yyval here.

I haven't tried doing the typed version under C++, in part because I do not
need it, and in part because %union does not make much sense under C++ --
unions cannot be used with C++ classes that have non-trivial constructors.
So in order to experiment with it fully under C++, one needs an option
%typed that merely triggers the Bison type checking mechanism without
writing a union.

That is easy enough. -- I once did that. But as I have no need for it now,
I haven't tried it.

But I figure that the C++ equivalent of the zero length rule default action
might be
    $$.field = semantic_type.field();
This involved the field name and the $$ to set. Therefore I thought one
under C might use a macro
    YYSVALDEFAULT(yyval, field)
A simple default might be:
    #define YYSVALDEFAULT(yyval, type)  yyval.field = 0

-- I this case there are no other $k values to tie typing to. But it might
be convenient not having to write in initializations explicitly.

  Hans Aberg






reply via email to

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