bug-bison
[Top][All Lists]
Advanced

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

Re: i18n for yacc backend messages


From: Jan Nieuwenhuizen
Subject: Re: i18n for yacc backend messages
Date: Thu, 14 Apr 2005 00:35:47 +0200
User-agent: Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3.50 (gnu/linux)

Paul Eggert writes:

> In your proposed patch, some of the strings in yacc.c weren't marked
> for translation; was that intended?

No, thanks for fixing that.

> Also, I'm a bit leery of of definitions like SYNTAX_ERROR_UNEXPECTED4
> that hardware the number 5 into the code, in many ways.

Yes, it's even less elegant than what was there before.

> Would it be OK simply to mimic the current code?  That won't result
> in translations that are quite as nice, but it might be good enough.

It would for English-like languages like Dutch, but I'm quite sure
this will be problematic for other languages; I think translators
really need a sentence to translate.  If necessary, we could ask the
translation project (François Pinard).

I'll see if I can come up with something better, how's the patch below?

Thanks for your quick reply,
Jan.


Index: NEWS
===================================================================
RCS file: /cvsroot/bison/bison/NEWS,v
retrieving revision 1.110
diff -p -u -r1.110 NEWS
--- NEWS        26 Dec 2004 05:49:52 -0000      1.110
+++ NEWS        13 Apr 2005 22:31:27 -0000
@@ -1,6 +1,12 @@
 Bison News
 ----------
 
+Changes in version 2.1, ????-??-??:
+
+* Bison-generated C parsers use the _ macro to translate strings from
+  English to the user's language, e.g., _("syntax error").  By default,
+  _ is defined to be a no-op macro so the strings are not translated.
+
 Changes in version 2.0, 2004-12-25:
 
 * Possibly-incompatible changes
Index: data/c.m4
===================================================================
RCS file: /cvsroot/bison/bison/data/c.m4,v
retrieving revision 1.26
diff -p -u -r1.26 c.m4
--- data/c.m4   24 Sep 2004 14:14:58 -0000      1.26
+++ data/c.m4   13 Apr 2005 22:31:27 -0000
@@ -309,6 +309,15 @@ m4_define([b4_c_args],
 m4_define([b4_c_arg],
 [$2])
 
+# b4_gettext_list([STRING1], ...)
+# -------------------------------
+# Output the arguments _(STRING1), _(STRING2)...
+m4_define([b4_gettext_list],
+[m4_map([b4_gettext_map], $@)])
+
+m4_define([b4_gettext_map],
+[m4_map_sep([[_]], [, ], address@hidden)])
+
 
 ## ----------- ##
 ## Synclines.  ##
Index: data/yacc.c
===================================================================
RCS file: /cvsroot/bison/bison/data/yacc.c,v
retrieving revision 1.83
diff -p -u -r1.83 yacc.c
--- data/yacc.c 17 Mar 2005 19:19:44 -0000      1.83
+++ data/yacc.c 13 Apr 2005 22:31:27 -0000
@@ -373,6 +373,29 @@ static const char *const yytname[] =
 {
   ]b4_tname[
 };
+# if 0
+static char const *yytname_gettext_helper[] =
+{
+  ]b4_gettext_list([b4_tname])[
+};
+# endif
+
+#define YYEXPECTINGMAX 5
+static char const* SYNTAX_ERROR_UNEXPECTED[] =
+{
+  _ ("syntax error, unexpected %s"),
+  _ ("syntax error, unexpected %s, expecting %s"),
+  _ ("syntax error, unexpected %s, expecting %s or %s"),
+  _ ("syntax error, unexpected %s, expecting %s or %s or %s"),
+  _ ("syntax error, unexpected %s, expecting %s or %s or %s or %s"),
+  0,
+};
+
+#endif
+
+/* INFRINGES ON USER NAME SPACE */
+#ifndef _
+# define _(msgid) msgid
 #endif
 
 # ifdef YYPRINT
@@ -492,7 +515,7 @@ do                                                          
\
     }                                                          \
   else                                                         \
     {                                                          \
-      yyerror (]b4_yyerror_args["syntax error: cannot back up");\
+      yyerror (]b4_yyerror_args[_("syntax error: cannot back up")); \
       YYERROR;                                                 \
     }                                                          \
 while (0)
@@ -586,7 +609,7 @@ do {                                                        
        \
                    [[short int *bottom], [bottom]],
                    [[short int *top],    [top]])[
 {
-  YYFPRINTF (stderr, "Stack now");
+  YYFPRINTF (stderr, _("Stack now"));
   for (/* Nothing. */; bottom <= top; ++bottom)
     YYFPRINTF (stderr, " %d", *bottom);
   YYFPRINTF (stderr, "\n");
@@ -608,12 +631,12 @@ do {                                                      
        \
 {
   int yyi;
   unsigned int yylno = yyrline[yyrule];
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+  YYFPRINTF (stderr, _("Reducing stack by rule %d (line %u), "),
              yyrule - 1, yylno);
   /* Print the symbols being reduced, and their result.  */
   for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
-    YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
-  YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+    YYFPRINTF (stderr, "%s ", _(yytname [yyrhs[yyi]]));
+  YYFPRINTF (stderr, "-> %s\n", _(yytname [yyr1[yyrule]]));
 }
 
 # define YY_REDUCE_PRINT(Rule)         \
@@ -877,7 +900,7 @@ b4_syncline(address@hidden@], address@hidden@])])dnl
           data in use in that stack, in bytes.  This used to be a
           conditional around just the two extra args, but that might
           be undefined if yyoverflow is a macro.  */
-       yyoverflow ("parser stack overflow",
+       yyoverflow (_("parser stack overflow"),
                    &yyss1, yysize * sizeof (*yyssp),
                    &yyvs1, yysize * sizeof (*yyvsp),
 ]b4_location_if([                  &yyls1, yysize * sizeof (*yylsp),])[
@@ -917,14 +940,14 @@ b4_syncline(address@hidden@], address@hidden@])])dnl
       yyvsp = yyvs + yysize - 1;
 ]b4_location_if([      yylsp = yyls + yysize - 1;])[
 
-      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+      YYDPRINTF ((stderr, _("Stack size increased to %lu\n"),
                  (unsigned long int) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
        YYABORT;
     }
 
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+  YYDPRINTF ((stderr, _("Entering state %d\n"), yystate));
 
   goto yybackup;
 
@@ -948,19 +971,19 @@ yybackup:
   /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
   if (yychar == YYEMPTY)
     {
-      YYDPRINTF ((stderr, "Reading a token: "));
+      YYDPRINTF ((stderr, _("Reading a token: ")));
       yychar = YYLEX;
     }
 
   if (yychar <= YYEOF)
     {
       yychar = yytoken = YYEOF;
-      YYDPRINTF ((stderr, "Now at end of input.\n"));
+      YYDPRINTF ((stderr, _("Now at end of input.\n")));
     }
   else
     {
       yytoken = YYTRANSLATE (yychar);
-      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+      YY_SYMBOL_PRINT (_("Next token is"), yytoken, &yylval, &yylloc);
     }
 
   /* If the proper action on seeing token YYTOKEN is to reduce or to
@@ -981,7 +1004,7 @@ yybackup:
     YYACCEPT;
 
   /* Shift the look-ahead token.  */
-  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+  YY_SYMBOL_PRINT (_("Shifting"), yytoken, &yylval, &yylloc);
 
   /* Discard the token being shifted unless it is eof.  */
   if (yychar != YYEOF)
@@ -1078,7 +1101,6 @@ yyerrlab:
        {
          YYSIZE_T yysize = 0;
          int yytype = YYTRANSLATE (yychar);
-         const char* yyprefix;
          char *yymsg;
          int yyx;
 
@@ -1090,47 +1112,42 @@ yyerrlab:
          int yychecklim = YYLAST - yyn;
          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
          int yycount = 0;
-
-         yyprefix = ", expecting ";
-         for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-           if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-             {
-               yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
-               yycount += 1;
-               if (yycount == 5)
+         char const **yytnamei = (char const**) YYSTACK_ALLOC (YYEXPECTINGMAX);
+         if (yytnamei != 0)
+           {
+             for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+               if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
                  {
-                   yysize = 0;
-                   break;
+                   yytnamei[yycount] = _ (yytname[yyx]);
+                   yysize += yystrlen (yytnamei[yycount]);
+                   yycount += 1;
+                   if (yycount == YYEXPECTINGMAX)
+                     {
+                       yycount = 0;
+                       yysize = 0;
+                       break;
+                     }
                  }
-             }
-         yysize += (sizeof ("syntax error, unexpected ")
-                    + yystrlen (yytname[yytype]));
-         yymsg = (char *) YYSTACK_ALLOC (yysize);
+             yysize += yystrlen (_ (yytname[yytype]));
+             yysize += strlen (SYNTAX_ERROR_UNEXPECTED[yycount]);
+             yymsg = (char *) YYSTACK_ALLOC (yysize);
+             if (yymsg != 0)
+               sprintf (yymsg, SYNTAX_ERROR_UNEXPECTED[yycount],
+                        _ (yytname[yytype]), *yytnamei);
+             YYSTACK_FREE (yytnamei);
+           }
+         
          if (yymsg != 0)
            {
-             char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
-             yyp = yystpcpy (yyp, yytname[yytype]);
-
-             if (yycount < 5)
-               {
-                 yyprefix = ", expecting ";
-                 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-                   if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-                     {
-                       yyp = yystpcpy (yyp, yyprefix);
-                       yyp = yystpcpy (yyp, yytname[yyx]);
-                       yyprefix = " or ";
-                     }
-               }
              yyerror (]b4_yyerror_args[yymsg);
              YYSTACK_FREE (yymsg);
            }
          else
-           yyerror (]b4_yyerror_args["syntax error; also virtual memory 
exhausted");
+           yyerror (]b4_yyerror_args[_("syntax error; also virtual memory 
exhausted"));
        }
       else
 #endif /* YYERROR_VERBOSE */
-       yyerror (]b4_yyerror_args["syntax error");
+       yyerror (]b4_yyerror_args[_("syntax error"));
     }
 
 ]b4_location_if([[  yyerror_range[0] = yylloc;]])[
@@ -1151,13 +1168,13 @@ yyerrlab:
                 YYPOPSTACK;
                 if (yyssp == yyss)
                   YYABORT;
-                yydestruct ("Error: popping",
+                yydestruct (_("Error: popping"),
                              yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[);
               }
         }
       else
        {
-         yydestruct ("Error: discarding", yytoken, &yylval]b4_location_if([, 
&yylloc])[);
+         yydestruct (_("Error: discarding"), yytoken, 
&yylval]b4_location_if([, &yylloc])[);
          yychar = YYEMPTY;
        }
     }
@@ -1211,7 +1228,7 @@ yyerrlab1:
        YYABORT;
 
 ]b4_location_if([[      yyerror_range[0] = *yylsp;]])[
-      yydestruct ("Error: popping", yystos[yystate], yyvsp]b4_location_if([, 
yylsp])[);
+      yydestruct (_("Error: popping"), yystos[yystate], 
yyvsp]b4_location_if([, yylsp])[);
       YYPOPSTACK;
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
@@ -1229,7 +1246,7 @@ yyerrlab1:
   *++yylsp = yyloc;]])[
 
   /* Shift the error token. */
-  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+  YY_SYMBOL_PRINT (_("Shifting"), yystos[yyn], yyvsp, yylsp);
 
   yystate = yyn;
   goto yynewstate;
@@ -1246,7 +1263,7 @@ yyacceptlab:
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
 yyabortlab:
-  yydestruct ("Error: discarding lookahead",
+  yydestruct (_("Error: discarding lookahead"),
               yytoken, &yylval]b4_location_if([, &yylloc])[);
   yychar = YYEMPTY;
   yyresult = 1;
@@ -1257,7 +1274,7 @@ yyabortlab:
 | yyoverflowlab -- parser overflow comes here.  |
 `----------------------------------------------*/
 yyoverflowlab:
-  yyerror (]b4_yyerror_args["parser stack overflow");
+  yyerror (]b4_yyerror_args[_("parser stack overflow"));
   yyresult = 2;
   /* Fall through.  */
 #endif
Index: doc/bison.texinfo
===================================================================
RCS file: /cvsroot/bison/bison/doc/bison.texinfo,v
retrieving revision 1.142
diff -p -u -r1.142 bison.texinfo
--- doc/bison.texinfo   1 Mar 2005 00:41:33 -0000       1.142
+++ doc/bison.texinfo   13 Apr 2005 22:31:28 -0000
@@ -1166,7 +1166,14 @@ start with a function called @code{main}
 arrange for it to call @code{yyparse} or the parser will never run.
 @xref{Interface, ,Parser C-Language Interface}.
 
-Aside from the token type names and the symbols in the actions you
+If your code defines a C preprocessor macro @code{_} (a single
+underscore), Bison assumes that it can be used to translate
+English-language strings to the user's preferred language using a
+function-like syntax, e.g., @code{_("syntax error")}.  Otherwise,
+Bison defines a no-op macro by that name that merely returns its
+argument, so strings are not translated.
+
+Aside from @code{_} and the token type names and the symbols in the actions you
 write, all symbols defined in the Bison parser file itself
 begin with @samp{yy} or @samp{YY}.  This includes interface functions
 such as the lexical analyzer function @code{yylex}, the error reporting


-- 
Jan Nieuwenhuizen <address@hidden> | GNU LilyPond - The music typesetter
http://www.xs4all.nl/~jantien       | http://www.lilypond.org




reply via email to

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