bison-patches
[Top][All Lists]
Advanced

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

Re: RFC: generate the default semantic action


From: Rici Lake
Subject: Re: RFC: generate the default semantic action
Date: Tue, 16 Oct 2018 02:23:31 -0500

That's an interesting example, certainly. It is indeed dubious, and I
always caution bison beginners against using large fixed-length arrays as
part of their semantic union. However, it still seems to be quite common,
and the fact that such values are preserved through unit productions with
no action makes it more likely that you will find it in the wild.

The dependency on the pre-action I was thinking of is more like the
following:

     list: %empty      { $$ = new List; }
         | list entry  { $$.append($2); }

or

     list: %empty      { $$ = new List; }
         | list entry  { $1.append($2); }

I've stumbled upon both of those in the wild. Certainly, the code is
incorrect and it should be fixed. On the other hand, it works fine, so it
is understandable that the bug has never been noticed.

 It's an open question to what extent one ought to preserve past behaviour
in order to not trigger bugs, but I'd err on the side of caution. I think
we've all seen software projects whose maintainers insist on using
antediluvian bison versions because something doesn't work with the new
bison version, and nobody still associated with the project feels
sufficiently comfortable with parser generators to fix whatever triggers
the error.

In short, I'd vote for leaving things as they are in the C template, and
taking a bit more time to think about a good resolution.

----

In answer to your other questions, I was thinking about exactly the
paragraph of the manual which you cite, which warns against relying on the
value of $$ in empty productions. I have seen the comment in the generated
source before, but it's a bit optimistic to assume that bison users will
take the time to read the generated code. If a warning isn't in the manual,
it doesn't exist IMHO.

As far as I'm concerned, you're welcome to use any code I've published on
the 'net, in mailing lists or StackOverflow answers. I haven't ever signed
anything submitted to the FSF; all my open source stuff has been bsd or
apache licensed. But I guess I could do it if it is really necessary. Email
me privately. I'll try to find a more interesting example if you want one;
that one was just thrown together in a few minutes.

"%ms" is a (very useful) Posix feature. I thought it was widely implemented
(other than Windows, of course). The contrast between its simplicity and
the almost punitive nature of Microsoft's "safe" scanf alternatives seems
to me to reveal two very different programming philosophies. I'd be looking
for a new libc :-)



El mar., 16 oct. 2018 a las 0:38, Akim Demaille (<address@hidden>)
escribió:

>
>
> > Le 16 oct. 2018 à 07:13, Akim Demaille <address@hidden> a écrit :
> >
> > Hi Rici,
> >
> >> This patch won't affect programs which rely on this feature, as far as I
> >> can see. But I wanted to highlight the issue because the road that
> follows
> >> this patch might inadvertently affect existing programs which count on
> the
> >> default action to be a copy of the *entire* semantic value.
> >
> > No, I don’t think it changes anything, indeed.  Even type checking
> > is run before adding the explicit default action.  Your example
> > runs fine.
>
> Scratch that, my experiments were broken.  Like C’s handling of arrays.
>
> This language treats arrays in a special way, forbidding assignments
> between arrays, but accepting them happily if the arrays are members
> of structs and you assign the structs.
>
> Consider this:
>
> %{
> #include <ctype.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> void yyerror(const char* msg) { fprintf(stderr, "%s\n", msg); }
> int yylex(void);
>
> typedef char string[256];
> %}
>
> %union {
>   string str;
> };
>
> %token <str> WORD
> %type <str> word
> %%
>
> prog: %empty
>    | prog word        { printf("%s\n", $2); }
>
> word:   WORD
>
> %%
>
> int yylex(void) {
>   static int c = 0;
>   int val = c++;
>   if (val < 4)
>     {
>       sprintf(yylval.str, "%d", val);
>       return WORD;
>     }
>   else
>     return YYEOF;
> }
>
> int main(int argc, char** argv) { return yyparse(); }
>
>
> The old bison is happy with it, and it generates valid C code.
>
> $ /opt/local/bin/bison /tmp/foo.y && gcc-mp-7 foo.tab.c && ./a.out
> 0
> 1
> 2
> 3
>
> The ‘new’ bison is happy with it, but generates invalid code.
>
> $ ./_build/8s/tests/bison /tmp/foo.y && gcc-mp-7 foo.tab.c
> /tmp/foo.y: In function 'yyparse':
> /tmp/foo.y:24:19: error: assignment to expression with array type
>  word:   WORD
>                    ^
>
> This example is dubious, is the user really likely to expect
>
>   word: WORD
>
> to behave properly without strncpy?  In practice, it does, but…
>
>
> So I think I will (for a start?) restrict this change to only
> C++ with variants.
>
> WDYT?


reply via email to

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