mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
examples: bistromathic: demonstrate internationalization
Currently it was only using stubs. Let's actually translate the strings using gettext. * examples/c/bistromathic/local.mk: Define LOCALEDIR, BISON_LOCALEDIR and link with libintl. * examples/c/bistromathic/parse.y: Use them. Remove useless includes. Take ENABLE_NLS into account. (error_format_string): New. (yyreport_syntax_error): Rewrite to rely on a format string, which is more appropriate for internationalization. * examples/c/bistromathic/Makefile: We no longer use Flex. We need readline and intl. * doc/bison.texi: Point to bistromathic for a better option for internationalization. * po/POTFILES.in: Add bistromathic.
This commit is contained in:
@@ -7514,7 +7514,9 @@ values, which is always less than @code{YYNTOKENS}.
|
||||
The name of the symbol whose kind is @var{symbol}, possibly translated.
|
||||
@end deftypefun
|
||||
|
||||
A custom syntax error function looks as follows.
|
||||
A custom syntax error function looks as follows. This implementation is
|
||||
inappropriate for internationalization, see the @file{c/bistromathic}
|
||||
example for a better altnative.
|
||||
|
||||
@example
|
||||
int
|
||||
@@ -10601,7 +10603,7 @@ Print the version number of Bison and exit.
|
||||
Print the name of the directory containing locale-dependent data.
|
||||
|
||||
@item --print-datadir
|
||||
Print the name of the directory containing skeletons and XSLT.
|
||||
Print the name of the directory containing skeletons, CSS and XSLT.
|
||||
|
||||
@item -u
|
||||
@item --update
|
||||
@@ -12074,7 +12076,9 @@ values, which is always less than @code{YYNTOKENS}.
|
||||
The name of the symbol whose kind is @var{symbol}, possibly translated.
|
||||
@end deftypemethod
|
||||
|
||||
A custom syntax error function looks as follows.
|
||||
A custom syntax error function looks as follows. This implementation is
|
||||
inappropriate for internationalization, see the @file{c/bistromathic}
|
||||
example for a better altnative.
|
||||
|
||||
@example
|
||||
void
|
||||
@@ -13327,6 +13331,10 @@ public void reportSyntaxError(YYParser.Context ctx) @{
|
||||
System.err.println("");
|
||||
@}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
This implementation is inappropriate for internationalization, see the
|
||||
@file{c/bistromathic} example for a better altnative.
|
||||
@end deftypemethod
|
||||
|
||||
@node Java Action Features
|
||||
|
||||
@@ -57,6 +57,8 @@ This example demonstrates best practices when using Bison.
|
||||
push-parser API to feed the parser with the incoming tokens.
|
||||
- It features an interactive command line with completion based on the
|
||||
parser state, based on `yyexpected_tokens`.
|
||||
- It uses Bison's standard catalogue for internationalization of generated
|
||||
messages.
|
||||
- It uses a custom syntax error with location, lookahead correction and
|
||||
token internationalization.
|
||||
- It supports debug traces with semantic values.
|
||||
|
||||
@@ -3,20 +3,26 @@
|
||||
|
||||
BASE = bistromathic
|
||||
BISON = bison
|
||||
FLEX = flex
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
# We need to find the headers and libs for readline and intl.
|
||||
# You probably need to customize this for your own environment.
|
||||
CPPFLAGS = -I/opt/local/include
|
||||
LDFLAGS = -L/opt/local/lib
|
||||
|
||||
# Find the translation catalogue for Bison's generated messagess.
|
||||
BISON_LOCALEDIR = $(shell $(BISON) $(BISON_FLAGS) --print-localedir)
|
||||
CPPFLAGS += -DENABLE_NLS -DBISON_LOCALEDIR='"$(BISON_LOCALEDIR)"'
|
||||
|
||||
LIBS = -lreadline -lintl
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.c %.h %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
|
||||
|
||||
%.c: %.l
|
||||
$(FLEX) $(FLEXFLAGS) -o$*.c $<
|
||||
|
||||
scan.o: parse.h
|
||||
$(BASE): parse.o scan.o
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
$(BASE): parse.o
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
|
||||
|
||||
run: $(BASE)
|
||||
@echo "Type bistromathic expressions. Quit with ctrl-d."
|
||||
@@ -28,8 +34,7 @@ html: $(BASE).html
|
||||
|
||||
CLEANFILES = \
|
||||
$(BASE) *.o \
|
||||
parse.[ch] parse.output parse.xml parse.html parse.gv \
|
||||
scan.c
|
||||
parse.[ch] parse.output parse.xml parse.html parse.gv
|
||||
|
||||
clean:
|
||||
rm -f $(CLEANFILES)
|
||||
|
||||
@@ -6,6 +6,8 @@ This example demonstrates best practices when using Bison.
|
||||
push-parser API to feed the parser with the incoming tokens.
|
||||
- It features an interactive command line with completion based on the
|
||||
parser state, based on `yyexpected_tokens`.
|
||||
- It uses Bison's standard catalogue for internationalization of generated
|
||||
messages.
|
||||
- It uses a custom syntax error with location, lookahead correction and
|
||||
token internationalization.
|
||||
- It supports debug traces with semantic values.
|
||||
|
||||
@@ -26,8 +26,11 @@ 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 = \
|
||||
-DBISON_LOCALEDIR='"$(localdir)"' \
|
||||
-DLOCALEDIR='"$(localdir)"' \
|
||||
-I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||
%C%_bistromathic_LDADD = -lm -lreadline $(LIBINTL)
|
||||
|
||||
dist_bistromathic_DATA = %D%/parse.y %D%/Makefile %D%/README.md
|
||||
CLEANFILES += %D%/parse.[ch] %D%/parse.output
|
||||
|
||||
@@ -3,13 +3,23 @@
|
||||
%code top {
|
||||
#include <ctype.h> // isdigit
|
||||
#include <math.h> // cos, sin, etc.
|
||||
#include <stddef.h> // ptrdiff_t
|
||||
#include <stdio.h> // printf
|
||||
#include <stdlib.h> // calloc.
|
||||
#include <stdlib.h> // calloc
|
||||
#include <string.h> // strcmp
|
||||
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
#if defined ENABLE_NLS && ENABLE_NLS
|
||||
// Unable the translation of Bison's generated messages.
|
||||
# define YYENABLE_NLS 1
|
||||
# include <libintl.h>
|
||||
// Unless specified otherwise, we expect bistromathic's own
|
||||
// catalogue to be installed in the same tree as Bison's catalogue.
|
||||
# ifndef LOCALEDIR
|
||||
# define LOCALEDIR BISON_LOCALEDIR
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
%code requires {
|
||||
@@ -40,8 +50,12 @@
|
||||
}
|
||||
|
||||
%code {
|
||||
#define N_
|
||||
#define _
|
||||
#if defined ENABLE_NLS && ENABLE_NLS
|
||||
# define _(Msgid) gettext (Msgid)
|
||||
#else
|
||||
# define _(Msgid) (Msgid)
|
||||
#endif
|
||||
#define N_(Msgid) (Msgid)
|
||||
|
||||
// Whether to quit.
|
||||
int done = 0;
|
||||
@@ -286,35 +300,69 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
| Parser. |
|
||||
`---------*/
|
||||
|
||||
|
||||
const char *
|
||||
error_format_string (int argc)
|
||||
{
|
||||
switch (argc)
|
||||
{
|
||||
default: /* Avoid compiler warnings. */
|
||||
case 0: return _("%@: syntax error");
|
||||
case 1: return _("%@: syntax error: unexpected %u");
|
||||
case 2: return _("%@: syntax error: expected %0e before %u");
|
||||
case 3: return _("%@: syntax error: expected %0e or %1e before %u");
|
||||
case 4: return _("%@: syntax error: expected %0e or %1e or %2e before %u");
|
||||
case 5: return _("%@: syntax error: expected %0e or %1e or %2e or %3e before %u");
|
||||
case 6: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e before %u");
|
||||
case 7: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e before %u");
|
||||
case 8: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e or %6e before %u");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
yyreport_syntax_error (const yypcontext_t *ctx)
|
||||
{
|
||||
int res = 0;
|
||||
enum { ARGS_MAX = 7 };
|
||||
yysymbol_kind_t arg[ARGS_MAX];
|
||||
int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
|
||||
if (argsize < 0)
|
||||
return argsize;
|
||||
const char *format = error_format_string (1 + argsize);
|
||||
|
||||
while (*format)
|
||||
// %@: location.
|
||||
if (format[0] == '%' && format[1] == '@')
|
||||
{
|
||||
YY_LOCATION_PRINT (stderr, *yypcontext_location (ctx));
|
||||
fprintf (stderr, ": syntax error");
|
||||
// Report the tokens expected at this point.
|
||||
format += 2;
|
||||
}
|
||||
// %t: unexpected token.
|
||||
else if (format[0] == '%' && format[1] == 'u')
|
||||
{
|
||||
enum { TOKENMAX = 10 };
|
||||
yysymbol_kind_t expected[TOKENMAX];
|
||||
int n = yypcontext_expected_tokens (ctx, expected, TOKENMAX);
|
||||
if (n < 0)
|
||||
// Forward errors to yyparse.
|
||||
res = n;
|
||||
fputs (yysymbol_name (yypcontext_token (ctx)), stderr);
|
||||
format += 2;
|
||||
}
|
||||
// %0e, %1e...: expected token.
|
||||
else if (format[0] == '%'
|
||||
&& isdigit (format[1])
|
||||
&& format[2] == 'e'
|
||||
&& (format[1] - '0') < argsize)
|
||||
{
|
||||
int i = format[1] - '0';
|
||||
fputs (yysymbol_name (arg[i]), stderr);
|
||||
format += 3;
|
||||
}
|
||||
else
|
||||
for (int i = 0; i < n; ++i)
|
||||
fprintf (stderr, "%s %s",
|
||||
i == 0 ? ": expected" : " or", yysymbol_name (expected[i]));
|
||||
}
|
||||
// Report the unexpected token.
|
||||
{
|
||||
yysymbol_kind_t lookahead = yypcontext_token (ctx);
|
||||
if (lookahead != YYSYMBOL_YYEMPTY)
|
||||
fprintf (stderr, " before %s", yysymbol_name (lookahead));
|
||||
fputc (*format, stderr);
|
||||
++format;
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
return res;
|
||||
fputc ('\n', stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Called by yyparse on error.
|
||||
void yyerror (YYLTYPE *loc, char const *msg)
|
||||
{
|
||||
@@ -467,6 +515,18 @@ void init_readline (void)
|
||||
|
||||
int main (int argc, char const* argv[])
|
||||
{
|
||||
#if defined ENABLE_NLS && ENABLE_NLS
|
||||
// Set up internationalization.
|
||||
setlocale (LC_ALL, "");
|
||||
// Use Bison's standard translation catalogue for error messages
|
||||
// (the generated messages).
|
||||
bindtextdomain ("bison-runtime", BISON_LOCALEDIR);
|
||||
// The translation catalogue of bistromathic is actually included in
|
||||
// Bison's. In your own project, use the name of your project.
|
||||
bindtextdomain ("bison", LOCALEDIR);
|
||||
textdomain ("bison");
|
||||
#endif
|
||||
|
||||
// Enable parse traces on option -p.
|
||||
if (argc == 2 && strcmp (argv[1], "-p") == 0)
|
||||
yydebug = 1;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
examples/c/bistromathic/parse.y
|
||||
src/complain.c
|
||||
src/conflicts.c
|
||||
src/files.c
|
||||
|
||||
Reference in New Issue
Block a user