bison-patches
[Top][All Lists]
Advanced

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

Re: lalr1.cc: use %printer in the syntax error messages


From: Joel E. Denny
Subject: Re: lalr1.cc: use %printer in the syntax error messages
Date: Wed, 2 Sep 2009 22:27:08 -0400 (EDT)
User-agent: Alpine 1.00 (DEB 882 2007-12-20)

Hi Akim.

On Wed, 2 Sep 2009, Akim Demaille wrote:

> Le 27 août 09 à 09:11, Joel E. Denny a écrit :
> 
> > On Wed, 26 Aug 2009, Akim Demaille wrote:
> > 
> > > So I think that what we really need is to open yysyntax_error to the user.
> > > We
> > > should provide the user with the lookahead, the (full) list of expected
> > > tokens, the location, and *she* should forge the error message she wants.
> > 
> > That makes sense to me.  Some time ago, we discussed adding a
> > %error-report declaration in order to avoid the fluctuating yyerror
> > prototype.  The user could access all these elements from that.  For C, it
> > might be:
> > 
> > %error-report {
> >   char const *loc = yylocation_to_string (@$);
> >   fprintf (stderr, "%s: %s\n", loc, yymessage);
> >   fprintf (stderr, "%s: unexpected %s", loc, yytname[yyunexpected]);
> >   if (yyunexpected_is_typed)
> >     {
> >       fprintf (stderr, " with value ");
> >       yyunexpected_value_printer (stderr);
> >     }
> >   fprintf (stderr, "\n%s: expected any of:\n", loc);
> >   for (int i = 0; i < yynexpected; ++i)
> >     fprintf (stderr, "%s:   %s\n, loc, yytname[yyexpected[i]]);
> > } <*> <>
> 
> Yes, indeed.  But note that you are using %printer conveniently since you
> assume that the message is to be sent to the console.  If we're to send it to
> a GUI, to syslog, whatever, we don't have a nice means to use %printer.  This
> is a pity.

Agreed.

> I would have preferred to have this %error-report in charge of
> building the error message, and then another function, yyerror, to be in
> charge of reporting the message.  As is the case today with yysyntax_error vs.
> yyerror.

It seem we're discussing three ways of handling error reporting:

1. The current separation allows Bison to be in control of formatting the 
error message while the Bison user is in control of delivery (via 
yyerror).

2. I thought we wanted to give the Bison user control over both the 
formatting and delivery of error messages.  He can do both within 
%error-report.  If he wants to encapsulate each task separately, he can 
write his own functions and maintain their prototypes without Bison's 
interference.

3. Are you thinking that, in some cases, Bison will want to take over the 
delivery of error messages that the user has formatted?  That's really the 
reverse of Yacc's traditional yyerror mechanism, and I haven't thought of 
a case where it makes sense.  Maybe my imagination just isn't very strong 
today.

I don't see how any of these three cases makes it easier to use %printer 
to write to strings.  While the %printer issue is similar to the question 
of whether to separate error message formatting from delivery, I think 
it's an orthogonal issue.

> No problem for C++, and I guess neither for Java.
> 
> Inappropriate design for C :(  Actually, the flaw is arguably in C itself, too
> bad there is no standard open_memstream, as provided by the GNU Libc :(

Perhaps we could just treat this as a shortcoming of C that will be solved 
eventually by those responsible for C and its libraries.  That is, maybe 
it's not our job to fix it.  In the meantime, those who are fine with 
depending on glibc will be able to use %printer in %error-report freely.

Alternatively, we could ask users to write their %printer like this:

  %printer {
    char *msg = foo_to_string ($$);
    yymessage_append (msg);
    free (msg);
  } <foo>;

In each context that Bison invokes %printer, it can define 
yymessage_append to append to a char* or to push to a FILE* or whatever 
else is needed.  For use in a %error-report that handles both formatting 
and delivery of error messages, Bison could provide wrappers around 
%printer for char* and for FILE*.

> I don't understand how yyunexpected_value_printer would be different from
> merely using %printer as provided by the user.  So actually just
> yyvalue_printer.

I was thinking yyunexpected_value_printer would be a wrapper that invokes 
%printer specifically for the unexpected token's value.  I was trying to 
provide the C user a way to avoid using $$ so Bison doesn't always have to 
build a switch on semantic type for %error-report.  Bison's %printer 
implementation already has the necessary switch.

But maybe you're suggesting that, instead of

  yyunexpected_value_printer (stderr);

the user can write

  yyvalue_printer (stderr, yyunexpected_token, yyunexpected_value);

where the C type of yyunexpected_value is YYSTYPE rather than the C type 
of $$.

So I guess we have 3 proposed approaches for accessing the unexpected 
value in %error-report:

1. yyvalue_printer (stderr, yyunexpected_token, yyunexpected_value);

2. yyunexpected_value_printer (stderr);

3. yyvalue_printer (stderr, $$);

I'm not sure which approach is best.  I believe #3 would provide the most 
consistent interface for the user, but is it worth the extra switch?  
Maybe the extra switch isn't really a significant problem.

reply via email to

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