bug-bison
[Top][All Lists]
Advanced

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

Re: [Bison-Announce] Bison 3.5.90 released [beta]


From: Akim Demaille
Subject: Re: [Bison-Announce] Bison 3.5.90 released [beta]
Date: Sun, 19 Apr 2020 09:19:21 +0200

Hi Frank!

> Le 18 avr. 2020 à 17:08, Frank Heckenbach <address@hidden> a écrit :
> 
> Akim Demaille wrote:
> 
>> So **please** take the time to play with this beta,
> 
> So far it works well with my parsers.

Great news!  While I have taken care of not breaking backward
compatibility (and in fact the test suite is still using the
old names), s*t happens, so it is reassuring to know that it
works well for you.


>> in particular to
>> see how these features allow you to get rid of dirty hacks you needed
>> to customize your error messages (I listed several such examples in
>> https://lists.gnu.org/r/bison-patches/2020-01/msg00000.html).
> 
> I haven't used any such hacks, but I might start i14ing my parsers

(there were also hacks for people who want to play with quotes
around the token names).

> now that it's properly supported. On that subject:
> 
>>  Therefore, by default, error messages now refer to "end of file"
>>  (internationalized) rather than the cryptic "$end", or to "invaid token"
> 
> Typo: "invaid" (only in NEWS apparently).

Thanks, I've fixed that.


>> **** Token aliases internationalization
>> 
>>  When the %define variable parse.error is set to `custom` or `detailed`,
>>  one may specify which token aliases are to be translated using _().  For
>>  instance
>> 
>>    %token
>>        PLUS   "+"
>>        MINUS  "-"
>>      <double>
>>        NUM _("double precision number")
>>      <symrec*>
>>        FUN _("function")
>>        VAR _("variable")
>> 
>>  In that case the user must define _() and N_(), and yysymbol_name returns
>>  the translated symbol (i.e., it returns '_("variable")' rather that
>>  '"variable"').  In Java, the user must provide an i18n() function.
> 
> I've used GNU gettext, but not those (strange IMHO) macros with it,
> so I had to find out what to define them to. You might want to
> elaborate a bit on that.

So I guess I should point people to the documentation of gettext.
I can elaborate a bit more, but I should not aim at a full description
of how to add i18n, that's way out of scope.

> In examples/c/bistromathic/parse.y I see just:
> 
>  #define N_
>  #define _
> 
> If I do that, I get the compiler warning:
> 
>   error: this condition has identical branches [-Werror=duplicated-branches]
> 
> about:
> 
>    return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
>            ? _(yy_sname[yysymbol])
>            : yy_sname[yysymbol]);
> 
> Not sure if you consider this a problem, since this seems to be just
> "nop" i14ing.

Yes, that's not the typical set up :)

> Looking further in several tests, I found that apparently "N_"
> (unlike "_") should indeed always be defined as a nop

Yes.  '_' serves two purposes: one is that at runtime it is actually
consulting the translation dictionary to return the translation, the
other is that it is recognized as a markup for strings to
internationalize by the i18n tools that scan the source code.

However in C you can't call a function when you define a table,
so you need to split in two: 'N_' serves as markup, and does nothing,
while '_' actually translates.


> -- but if so,
> can't the skeleton do this by itself?

Hum.

Good point.

I guess it would be ok to just define it if N_ is not yet
#defined.


> Also, since I don't use autoblah,

:) :) :)

> it seems I have to define both
> YYENABLE_NLS and ENABLE_NLS. The former is mentioned in the manual
> (but only in conjunction with autoblah), the latter not at all.
> 
> So if I got it correctly now, this seems to be the minimum required
> for i18n, apart from the bindtextdomain call. Is that correct?
> 
> %define parse.error detailed
> %{
> #define YYENABLE_NLS 1
> #define ENABLE_NLS 1
> #define N_
> static auto _ (const char *s) { return dgettext ("mydomain", s); }
> %}

I don't think this is the right approach.  I think you are trying
to exploit the fact that the skeleton is actually already having
support to translate its own messages ("syntax error, expected...").


Rather I had something like the attachement in mind.  I am very
afraid about really installing this in the source tree, because I
expect tons of portability issues here: the examples are meant to
be self-contained, independent of bison's build, so I cannot use
the same tricks to be portable.

But I agree it would be better to actually demonstrate the whole
process in bistromathic.  I'll see what I can do.

Cheers!

 
commit c993d94c918cdeb60c9d0eb7f8e183697316169c
Author: Akim Demaille <address@hidden>
Date:   Sun Apr 19 09:13:47 2020 +0200

    examples: bistromathic: demontrate internationalization
    
    Currently it was only using stubs.  Let's actually translate the
    strings using gettext.
    
    * examples/c/bistromathic/local.mk: Define LOCALEDIR and link with
    libintl.
    * examples/c/bistromathic/parse.y: Use them.

diff --git a/examples/c/bistromathic/local.mk b/examples/c/bistromathic/local.mk
index cab026e2..f3b9045d 100644
--- a/examples/c/bistromathic/local.mk
+++ b/examples/c/bistromathic/local.mk
@@ -26,8 +26,10 @@ nodist_%C%_bistromathic_SOURCES = %D%/parse.y %D%/parse.h
 %D%/parse.c: $(dependencies)
 
 # Don't use gnulib's system headers.
-%C%_bistromathic_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
-%C%_bistromathic_LDADD = -lm -lreadline
+%C%_bistromathic_CPPFLAGS =                    \
+  -DLOCALEDIR='"$(localdir)"'                  \
+  -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
+%C%_bistromathic_LDADD = -lm -lreadline -lintl
 
 dist_bistromathic_DATA = %D%/parse.y %D%/Makefile %D%/README.md
 CLEANFILES += %D%/parse.[ch] %D%/parse.output
diff --git a/examples/c/bistromathic/parse.y b/examples/c/bistromathic/parse.y
index a3b34c38..a868def9 100644
--- a/examples/c/bistromathic/parse.y
+++ b/examples/c/bistromathic/parse.y
@@ -10,6 +10,10 @@
 
   #include <readline/readline.h>
   #include <readline/history.h>
+
+  #ifdef LOCALEDIR
+  # include <libintl.h>
+  #endif
 }
 
 %code requires {
@@ -40,8 +44,12 @@
 }
 
 %code {
-#define N_
-#define _
+  #ifdef LOCALEDIR
+  # define _(Msgid)  gettext (Msgid)
+  #else
+  # define _(Msgid)  (Msgid)
+  #endif
+  #define N_(Msgid) (Msgid)
 
   // Whether to quit.
   int done = 0;
@@ -467,6 +475,13 @@ void init_readline (void)
 
 int main (int argc, char const* argv[])
 {
+#ifdef LOCALEDIR
+  // Set up internationalization.
+  setlocale (LC_ALL, "");
+  bindtextdomain ("bistromathic", LOCALEDIR);
+  textdomain ("bistromathic");
+#endif
+
   // Enable parse traces on option -p.
   if (argc == 2 && strcmp (argv[1], "-p") == 0)
     yydebug = 1;




reply via email to

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