which reads tokens.
* Error Reporting:: You must supply a function @code{yyerror}.
* Action Features:: Special features for use in actions.
+* Internationalization:: How to let the parser speak in the user's
+ native language.
The Lexical Analyzer Function @code{yylex}
arrange for it to call @code{yyparse} or the parser will never run.
@xref{Interface, ,Parser C-Language Interface}.
-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
+Aside from 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
which reads tokens.
* Error Reporting:: You must supply a function @code{yyerror}.
* Action Features:: Special features for use in actions.
+* Internationalization:: How to let the parser speak in the user's
+ native language.
@end menu
@node Parser Function
Tracking Locations}.
@end deffn
+@node Internationalization
+@section Parser Internationalization
+@cindex internationalization
+@cindex i18n
+@cindex NLS
+@cindex gettext
+@cindex bison-po
+
+A Bison-generated parser can print diagnostics, including error and
+tracing messages. By default, they appear in English. However, Bison
+also supports outputting diagnostics in the user's native language.
+To make this work, the user should set the usual environment
+variables. @xref{Using gettextized software, , User influence on
+@code{gettext}, libc, The GNU C Library Reference Manual}. For
+example, the shell command @samp{export LC_ALL=fr_CA.UTF-8} might set
+the user's locale to French Canadian using the @acronym{UTF}-8
+encoding. The exact set of available locales depends on the user's
+installation.
+
+The maintainer of a package that uses a Bison-generated parser enables
+the internationalization of the parser's output through the following
+steps. Here we assume a package that uses @acronym{GNU} Autoconf and
+@acronym{GNU} Automake.
+
+@enumerate
+@item
+Into the directory containing the @acronym{GNU} Autoconf macros used
+by the package---often called @file{m4}---copy the
+@file{bison-i18n.m4} file installed by Bison under
+@samp{share/aclocal/bison-i18n.m4} in Bison's installation directory.
+For example:
+
+@example
+cp /usr/local/share/aclocal/bison-i18n.m4 m4/bison-i18n.m4
+@end example
+
+@item
+In the top-level @file{configure.ac}, after the @code{AM_GNU_GETTEXT}
+invocation, add an invocation of @code{BISON_I18N}. This macro is
+defined in the file @file{bison-i18n.m4} that you copied earlier. It
+causes @samp{configure} to find the value of the
+@code{BISON_LOCALEDIR} variable.
+
+@item
+In the @code{main} function of your program, designate the directory
+containing Bison's runtime message catalog, through a call to
+@samp{bindtextdomain} with domain name @samp{bison-runtime}.
+For example:
+
+@example
+bindtextdomain ("bison-runtime", BISON_LOCALEDIR);
+@end example
+
+Typically this appears after any other call @code{bindtextdomain
+(PACKAGE, LOCALEDIR)} that your package already has. Here we rely on
+@samp{BISON_LOCALEDIR} to be defined as a string through the
+@file{Makefile}.
+
+@item
+In the @file{Makefile.am} that controls the compilation of the @code{main}
+function, make @samp{BISON_LOCALEDIR} available as a C preprocessor macro,
+either in @samp{DEFS} or in @samp{AM_CPPFLAGS}. For example:
+
+@example
+DEFS = @@DEFS@@ -DBISON_LOCALEDIR='"$(BISON_LOCALEDIR)"'
+@end example
+
+or:
+
+@example
+AM_CPPFLAGS = -DBISON_LOCALEDIR='"$(BISON_LOCALEDIR)"'
+@end example
+
+@item
+Finally, invoke the command @command{autoreconf} to generate the build
+infrastructure.
+@end enumerate
+
@node Algorithm
@chapter The Bison Parser Algorithm
;
@end example
+For a more detailed exposition of @acronym{LALR}(1) parsers and parser
+generators, please see:
+Frank DeRemer and Thomas Pennello, Efficient Computation of
+@acronym{LALR}(1) Look-Ahead Sets, @cite{@acronym{ACM} Transactions on
+Programming Languages and Systems}, Vol.@: 4, No.@: 4 (October 1982),
+pp.@: 615--649 @uref{http://doi.acm.org/10.1145/69622.357187}.
+
@node Generalized LR Parsing
@section Generalized @acronym{LR} (@acronym{GLR}) Parsing
@cindex @acronym{GLR} parsing
@itemx --version
Print the version number of Bison and exit.
+@item --print-localedir
+Print the name of the directory containing locale-dependent data.
+
@need 1750
@item -y
@itemx --yacc
\line{ --no-lines \leaderfill -l}
\line{ --no-parser \leaderfill -n}
\line{ --output \leaderfill -o}
+\line{ --print-localedir}
\line{ --token-table \leaderfill -k}
\line{ --verbose \leaderfill -v}
\line{ --version \leaderfill -V}
--no-lines -l
--no-parser -n
--output=@var{outfile} -o @var{outfile}
+--print-localedir
--token-table -k
--verbose -v
--version -V
@c - Always pure
@c - initial action
-The C++ parser LALR(1) skeleton is named @file{lalr1.cc}. To select
+The C++ parser @acronym{LALR}(1) skeleton is named @file{lalr1.cc}. To select
it, you may either pass the option @option{--skeleton=lalr1.cc} to
Bison, or include the directive @samp{%skeleton "lalr1.cc"} in the
grammar preamble. When run, @command{bison} will create several
it describes an additional member of the parser class, and an
additional argument for its constructor.
-@deftypemethod {parser} {semantic_value_type}
-@deftypemethodx {parser} {location_value_type}
+@defcv {Type} {parser} {semantic_value_type}
+@defcvx {Type} {parser} {location_value_type}
The types for semantics value and locations.
-@c FIXME: deftypemethod pour des types ???
-@end deftypemethod
+@end defcv
@deftypemethod {parser} {} parser (@var{type1} @var{arg1}, ...)
Build a new parser object. There are no arguments by default, unless
follows. The first part includes the CPP guard and imports the
required standard library components.
+@comment file: calc++-driver.hh
@example
#ifndef CALCXX_DRIVER_HH
# define CALCXX_DRIVER_HH
by the rest of the project, it is saner to forward declare the
parser's information here.
+@comment file: calc++-driver.hh
@example
// Forward declarations.
union YYSTYPE;
-namespace yy @{ class calcxx_parser; @}
+namespace yy
+@{
+ class location;
+ class calcxx_parser;
+@}
class calcxx_driver;
@end example
the signature of @code{yylex} to be defined in the macro
@code{YY_DECL}, and the C++ parser expects it to be declared. We can
factor both as follows.
+
+@comment file: calc++-driver.hh
@example
// Announce to Flex the prototype we want for lexing function, ...
-# define YY_DECL \
+# define YY_DECL \
int yylex (YYSTYPE* yylval, yy::location* yylloc, calcxx_driver& driver)
// ... and declare it for the parser's sake.
YY_DECL;
The @code{calcxx_driver} class is then declared with its most obvious
members.
+@comment file: calc++-driver.hh
@example
// Conducting the whole scanning and parsing of Calc++.
class calcxx_driver
have two members function to open and close the scanning phase.
members.
+@comment file: calc++-driver.hh
@example
// Handling the scanner.
void scan_begin ();
@noindent
Similarly for the parser itself.
+@comment file: calc++-driver.hh
@example
// Handling the parser.
void parse (const std::string& f);
compiler driver using the following two member functions. Finally, we
close the class declaration and CPP guard.
+@comment file: calc++-driver.hh
@example
// Error handling.
void error (const yy::location& l, const std::string& m);
are simple stubs, they should actually register the located error
messages and set error state.
+@comment file: calc++-driver.cc
@example
#include "calc++-driver.hh"
#include "calc++-parser.hh"
for the C++ skeleton, the creation of the parser header file, and
specifies the name of the parser class. It then includes the required
headers.
+
+@comment file: calc++-parser.yy
@example
%skeleton "lalr1.cc" /* -*- C++ -*- */
%define "parser_class_name" "calcxx_parser"
This provides a simple but effective pure interface, not relying on
global variables.
+@comment file: calc++-parser.yy
@example
// The parsing context.
%parse-param @{ calcxx_driver& driver @}
relatively to the previous locations: the file name will be
automatically propagated.
+@comment file: calc++-parser.yy
@example
%locations
%initial-action
Use the two following directives to enable parser tracing and verbose
error messages.
+@comment file: calc++-parser.yy
@example
%debug
%error-verbose
Semantic values cannot use ``real'' objects, but only pointers to
them.
+@comment file: calc++-parser.yy
@example
// Symbols.
%union
symbol. Note that the tokens names are prefixed by @code{TOKEN_} to
avoid name clashes.
+@comment file: calc++-parser.yy
@example
%token YYEOF 0 "end of file"
%token TOKEN_ASSIGN ":="
To enable memory deallocation during error recovery, use
@code{%destructor}.
+@comment file: calc++-parser.yy
@example
%printer @{ debug_stream () << *$$; @} "identifier"
%destructor @{ delete $$; @} "identifier"
@noindent
The grammar itself is straightforward.
+@comment file: calc++-parser.yy
@example
%%
%start unit;
Finally the @code{error} member function registers the errors to the
driver.
+@comment file: calc++-parser.yy
@example
void
-yy::calcxx_parser::error (const location_type& l, const std::string& m)
+yy::calcxx_parser::error (const yy::calcxx_parser::location_type& l,
+ const std::string& m)
@{
driver.error (l, m);
@}
The Flex scanner first includes the driver declaration, then the
parser's to get the set of defined tokens.
+@comment file: calc++-scanner.ll
@example
%@{ /* -*- C++ -*- */
# include <string>
actual file, this is not an interactive session with the user.
Finally we enable the scanner tracing features.
+@comment file: calc++-scanner.ll
@example
%option noyywrap nounput batch debug
@end example
@noindent
Abbreviations allow for more readable rules.
+@comment file: calc++-scanner.ll
@example
id [a-zA-Z][a-zA-Z_0-9]*
int [0-9]+
is moved onto the end cursor to effectively ignore the blanks
preceding tokens. Comments would be treated equally.
+@comment file: calc++-scanner.ll
@example
+%@{
+# define YY_USER_ACTION yylloc->columns (yyleng);
+%@}
%%
%@{
yylloc->step ();
-# define YY_USER_ACTION yylloc->columns (yyleng);
%@}
@{blank@}+ yylloc->step ();
[\n]+ yylloc->lines (yyleng); yylloc->step ();
The rules are simple, just note the use of the driver to report
errors.
+@comment file: calc++-scanner.ll
@example
[-+*/] return yytext[0];
":=" return TOKEN_ASSIGN;
Finally, because the scanner related driver's member function depend
on the scanner's data, it is simpler to implement them in this file.
+@comment file: calc++-scanner.ll
@example
void
calcxx_driver::scan_begin ()
The top level file, @file{calc++.cc}, poses no problem.
+@comment file: calc++.cc
@example
#include <iostream>
#include "calc++-driver.hh"