bison-patches
[Top][All Lists]
Advanced

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

Re: [RFA] Java skeleton


From: Paolo Bonzini
Subject: Re: [RFA] Java skeleton
Date: Mon, 29 Jan 2007 20:07:15 +0100
User-agent: Thunderbird 1.5.0.9 (Macintosh/20061207)

If you still have it, could you please send me the patch so I can look it over more easily? The archives often mangle code, and cvs diff isn't quite so nice as svn diff.

Sorry.

Here is exactly what I committed (there were some changes since I posted the patch, so I regenerated the patch from CVS using -D).

Paolo
2007-01-29  Paolo Bonzini  <address@hidden>

        * NEWS: Mention java.
        * TODO: Remove things that are done.
        * bootstrap.conf: Add javacomp-script and javaexec-script.
        * configure.ac: Invoke gt_JAVACOMP and gt_JAVAEXEC.

        * data/Makefile.am: Add new files.
        * data/java-skel.m4: New.
        * data/java.m4: New.
        * data/lalr1.java: New.

        * doc/bison.texinfo: Put "A Complete C++ Example" under
        C++ Parsers.  Add Java Parsers.  Put C++ Parsers and Java Parsers
        under Other Languages.

        * src/getargs.c (valid_languages): Add Java.
        * src/getargs.h (struct bison_language): Update size of string fields.

        * tests/Makefile.am: Add java.at.
        * tests/atlocal.in: Add CONF_JAVA and CONF_JAVAC.
        * tests/java.at: New.
        * tests/testsuite.at: Include it.


Index: NEWS
===================================================================
RCS file: /sources/bison/bison/NEWS,v
retrieving revision 1.172
retrieving revision 1.173
diff -u -p -r1.172 -r1.173
--- NEWS        17 Jan 2007 08:36:07 -0000      1.172
+++ NEWS        29 Jan 2007 10:54:42 -0000      1.173
@@ -92,6 +92,9 @@ Changes in version 2.3a+ (????-??-??):
 
 Changes in version 2.3a, 2006-09-13:
 
+* Bison now supports generating Java parsers.  Grammars written for
+  the Java language should include the `%language "Java"' directive.
+
 * Instead of %union, you can define and use your own union type
   YYSTYPE if your grammar contains at least one <type> tag.
   Your YYSTYPE need not be a macro; it can be a typedef.
Index: TODO
===================================================================
RCS file: /sources/bison/bison/TODO,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -p -r1.99 -r1.100
--- TODO        13 Dec 2006 20:23:19 -0000      1.99
+++ TODO        29 Jan 2007 10:54:42 -0000      1.100
@@ -14,13 +14,6 @@ find something clean (not like YYLSP_NEE
 
 * Installation
 
-** Disable installation of yacc.
-
-Add an option to 'configure' that allows people to install Bison
-without installing the yacc wrapper script or the rarely-used little
-yacc library required by Posix.  This is for people who prefer some
-other implementation of yacc.
-
 * Documentation
 Before releasing, make sure the documentation ("Understanding your
 parser") refers to the current `output' format.
@@ -154,23 +147,6 @@ Are there any Texinfo standards for bibl
 * Java, Fortran, etc.
 
 
-** Java
-
-There are a couple of proposed outputs:
-
-- BYACC/J
-  which is based on Byacc.
-  <http://troi.lincom-asg.com/~rjamison/byacc/>
-
-- Bison Java
-  which is based on Bison.
-  <http://www.goice.co.jp/member/mo/hack-progs/bison-java.html>
-
-Sebastien Serrurier (address@hidden) is working on this: he is
-expected to contact the authors, design the output, and implement it
-into Bison.
-
-
 * Coding system independence
 Paul notes:
 
@@ -231,9 +207,6 @@ It is unfortunate that there is a total 
 makes it impossible to have modular precedence information.  We should
 move to partial orders (sounds like series/parallel orders to me).
 
-This will be possible with a Bison parser for the grammar, as it will
-make it much easier to extend the grammar.
-
 ** Correlation b/w precedence and associativity
 Also, I fail to understand why we have to assign the same
 associativity to operators with the same precedence.  For instance,
Index: bootstrap.conf
===================================================================
RCS file: /sources/bison/bison/bootstrap.conf,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -p -r1.5 -r1.6
--- bootstrap.conf      8 Nov 2006 20:41:55 -0000       1.5
+++ bootstrap.conf      29 Jan 2007 10:54:42 -0000      1.6
@@ -21,9 +21,10 @@
 # gnulib modules used by this package.
 gnulib_modules='
        argmatch config-h configmake dirname error extensions fopen-safer
-       getopt gettext hash inttypes malloc mbswidth obstack quote
-       quotearg stdbool stpcpy strerror strtoul strverscmp unistd
-       unistd-safer unlocked-io verify xalloc xalloc-die xstrndup
+       getopt gettext hash inttypes javacomp-script javaexec-script malloc
+       mbswidth obstack quote quotearg stdbool stpcpy strerror strtoul
+       strverscmp unistd unistd-safer unlocked-io verify xalloc xalloc-die
+       xstrndup
 '
 
 # Any gnulib files needed that are not in modules.
Index: configure.ac
===================================================================
RCS file: /sources/bison/bison/configure.ac,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -p -r1.78 -r1.79
--- configure.ac        26 Dec 2006 18:09:53 -0000      1.78
+++ configure.ac        29 Jan 2007 10:54:42 -0000      1.79
@@ -136,6 +136,9 @@ AC_SUBST([O0CFLAGS])
 O0CXXFLAGS=`echo $CXXFLAGS | sed 's/-O[[0-9]] *//'`
 AC_SUBST([O0CXXFLAGS])
 
+gt_JAVACOMP([1.3], [1.3])
+gt_JAVAEXEC
+
 AC_CONFIG_FILES([Makefile
                  build-aux/Makefile
                  po/Makefile.in
Index: build-aux/.cvsignore
===================================================================
RCS file: /sources/bison/bison/build-aux/.cvsignore,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- build-aux/.cvsignore        21 Oct 2005 09:13:01 -0000      1.1
+++ build-aux/.cvsignore        29 Jan 2007 10:54:42 -0000      1.2
@@ -6,6 +6,8 @@ config.rpath
 config.sub
 depcomp
 install-sh
+javacomp.sh.in
+javaexec.sh.in
 mdate-sh
 missing
 mkinstalldirs
Index: data/Makefile.am
===================================================================
RCS file: /sources/bison/bison/data/Makefile.am,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -p -r1.16 -r1.17
--- data/Makefile.am    19 Dec 2006 00:34:36 -0000      1.16
+++ data/Makefile.am    29 Jan 2007 10:54:42 -0000      1.17
@@ -17,7 +17,8 @@
 
 dist_pkgdata_DATA = README bison.m4 \
    c-skel.m4 c.m4 yacc.c glr.c push.c \
-   c++-skel.m4 c++.m4 location.cc lalr1.cc glr.cc
+   c++-skel.m4 c++.m4 location.cc lalr1.cc glr.cc \
+   java-skel.m4 java.m4 lalr1.java
 
 m4sugardir = $(pkgdatadir)/m4sugar
 dist_m4sugar_DATA = m4sugar/m4sugar.m4
Index: data/java-skel.m4
===================================================================
RCS file: data/java-skel.m4
diff -N data/java-skel.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ data/java-skel.m4   29 Jan 2007 10:54:42 -0000      1.1
@@ -0,0 +1,28 @@
+                                                            -*- Autoconf -*-
+
+# Java skeleton dispatching for Bison.
+# Copyright (C) 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301  USA
+
+b4_glr_if(             [b4_complain([%%glr-parser not supported for Java])])
+b4_nondeterministic_if([b4_complain([%%nondeterministic-parser not supported 
for Java])])
+b4_push_if(            [b4_complain([%%push-parser is not supported for 
Java])])
+
+m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[lalr1.java]])
+m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"])
+
+m4_include(b4_used_skeleton)
Index: data/java.m4
===================================================================
RCS file: data/java.m4
diff -N data/java.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ data/java.m4        29 Jan 2007 10:54:42 -0000      1.1
@@ -0,0 +1,268 @@
+                                                            -*- Autoconf -*-
+
+# Java language support for Bison
+
+# Copyright (C) 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301  USA
+
+
+# b4_comment(TEXT)
+# ----------------
+m4_define([b4_comment], [/* m4_bpatsubst([$1], [
+], [
+   ])  */])
+
+
+# b4_flag_value(BOOLEAN-FLAG)
+# ---------------------------
+m4_define([b4_flag_value], [b4_flag_if([$1], [true], [false])])
+
+
+# b4_public_if(TRUE, FALSE)
+# -------------------------
+b4_percent_define_default([public], 0)
+m4_define([b4_public_if],
+[b4_percent_define_flag_if([public], [$1], [$2])])
+
+# b4_single_class_if(TRUE, FALSE)
+# -------------------------------
+b4_percent_define_default([single_class], 0)
+m4_define([b4_single_class_if],
+[b4_percent_define_flag_if([single_class], [$1], [$2])])
+
+
+# b4_abstract_if(TRUE, FALSE)
+# ---------------------------
+m4_define([b4_abstract_if],
+[b4_pure_if([$2], [b4_single_class_if([$2], [$1])])])
+
+
+# b4_identification
+# -----------------
+m4_define([b4_identification],
+[/** Always <tt>true</tt>, identifies Bison output.  */
+  public static final boolean bison = true;
+
+  /** Version number for the Bison executable that generated this parser.  */
+  public static final String bisonVersion = "b4_version";
+
+  /** Name of the skeleton that generated this parser.  */
+  public static final String bisonSkeleton = b4_skeleton;
+])
+
+
+## ------------ ##
+## Data types.  ##
+## ------------ ##
+
+# b4_int_type(MIN, MAX)
+# ---------------------
+# Return the smallest int type able to handle numbers ranging from
+# MIN to MAX (included).
+m4_define([b4_int_type],
+[m4_if(b4_ints_in($@,   [-128],   [127]), [1], [byte],
+       b4_ints_in($@, [-32768], [32767]), [1], [short],
+                                                      [int])])
+
+# b4_int_type_for(NAME)
+# ---------------------
+# Return the smallest int type able to handle numbers ranging from
+# `NAME_min' to `NAME_max' (included).
+m4_define([b4_int_type_for],
+[b4_int_type($1_min, $1_max)])
+
+# b4_null
+# -------
+m4_define([b4_null], [null])
+
+
+## ------------------------- ##
+## Assigning token numbers.  ##
+## ------------------------- ##
+
+# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
+# ---------------------------------------
+# Output the definition of this token as an enum.
+m4_define([b4_token_enum],
+[  /** Token number, to be returned by the scanner.  */
+  public static final int $1 = $2;
+])
+
+
+# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
+# -----------------------------------------------------
+# Output the definition of the tokens (if there are) as enums.
+m4_define([b4_token_enums],
+[m4_if(address@hidden, [[]], [],
+[/* Tokens.  */
+m4_map([b4_token_enum], address@hidden)])
+])
+
+# b4-case(ID, CODE)
+# -----------------
+# We need to fool Java's stupid unreachable code detection.
+m4_define([b4_case], [  case $1:
+  if (yyn == $1)
+    $2;
+  break;
+    ])
+
+
+## ---------------- ##
+## Default values.  ##
+## ---------------- ##
+
+m4_define([b4_union_name], [b4_percent_define_get([[union_name]])])
+b4_percent_define_default([[union_name]], [[Object]])])
+
+m4_define_default([[b4_prefix]], [[YY]])])
+b4_percent_define_default([[parser_class_name]], [b4_prefix[]Parser])])
+m4_define([b4_parser_class_name], 
[b4_percent_define_get([[parser_class_name]])])
+
+b4_percent_define_default([[lex_throws]], [[java.io.IOException]])])
+m4_define([b4_lex_throws], [b4_percent_define_get([[lex_throws]])])
+
+b4_percent_define_default([[throws]], [b4_lex_throws])])
+m4_define([b4_throws], [b4_percent_define_get([[throws]])])
+
+b4_percent_define_default([[location_type]], [Location])])
+m4_define([b4_location_type], [b4_percent_define_get([[location_type]])])
+
+b4_percent_define_default([[position_type]], [Position])])
+m4_define([b4_position_type], [b4_percent_define_get([[position_type]])])
+
+
+## ----------------- ##
+## Semantic Values.  ##
+## ----------------- ##
+
+
+# b4_lhs_value([TYPE])
+# --------------------
+# Expansion of $<TYPE>$.
+m4_define([b4_lhs_value], [yyval])
+
+
+# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
+# --------------------------------------
+# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
+# symbols on RHS.
+#
+# In this simple implementation, %token and %type have class names
+# between the angle brackets.
+m4_define([b4_rhs_value],
+[(m4_ifval([$3], [($3)])[](yystack.valueAt ($1-($2))))])
+
+# b4_lhs_location()
+# -----------------
+# Expansion of @$.
+m4_define([b4_lhs_location],
+[(yyloc)])
+
+
+# b4_rhs_location(RULE-LENGTH, NUM)
+# ---------------------------------
+# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
+# on RHS.
+m4_define([b4_rhs_location],
+[yystack.locationAt ($1-($2))])
+
+
+# b4_lex_param
+# b4_parse_param
+# --------------
+# If defined, b4_lex_param arrives double quoted, but below we prefer
+# it to be single quoted.  Same for b4_parse_param.
+
+# TODO: should be in bison.m4
+m4_define_default([b4_lex_param], [[]]))
+m4_define([b4_lex_param], b4_lex_param))
+m4_define([b4_parse_param], b4_parse_param))
+
+# b4_lex_param_decl
+# -------------------
+# Extra formal arguments of the constructor.
+m4_define([b4_lex_param_decl],
+[m4_ifset([b4_lex_param],
+          [b4_remove_comma([$1],
+                          [m4_map([b4_lex_param_decl_1], [b4_lex_param])])],
+         [$1])])
+
+m4_define([b4_lex_param_decl_1], [, $1])
+m4_define([b4_remove_comma], [m4_ifval([$1], [$1, ], [])m4_cdr([m4_cdr($@)])])
+
+
+
+# b4_lex_param_call
+# -------------------
+# Extra initialisations of the constructor.
+m4_define([b4_lex_param_call],
+          [m4_ifset([b4_lex_param],
+                   [b4_remove_comma([$1],
+                                    [b4_lex_param_calls(b4_lex_param)])],
+                   [$1])])
+m4_define([b4_lex_param_calls],
+         [m4_map([b4_lex_param_call_1], address@hidden)])
+m4_define([b4_lex_param_call_1], [, $2])
+
+
+
+# b4_parse_param_decl
+# -------------------
+# Extra formal arguments of the constructor.
+m4_define([b4_parse_param_decl],
+[m4_ifset([b4_parse_param],
+          [b4_remove_comma([$1],
+                          [m4_map([b4_parse_param_decl_1],
+                                  [b4_parse_param])])],
+         [$1])])
+
+m4_define([b4_parse_param_decl_1], [, $1])
+
+
+
+# b4_parse_param_cons
+# -------------------
+# Extra initialisations of the constructor.
+m4_define([b4_parse_param_cons],
+          [m4_ifset([b4_parse_param],
+                   [b4_constructor_calls(b4_parse_param)])])
+m4_define([b4_constructor_calls],
+         [m4_map([b4_constructor_call], address@hidden)])
+m4_define([b4_constructor_call],
+         [this.$2 = $2;
+         ])
+
+# b4_parse_param_vars
+# -------------------
+# Extra instance variables.
+m4_define([b4_parse_param_vars],
+          [m4_ifset([b4_parse_param],
+                   [
+    /* User arguments.  */
+b4_var_decls(b4_parse_param)])])
+m4_define([b4_var_decls],
+         [m4_map_sep([b4_var_decl], [
+], address@hidden)])
+m4_define([b4_var_decl],
+         [    protected final $1;])
+
+# b4_maybe_throws(THROWS)
+# -----------------------
+# Expand to either an empty string or "throws THROWS".
+m4_define([b4_maybe_throws],
+         [m4_ifval([$1], [throws $1])])
Index: data/lalr1.java
===================================================================
RCS file: data/lalr1.java
diff -N data/lalr1.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ data/lalr1.java     29 Jan 2007 10:54:42 -0000      1.1
@@ -0,0 +1,880 @@
+# Java skeleton for Bison -*- autoconf -*-
+
+# Copyright (C) 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301  USA
+
+m4_include(b4_pkgdatadir/[java.m4])
+
+b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java], 
[b4_skeleton])])
+m4_ifval(m4_defn([b4_symbol_destructors]),
+        [b4_fatal([%s: %%destructor does not make sense in Java], 
[b4_skeleton])],
+        [])
+
+m4_divert_push(0)dnl
address@hidden(b4_parser_file_name@)
+b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
+  [2007])
+
+b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);
+])[/* First part of user declarations.  */
+]b4_pre_prologue
+b4_percent_code_get([[imports]])
+[/**
+ * A Bison parser, automatically generated from <tt>@ofile@</tt>.
+ *
+ * @@author LALR (1) parser skeleton written by Paolo Bonzini.
+ */
+]b4_public_if([public ])b4_abstract_if([abstract ])[class 
]b4_parser_class_name[
+{
+  ]b4_identification[
+
+  /** True if verbose error messages are enabled.  */
+  public boolean errorVerbose = ]b4_flag_value([error_verbose]);
+
+b4_locations_if([[
+  /**
+   * A class defining a pair of positions.  Positions, defined by the
+   * <code>]b4_position_type[</code> class, denote a point in the input.
+   * Locations represent a part of the input through the beginning
+   * and ending positions.  */
+  public class ]b4_location_type[ {
+    /** The first, inclusive, position in the range.  */
+    public ]b4_position_type[ begin;
+
+    /** The first position beyond the range.  */
+    public ]b4_position_type[ end;
+
+    /**
+     * Create a ]b4_location_type[ denoting an empty range located at
+     * a given point.
+     * @@param loc The position at which the range is anchored.  */
+    public ]b4_location_type[ (]b4_position_type[ loc) {
+      this.begin = this.end = loc;
+    }
+
+    /**
+     * Create a <code>]b4_location_type[</code> from the endpoints of the 
range.
+     * @@param begin The first position included in the range.
+     * @@param begin The first position beyond the range.  */
+    public ]b4_location_type[ (]b4_position_type[ begin, ]b4_position_type[ 
end) {
+      this.begin = begin;
+      this.end = end;
+    }
+
+    /**
+     * Print a representation of the location.  For this to be correct,
+     * <code>]b4_position_type[</code> should override the <code>equals</code>
+     * method.  */
+    public String toString () {
+      if (begin.equals (end))
+        return begin.toString ();
+      else
+        return begin.toString () + "-" + end.toString ();
+    }
+  }
+
+]])
+
+[  /** Token returned by the scanner to signal the end of its input.  */
+  public static final int EOF = 0;]
+
+b4_token_enums(b4_tokens)
+
+  b4_locations_if([[
+  private ]b4_location_type[ yylloc (Stack rhs, int n)
+  {
+    if (n > 0)
+      return new ]b4_location_type[ (rhs.locationAt (1).begin, rhs.locationAt 
(n).end);
+    else
+      return new ]b4_location_type[ (rhs.locationAt (0).end);
+  }]])
+
+  b4_pure_if([[/**
+   * Communication interface between the scanner and the Bison-generated
+   * parser <tt>]b4_parser_class_name[</tt>.
+   */
+  public interface Lexer {
+    ]b4_locations_if([[/**
+     * Method to retrieve the beginning position of the last scanned token.
+     * @@return the position at which the last scanned token starts.  */
+    ]b4_position_type[ getStartPos ();
+
+    /**
+     * Method to retrieve the ending position of the last scanned token.
+     * @@return the first position beyond the last scanned token.  */
+    ]b4_position_type[ getEndPos ();]])[
+
+    /**
+     * Method to retrieve the semantic value of the last scanned token.
+     * @@return the semantic value of the last scanned token.  */
+    ]b4_union_name[ getLVal ();]], [[
+
+    /**
+     * A place where the scanner can store the beginning position of the
+     * last scanned token.  */
+    ]b4_locations_if([b4_position_type[ yystartpos;]])[
+
+    /**
+     * A place where the scanner can store the ending position of the last
+     * scanned token, i.e. the first position beyond the last scanned token.  
*/
+    ]b4_locations_if([b4_position_type[ yyendpos;]])[
+
+    /**
+     * A place where the scanner can store the semantic value of the
+     * last scanned token.  */
+    protected ]b4_union_name[ yylval;]])
+
+    b4_single_class_if([], [[/**
+     * Entry point for the scanner.  Returns the token identifier corresponding
+     * to the next token and ]b4_pure_if([prepares to return], [stores])[
+     * the semantic value]b4_locations_if([ and beginning/ending positions])[
+     * of the token. 
+     * @@return the token identifier corresponding to the next token. */
+    abstract int yylex (]b4_lex_param_decl) b4_maybe_throws([b4_lex_throws])[;
+
+    /**
+     * Entry point for error reporting.  Emits an error
+     * ]b4_locations_if([ referring to the given location])[in a user-defined
+     * way.
+     *
+     * ]b4_locations_if([loc], [[The location of the element to which the
+     *                error message is related]])[
+     * @@param s The string for the error message.  */
+     abstract void yyerror (]b4_locations_if([b4_location_type[ loc, 
]])[String s);]])
+  b4_pure_if([}
+
+  /** The object doing lexical analysis for us.  */
+  private Lexer yylex;])
+  b4_parse_param_vars[
+
+  /**
+   * Instantiates the Bison-generated parser.  ]b4_pure_if([
+   * @@param yylex The scanner that will supply tokens to the parser.])[
+   */
+  public ]b4_parser_class_name[ (]b4_parse_param_decl([b4_pure_if([Lexer 
yylex])])[) {
+    ]b4_pure_if(this.yylex = yylex;)
+    b4_parse_param_cons[
+  }
+
+  private java.io.PrintStream debugStream = System.err;
+
+  /**
+   * Return the <tt>PrintStream</tt> on which the debugging output is
+   * printed.
+   */
+  public final java.io.PrintStream getDebugStream () { return debugStream; }
+
+  /**
+   * Set the <tt>PrintStream</tt> on which the debug output is printed.
+   * @@param s The stream that is used for debugging output.
+   */
+  public final void setDebugStream(java.io.PrintStream s) { debugStream = s; }
+
+  private int yydebug = 0;
+
+  /**
+   * Answer the verbosity of the debugging output; 0 means that all kinds of
+   * output from the parser are suppressed.
+   */
+  public final int getDebugLevel() { return yydebug; }
+
+  /**
+   * Set the verbosity of the debugging output; 0 means that all kinds of
+   * output from the parser are suppressed.
+   * @@param level The verbosity level for debugging output.
+   */
+  public final void setDebugLevel(int level) { yydebug = level; }
+
+  ]b4_pure_if([[
+  private final int yylex (]b4_lex_param_decl) 
b4_maybe_throws([b4_lex_throws]) [{
+    return yylex.yylex (]b4_lex_param_call[);
+  }
+  protected final void yyerror (]b4_locations_if([b4_location_type[ loc, 
]])[String s) {
+    yylex.yyerror (]b4_locations_if([loc, ])[s);
+  }]])
+  b4_locations_if([
+  protected final void yyerror (String s) {
+    yyerror ((Location)null, s);
+  }
+  protected final void yyerror (]b4_position_type[ loc, String s) {
+    yyerror (new ]b4_location_type[ (loc), s);
+  }])
+
+  [protected final void yycdebug (String s) {
+    if (yydebug > 0)
+      debugStream.println (s);
+  }
+
+  private final class Stack {
+    private int[] stateStack = new int[16];
+    ]b4_locations_if([[private ]b4_location_type[[] locStack = new 
]b4_location_type[[16];]])[
+    private ]b4_union_name[[] valueStack = new ]b4_union_name[[16];
+
+    private int size = 16;
+    private int height = -1;
+    
+    public final void push (int state, ]b4_union_name[ value]dnl
+                           b4_locations_if([, ]b4_location_type[ loc])[) {
+      height++;
+      if (size == height) 
+        {
+         int[] newStateStack = new int[size * 2];
+         System.arraycopy (stateStack, 0, newStateStack, 0, height);
+         stateStack = newStateStack;
+         ]b4_locations_if([[
+         ]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2];
+         System.arraycopy (locStack, 0, newLocStack, 0, height);
+         locStack = newLocStack;]])
+         
+         b4_union_name[[] newValueStack = new ]b4_union_name[[size * 2];
+         System.arraycopy (valueStack, 0, newValueStack, 0, height);
+         valueStack = newValueStack;
+
+         size *= 2;
+       }
+
+      stateStack[height] = state;
+      ]b4_locations_if([[locStack[height] = loc;]])[
+      valueStack[height] = value;
+    }
+
+    public final void pop () {
+      height--;
+    }
+
+    public final void pop (int num) {
+      // Avoid memory leaks... garbage collection is a white lie!
+      if (num > 0) {
+       java.util.Arrays.fill (valueStack, height - num + 1, height, null);
+        ]b4_locations_if([[java.util.Arrays.fill (locStack, height - num + 1, 
height, null);]])[
+      }
+      height -= num;
+    }
+
+    public final int stateAt (int i) {
+      return stateStack[height - i];
+    }
+
+    ]b4_locations_if([[public final ]b4_location_type[ locationAt (int i) {
+      return locStack[height - i];
+    }
+
+    ]])[public final ]b4_union_name[ valueAt (int i) {
+      return valueStack[height - i];
+    }
+
+    // Print the state stack on the debug stream.
+    private void print (java.io.PrintStream out)
+    {
+      out.print ("Stack now");
+      
+      for (int i = 0; i < height; i++)
+        {
+         out.print (' ');
+         out.print (stateStack[i]);
+        }
+      out.println ();
+    }
+  }
+
+  /**
+   * Returned by a Bison action in order to stop the parsing process and
+   * return success (<tt>true</tt>).  */
+  public static final int YYACCEPT = 0;
+
+  /**
+   * Returned by a Bison action in order to stop the parsing process and
+   * return failure (<tt>false</tt>).  */
+  public static final int YYABORT = 1;
+
+  /**
+   * Returned by a Bison action in order to start error recovery without
+   * printing an error message.  */
+  public static final int YYERROR = 2;
+
+  /**
+   * Returned by a Bison action in order to print an error message and start
+   * error recovery.  */
+  public static final int YYFAIL = 3;
+
+  private static final int YYNEWSTATE = 4;
+  private static final int YYDEFAULT = 5;
+  private static final int YYREDUCE = 6;
+  private static final int YYERRLAB1 = 7;
+  private static final int YYRETURN = 8;
+
+  private int yyerrstatus_ = 0;
+
+  /**
+   * Return whether error recovery is being done.  In this state, the parser
+   * reads token until it reaches a known state, and then restarts normal
+   * operation.  */
+  public final boolean yyrecovering ()
+  {
+    return yyerrstatus_ == 0;
+  }
+
+  private int yyaction (int yyn, Stack yystack, int yylen)
+  {
+    ]b4_union_name[ yyval;
+    ]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
+
+    /* If YYLEN is nonzero, implement the default value of the action:
+       `$$ = $1'.  Otherwise, use the top of the stack.
+    
+       Otherwise, the following line sets YYVAL to garbage.
+       This behavior is undocumented and Bison
+       users should not rely upon it.  */
+    if (yylen > 0)
+      yyval = yystack.valueAt (yylen - 1);
+    else
+      yyval = yystack.valueAt (0);
+    
+    yy_reduce_print (yyn, yystack);
+
+    switch (yyn)
+      {
+       ]b4_user_actions[
+       default: break;
+      }
+
+    yy_symbol_print ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[);
+
+    yystack.pop (yylen);
+    yylen = 0;
+
+    /* Shift the result of the reduction.  */
+    yyn = yyr1_[yyn];
+    int yystate = yypgoto_[yyn - yyntokens_] + yystack.stateAt (0);
+    if (0 <= yystate && yystate <= yylast_
+       && yycheck_[yystate] == yystack.stateAt (0))
+      yystate = yytable_[yystate];
+    else
+      yystate = yydefgoto_[yyn - yyntokens_];
+
+    yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
+    return YYNEWSTATE;
+  }
+
+  /* Return YYSTR after stripping away unnecessary quotes and
+     backslashes, so that it's suitable for yyerror.  The heuristic is
+     that double-quoting is unnecessary unless the string contains an
+     apostrophe, a comma, or backslash (other than backslash-backslash).
+     YYSTR is taken from yytname.  */
+  private final String yytnamerr_ (String yystr)
+  {
+    if (yystr.charAt (0) == '"')
+      {
+        StringBuffer yyr = new StringBuffer ();
+        strip_quotes: for (int i = 1; i < yystr.length (); i++)
+          switch (yystr.charAt (i))
+            {
+            case '\'':
+            case ',':
+              break strip_quotes;
+
+            case '\\':
+             if (yystr.charAt(++i) != '\\')
+                break strip_quotes;
+              /* Fall through.  */
+            default:
+              yyr.append (yystr.charAt (i));
+              break;
+
+            case '"':
+              return yyr.toString ();
+            }
+      }
+    else if (yystr.equals ("$end"))
+      return "end of input";
+
+    return yystr;
+  }
+
+  /*--------------------------------.
+  | Print this symbol on YYOUTPUT.  |
+  `--------------------------------*/
+
+  private void yy_symbol_print (String s, int yytype,
+                                ]b4_union_name[ yyvaluep]dnl
+                                b4_locations_if([, Object yylocationp])[)
+  {
+    if (yydebug > 0)
+    yycdebug (s + (yytype < yyntokens_ ? " token " : " nterm ")
+             + yytname_[yytype] + " ("]b4_locations_if([
+             + yylocationp + ": "])[
+             + (yyvaluep == null ? "(null)" : yyvaluep) + ")");
+  }
+
+  /**
+   * Parse input from the scanner that was specified at object construction
+   * time.  Return whether the end of the input was reached successfully.
+   *
+   * @@return <tt>true</tt> if the parsing succeeds.  Note that this does not
+   *          imply that there were no syntax errors.
+   */
+  public boolean parse () ]b4_maybe_throws([b4_throws])[
+  {
+    /// Lookahead and lookahead in internal form.
+    int yychar = yyempty_;
+    int yytoken = 0;
+
+    /* State.  */
+    int yyn = 0;
+    int yylen = 0;
+    int yystate = 0;
+
+    Stack yystack = new Stack ();
+
+    /* Error handling.  */
+    int yynerrs_ = 0;
+    ]b4_locations_if([/// The location where the error started.
+    ]b4_location_type[ yyerrloc = null;
+
+    /// ]b4_location_type[ of the lookahead.
+    ]b4_location_type[ yylloc = new ]b4_location_type[ (null, null);
+
+    /// @@$.
+    ]b4_location_type[ yyloc;])
+
+    /// Semantic value of the lookahead.
+    b4_union_name[ yylval = null;
+
+    int yyresult;
+
+    yycdebug ("Starting parse\n");
+    yyerrstatus_ = 0;
+
+]m4_ifdef([b4_initial_action], [
+m4_pushdef([b4_at_dollar],     [yylloc])dnl
+m4_pushdef([b4_dollar_dollar], [yylval])dnl
+    /* User initialization code.  */
+    b4_user_initial_action
+m4_popdef([b4_dollar_dollar])dnl
+m4_popdef([b4_at_dollar])])dnl
+
+  [  /* Initialize the stack.  */
+    yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
+
+    int label = YYNEWSTATE;
+    for (;;)
+      switch (label)
+      {
+        /* New state.  Unlike in the C/C++ skeletons, the state is already
+          pushed when we come here.  */
+      case YYNEWSTATE:
+        yycdebug ("Entering state " + yystate + "\n");
+        if (yydebug > 0)
+          yystack.print (debugStream);
+    
+        /* Accept?  */
+        if (yystate == yyfinal_)
+          return true;
+    
+        /* Take a decision.  First try without lookahead.  */
+        yyn = yypact_[yystate];
+        if (yyn == yypact_ninf_)
+          {
+            label = YYDEFAULT;
+           break;
+          }
+    
+        /* Read a lookahead token.  */
+        if (yychar == yyempty_)
+          {
+           yycdebug ("Reading a token: ");
+           yychar = yylex (]b4_lex_param_call[);]
+            b4_locations_if([
+           b4_pure_if([yylloc = new ]b4_location_type[(yylex.getStartPos (),
+                                                       yylex.getEndPos ());],
+                      [yylloc = new ]b4_location_type[(this.yystartpos,
+                                                       this.yyendpos);]);])
+            b4_pure_if([yylval = yylex.getLVal ()], [yylval = this.yylval]);[
+          }
+    
+        /* Convert token to internal form.  */
+        if (yychar <= EOF)
+          {
+           yychar = yytoken = EOF;
+           yycdebug ("Now at end of input.\n");
+          }
+        else
+          {
+           yytoken = yytranslate_ (yychar);
+           yy_symbol_print ("Next token is", yytoken,
+                            yylval]b4_locations_if([, yylloc])[);
+          }
+    
+        /* If the proper action on seeing token YYTOKEN is to reduce or to
+           detect an error, take that action.  */
+        yyn += yytoken;
+        if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken)
+          label = YYDEFAULT;
+    
+        /* <= 0 means reduce or error.  */
+        else if ((yyn = yytable_[yyn]) <= 0)
+          {
+           if (yyn == 0 || yyn == yytable_ninf_)
+             label = YYFAIL;
+           else
+             {
+               yyn = -yyn;
+               label = YYREDUCE;
+             }
+          }
+    
+        else
+          {
+            /* Shift the lookahead token.  */
+           yy_symbol_print ("Shifting", yytoken,
+                            yylval]b4_locations_if([, yylloc])[);
+    
+            /* Discard the token being shifted.  */
+            yychar = yyempty_;
+    
+            /* Count tokens shifted since error; after three, turn off error
+               status.  */
+            if (yyerrstatus_ > 0)
+              --yyerrstatus_;
+    
+            yystate = yyn;
+            yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
+            label = YYNEWSTATE;
+          }
+        break;
+    
+      /*-----------------------------------------------------------.
+      | yydefault -- do the default action for the current state.  |
+      `-----------------------------------------------------------*/
+      case YYDEFAULT:
+        yyn = yydefact_[yystate];
+        if (yyn == 0)
+          label = YYFAIL;
+        else
+          label = YYREDUCE;
+        break;
+    
+      /*-----------------------------.
+      | yyreduce -- Do a reduction.  |
+      `-----------------------------*/
+      case YYREDUCE:
+        yylen = yyr2_[yyn];
+        label = yyaction (yyn, yystack, yylen);
+       yystate = yystack.stateAt (0);
+        break;
+    
+      /*------------------------------------.
+      | yyerrlab -- here on detecting error |
+      `------------------------------------*/
+      case YYFAIL:
+        /* If not already recovering from an error, report this error.  */
+        if (yyerrstatus_ == 0)
+          {
+           ++yynerrs_;
+           yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, 
yytoken));
+          }
+    
+        ]b4_locations_if([yyerrloc = yylloc;])[
+        if (yyerrstatus_ == 3)
+          {
+           /* If just tried and failed to reuse lookahead token after an
+            error, discard it.  */
+    
+           if (yychar <= EOF)
+             {
+             /* Return failure if at end of input.  */
+             if (yychar == EOF)
+               return false;
+             }
+           else
+             yychar = yyempty_;
+          }
+    
+        /* Else will try to reuse lookahead token after shifting the error
+           token.  */
+        label = YYERRLAB1;
+        break;
+    
+      /*---------------------------------------------------.
+      | errorlab -- error raised explicitly by YYERROR.  |
+      `---------------------------------------------------*/
+      case YYERROR:
+    
+        ]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[
+        /* Do not reclaim the symbols of the rule which action triggered
+           this YYERROR.  */
+        yystack.pop (yylen);
+        yylen = 0;
+        yystate = yystack.stateAt (0);
+        label = YYERRLAB1;
+        break;
+    
+      /*-------------------------------------------------------------.
+      | yyerrlab1 -- common code for both syntax error and YYERROR.  |
+      `-------------------------------------------------------------*/
+      case YYERRLAB1:
+        yyerrstatus_ = 3;      /* Each real token shifted decrements this.  */
+    
+        for (;;)
+          {
+           yyn = yypact_[yystate];
+           if (yyn != yypact_ninf_)
+             {
+               yyn += yyterror_;
+               if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
+                 {
+                   yyn = yytable_[yyn];
+                   if (0 < yyn)
+                     break;
+                 }
+             }
+    
+           /* Pop the current state because it cannot handle the error token.  
*/
+           if (yystack.height == 1)
+             return false;
+    
+           ]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
+           yystack.pop ();
+           yystate = yystack.stateAt (0);
+           if (yydebug > 0)
+             yystack.print (debugStream);
+          }
+    
+       ]b4_locations_if([
+       /* Muck with the stack to setup for yylloc.  */
+       yystack.push (0, null, yylloc);
+       yystack.push (0, null, yyerrloc);
+        yyloc = yylloc (yystack, 2);
+       yystack.pop (2);])[
+
+        /* Shift the error token.  */
+        yy_symbol_print ("Shifting", yystos_[yyn],
+                        yylval]b4_locations_if([, yyloc])[);
+    
+        yystate = yyn;
+       yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
+        label = YYNEWSTATE;
+        break;
+    
+        /* Accept.  */
+      case YYACCEPT:
+        return true;
+    
+        /* Abort.  */
+      case YYABORT:
+        return false;
+      }
+  }
+
+  // Generate an error message.
+  private String yysyntax_error (int yystate, int tok)
+  {
+    if (errorVerbose)
+      {
+        int yyn = yypact_[yystate];
+        if (yypact_ninf_ < yyn && yyn <= yylast_)
+          {
+           StringBuffer res;
+
+           /* Start YYX at -YYN if negative to avoid negative indexes in
+              YYCHECK.  */
+           int yyxbegin = yyn < 0 ? -yyn : 0;
+
+           /* Stay within bounds of both yycheck and yytname.  */
+           int yychecklim = yylast_ - yyn + 1;
+           int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
+           int count = 0;
+           for (int x = yyxbegin; x < yyxend; ++x)
+             if (yycheck_[x + yyn] == x && x != yyterror_)
+               ++count;
+
+           // FIXME: This method of building the message is not compatible
+           // with internationalization.
+           res = new StringBuffer ("syntax error, unexpected ");
+           res.append (yytnamerr_ (yytname_[tok]));
+           if (count < 5)
+             {
+               count = 0;
+               for (int x = yyxbegin; x < yyxend; ++x)
+                 if (yycheck_[x + yyn] == x && x != yyterror_)
+                   {
+                     res.append (count++ == 0 ? ", expecting " : " or ");
+                     res.append (yytnamerr_ (yytname_[x]));
+                   }
+             }
+           return res.toString ();
+          }
+      }
+
+    return "syntax error";
+  }
+
+
+  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+     STATE-NUM.  */
+  private static final ]b4_int_type_for([b4_pact])[ yypact_ninf_ = 
]b4_pact_ninf[;
+  private static final ]b4_int_type_for([b4_pact])[ yypact_[] =
+  {
+    ]b4_pact[
+  };
+
+  /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
+     doesn't specify something else to do.  Zero means the default is an
+     error.  */
+  private static final ]b4_int_type_for([b4_defact])[ yydefact_[] =
+  {
+    ]b4_defact[
+  };
+
+  /* YYPGOTO[NTERM-NUM].  */
+  private static final ]b4_int_type_for([b4_pgoto])[ yypgoto_[] =
+  {
+    ]b4_pgoto[
+  };
+
+  /* YYDEFGOTO[NTERM-NUM].  */
+  private static final ]b4_int_type_for([b4_defgoto])[
+  yydefgoto_[] =
+  {
+    ]b4_defgoto[
+  };
+
+  /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+     positive, shift that token.  If negative, reduce the rule which
+     number is the opposite.  If zero, do what YYDEFACT says.  */
+  private static final ]b4_int_type_for([b4_table])[ yytable_ninf_ = 
]b4_table_ninf[;
+  private static final ]b4_int_type_for([b4_table])[
+  yytable_[] =
+  {
+    ]b4_table[
+  };
+
+  /* YYCHECK.  */
+  private static final ]b4_int_type_for([b4_check])[
+  yycheck_[] =
+  {
+    ]b4_check[
+  };
+
+  /* STOS_[STATE-NUM] -- The (internal number of the) accessing
+     symbol of state STATE-NUM.  */
+  private static final ]b4_int_type_for([b4_stos])[
+  yystos_[] =
+  {
+    ]b4_stos[
+  };
+
+  /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding
+     to YYLEX-NUM.  */
+  private static final ]b4_int_type_for([b4_toknum])[
+  yytoken_number_[] =
+  {
+    ]b4_toknum[
+  };
+
+  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+  private static final ]b4_int_type_for([b4_r1])[
+  yyr1_[] =
+  {
+    ]b4_r1[
+  };
+
+  /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+  private static final ]b4_int_type_for([b4_r2])[
+  yyr2_[] =
+  {
+    ]b4_r2[
+  };
+
+  /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+     First, the terminals, then, starting at \a yyntokens_, nonterminals.  */
+  private static final String yytname_[] =
+  {
+    ]b4_tname[
+  };
+
+  /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+  private static final ]b4_int_type_for([b4_rhs])[ yyrhs_[] =
+  {
+    ]b4_rhs[
+  };
+
+  /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+     YYRHS.  */
+  private static final ]b4_int_type_for([b4_prhs])[ yyprhs_[] =
+  {
+    ]b4_prhs[
+  };
+
+  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
+  private static final ]b4_int_type_for([b4_rline])[ yyrline_[] =
+  {
+    ]b4_rline[
+  };
+
+  // Report on the debug stream that the rule yyrule is going to be reduced.
+  private void yy_reduce_print (int yyrule, Stack yystack)
+  {
+    if (yydebug == 0)
+      return;
+
+    int yylno = yyrline_[yyrule];
+    int yynrhs = yyr2_[yyrule];
+    /* Print the symbols being reduced, and their result.  */
+    yycdebug ("Reducing stack by rule " + (yyrule - 1)
+             + " (line " + yylno + "), ");
+
+    /* The symbols being reduced.  */
+    for (int yyi = 0; yyi < yynrhs; yyi++)
+      yy_symbol_print ("   $" + (yyi + 1) + " =",
+                      yyrhs_[yyprhs_[yyrule] + yyi],
+                      ]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([, 
+                      b4_rhs_location(yynrhs, yyi + 1)])[);
+  }
+
+  /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+  private static final ]b4_int_type_for([b4_translate])[ yytranslate_table_[] =
+  {
+    ]b4_translate[
+  };
+
+  private static final ]b4_int_type_for([b4_translate])[ yytranslate_ (int t)
+  {
+    if (t >= 0 && t <= yyuser_token_number_max_)
+      return yytranslate_table_[t];
+    else
+      return yyundef_token_;
+  }
+
+  private static final int yylast_ = ]b4_last[;
+  private static final int yynnts_ = ]b4_nterms_number[;
+  private static final int yyempty_ = -2;
+  private static final int yyfinal_ = ]b4_final_state_number[;
+  private static final int yyterror_ = 1;
+  private static final int yyerrcode_ = 256;
+  private static final int yyntokens_ = ]b4_tokens_number[;
+
+  private static final int yyuser_token_number_max_ = 
]b4_user_token_number_max[;
+  private static final int yyundef_token_ = ]b4_undef_token_number[;
+
+]/* User implementation code.  */
+b4_percent_code_get[]dnl
+
+}
+
+b4_epilogue
+m4_divert_pop(0)dnl
Index: doc/bison.texinfo
===================================================================
RCS file: /sources/bison/bison/doc/bison.texinfo,v
retrieving revision 1.224
retrieving revision 1.225
diff -u -p -r1.224 -r1.225
--- doc/bison.texinfo   27 Jan 2007 23:34:16 -0000      1.224
+++ doc/bison.texinfo   29 Jan 2007 10:54:42 -0000      1.225
@@ -104,7 +104,7 @@ Reference sections:
                         messy for Bison to handle straightforwardly.
 * Debugging::         Understanding or debugging Bison parsers.
 * Invocation::        How to run Bison (to produce the parser source file).
-* C++ Language Interface::  Creating C++ parser objects.
+* Other Languages::   Creating C++ and Java parsers.
 * FAQ::               Frequently Asked Questions
 * Table of Symbols::  All the keywords of the Bison language are explained.
 * Glossary::          Basic concepts are explained.
@@ -285,10 +285,10 @@ Invoking Bison
 * Option Cross Key::  Alphabetical list of long options.
 * Yacc Library::      Yacc-compatible @code{yylex} and @code{main}.
 
-C++ Language Interface
+Parsers Written In Other Languages
 
 * C++ Parsers::                 The interface to generate C++ parser classes
-* A Complete C++ Example::      Demonstrating their use
+* Java Parsers::                The interface to generate Java parser classes
 
 C++ Parsers
 
@@ -297,6 +297,7 @@ C++ Parsers
 * C++ Location Values::         The position and location classes
 * C++ Parser Interface::        Instantiating and running the parser
 * C++ Scanner Interface::       Exchanges between yylex and parse
+* A Complete C++ Example::      Demonstrating their use
 
 A Complete C++ Example
 
@@ -306,6 +307,15 @@ A Complete C++ Example
 * Calc++ Scanner::              A pure C++ Flex scanner
 * Calc++ Top Level::            Conducting the band
 
+Java Parsers
+
+* Java Bison Interface::         Asking for Java parser generation
+* Java Semantic Values::         %type and %token vs. Java
+* Java Location Values::         The position and location classes
+* Java Parser Interface::        Instantiating and running the parser
+* Java Scanner Interface::       Java scanners, and pure parsers
+* Java Differences::             Differences between C/C++ and Java Grammars
+
 Frequently Asked Questions
 
 * Memory Exhausted::           Breaking the Stack Limits
@@ -2694,7 +2704,7 @@ As an alternative, Bison provides a %cod
 field, which identifies the purpose of the code and thus the location(s) where
 Bison should generate it.
 For C/C++, the qualifier can be omitted for the default location, or it can be
address@hidden, @code{provides}, or @code{top}.
+one of @code{requires}, @code{provides}, @code{top}.
 @xref{Decl Summary,,%code}.
 
 Look again at the example of the previous section:
@@ -4572,18 +4582,19 @@ directives:
 @deffn {Directive} %code @address@hidden@}
 @findex %code
 This is the unqualified form of the @code{%code} directive.
-It inserts @var{code} verbatim at the default location in the output.
-That default location is determined by the selected target language and/or
-parser skeleton.
+It inserts @var{code} verbatim at a language-dependent default location in the
address@hidden default location is actually skeleton-dependent;
+  writers of non-standard skeletons however should choose the default location
+  consistently with the behavior of the standard Bison skeletons.}.
 
 @cindex Prologue
-For the current C/C++ skeletons, the default location is the parser source code
+For C/C++, the default location is the parser source code
 file after the usual contents of the parser header file.
 Thus, @code{%code} replaces the traditional Yacc prologue,
 @address@hidden@address@hidden, for most purposes.
 For a detailed discussion, see @ref{Prologue Alternatives}.
 
address@hidden For Java, the default location is inside the parser class.
+For Java, the default location is inside the parser class.
 
 (Like all the Yacc prologue alternatives, this directive is experimental.
 More user feedback will help to determine whether it should become a permanent
@@ -4651,7 +4662,7 @@ For example:
 
 @item Location(s): Near the top of the parser source code file.
 @end itemize
address@hidden
+
 @item imports
 @findex %code imports
 
@@ -4663,7 +4674,6 @@ For example:
 @item Location(s): The parser Java file after any Java package directive and
 before any class definitions.
 @end itemize
address@hidden ignore
 @end itemize
 
 (Like all the Yacc prologue alternatives, this directive is experimental.
@@ -7578,12 +7588,12 @@ int yyparse (void);
 
 @c ================================================= C++ Bison
 
address@hidden C++ Language Interface
address@hidden C++ Language Interface
address@hidden Other Languages
address@hidden Parsers Written In Other Languages
 
 @menu
 * C++ Parsers::                 The interface to generate C++ parser classes
-* A Complete C++ Example::      Demonstrating their use
+* Java Parsers::                The interface to generate Java parser classes
 @end menu
 
 @node C++ Parsers
@@ -7595,6 +7605,7 @@ int yyparse (void);
 * C++ Location Values::         The position and location classes
 * C++ Parser Interface::        Instantiating and running the parser
 * C++ Scanner Interface::       Exchanges between yylex and parse
+* A Complete C++ Example::      Demonstrating their use
 @end menu
 
 @node C++ Bison Interface
@@ -7803,7 +7814,7 @@ value and location being @var{yylval} an
 
 
 @node A Complete C++ Example
address@hidden A Complete C++ Example
address@hidden A Complete C++ Example
 
 This section demonstrates the use of a C++ parser with a simple but
 complete example.  This example should be available on your system,
@@ -7823,7 +7834,7 @@ actually easier to interface with.
 @end menu
 
 @node Calc++ --- C++ Calculator
address@hidden Calc++ --- C++ Calculator
address@hidden Calc++ --- C++ Calculator
 
 Of course the grammar is dedicated to arithmetics, a single
 expression, possibly preceded by variable assignments.  An
@@ -7838,7 +7849,7 @@ seven * seven
 @end example
 
 @node Calc++ Parsing Driver
address@hidden Calc++ Parsing Driver
address@hidden Calc++ Parsing Driver
 @c - An env
 @c - A place to store error messages
 @c - A place for the result
@@ -7987,7 +7998,7 @@ calcxx_driver::error (const std::string&
 @end example
 
 @node Calc++ Parser
address@hidden Calc++ Parser
address@hidden Calc++ Parser
 
 The parser definition file @file{calc++-parser.yy} starts by asking for
 the C++ LALR(1) skeleton, the creation of the parser header file, and
@@ -8157,7 +8168,7 @@ yy::calcxx_parser::error (const yy::calc
 @end example
 
 @node Calc++ Scanner
address@hidden Calc++ Scanner
address@hidden Calc++ Scanner
 
 The Flex scanner first includes the driver declaration, then the
 parser's to get the set of defined tokens.
@@ -8283,7 +8294,7 @@ calcxx_driver::scan_end ()
 @end example
 
 @node Calc++ Top Level
address@hidden Calc++ Top Level
address@hidden Calc++ Top Level
 
 The top level file, @file{calc++.cc}, poses no problem.
 
@@ -8306,6 +8317,321 @@ main (int argc, char *argv[])
 @}
 @end example
 
address@hidden Java Parsers
address@hidden Java Parsers
+
address@hidden
+* Java Bison Interface::         Asking for Java parser generation
+* Java Semantic Values::         %type and %token vs. Java
+* Java Location Values::         The position and location classes
+* Java Parser Interface::        Instantiating and running the parser
+* Java Scanner Interface::       Java scanners, and pure parsers
+* Java Differences::             Differences between C/C++ and Java Grammars
address@hidden menu
+
address@hidden Java Bison Interface
address@hidden Java Bison Interface
address@hidden - %language "Java"
address@hidden - initial action
+
+The Java parser skeletons are selected using a language directive,
address@hidden "Java"}, or the synonymous command-line option
address@hidden
+
+When run, @command{bison} will create several entities whose name
+starts with @samp{YY}.  Use the @samp{%name-prefix} directive to
+change the prefix, see @ref{Decl Summary}; classes can be placed
+in an arbitrary Java package using a @samp{%define package} section.
+
+The parser class defines an inner class, @code{Location}, that is used
+for location tracking.  If the parser is pure, it also defines an
+inner interface, @code{Lexer}; address@hidden Scanner Interface} for the
+meaning of pure parsers when the Java language is chosen.  Other than
+these inner class/interface, and the members described address@hidden
+Parser Interface}, all the other members and fields are preceded
+with a @code{yy} prefix to avoid clashes with user code.
+
+No header file can be generated for Java parsers; you must not pass
address@hidden/@option{--defines} to @command{bison}, nor use the
address@hidden directive.
+
+By default, the @samp{YYParser} class has package visibility.  A
+declaration @samp{%define "public"} will change to public visibility.
+Remember that, according to the Java language specification, the name
+of the @file{.java} file should match the name of the class in this
+case.
+
+All these files are documented using Javadoc.
+
address@hidden Java Semantic Values
address@hidden Java Semantic Values
address@hidden - No %union, specify type in %type/%token.
address@hidden - YYSTYPE
address@hidden - Printer and destructor
+
+There is no @code{%union} directive in Java parsers.  Instead, the
+semantic values' types (class names) should be specified in the
address@hidden or @code{%token} directive:
+
address@hidden
+%type <Expression> expr assignment_expr term factor
+%type <Integer> number
address@hidden example
+
+By default, the semantic stack is declared to have @code{Object} members,
+which means that the class types you specify can be of any class.
+To improve the type safety of the parser, you can declare the common
+superclass of all the semantic values using the @samp{%define} directive.
+For example, after the following declaration:
+
address@hidden
+%define "union_name" "ASTNode"
address@hidden example
+
address@hidden
+any @code{%type} or @code{%token} specifying a semantic type which
+is not a subclass of ASTNode, will cause a compile-time error.
+
+Types used in the directives may be qualified with a package name.
+Primitive data types are accepted for Java version 1.5 or later.  Note
+that in this case the autoboxing feature of Java 1.5 will be used.
+
+Java parsers do not support @code{%destructor}, since the language
+adopts garbage collection.  The parser will try to hold references
+to semantic values for as little time as needed.
+
+Java parsers do not support @code{%printer}, as @code{toString()}
+can be used to print the semantic values.  This however may change
+(in a backwards-compatible way) in future versions of Bison.
+
+
address@hidden Java Location Values
address@hidden Java Location Values
address@hidden - %locations
address@hidden - class Position
address@hidden - class Location
+
+When the directive @code{%locations} is used, the Java parser
+supports location tracking, see @ref{Locations, , Locations Overview}.
+An auxiliary user-defined class defines a @dfn{position}, a single point
+in a file; Bison itself defines a class representing a @dfn{location},
+a range composed of a pair of positions (possibly spanning several
+files).  The location class is an inner class of the parser; the name
+is @code{Location} by default, may also be renamed using @code{%define
+"location_type" "@var{class-name}}.
+
+The location class treats the position as a completely opaque value.
+By default, the class name is @code{Position}, but this can be changed
+with @code{%define "position_type" "@var{class-name}"}.
+
+
address@hidden {Location} {Position} begin
address@hidden {Location} {Position} end
+The first, inclusive, position of the range, and the first beyond.
address@hidden deftypemethod
+
address@hidden {Location} {void} toString ()
+Prints the range represented by the location.  For this to work
+properly, the position class should override the @code{equals} and
address@hidden methods appropriately.
address@hidden deftypemethod
+
+
address@hidden Java Parser Interface
address@hidden Java Parser Interface
address@hidden - define parser_class_name
address@hidden - Ctor
address@hidden - parse, error, set_debug_level, debug_level, set_debug_stream,
address@hidden   debug_stream.
address@hidden - Reporting errors
+
+The output file defines the parser class in the package optionally
+indicated in the @code{%define package} section.  The class name defaults
+to @code{YYParser}.  The @code{YY} prefix may be changed using
address@hidden; alternatively, you can use @samp{%define
+"parser_class_name" "@var{name}"} to give a custom name to the class.
+The interface of this class is detailed below.  It can be extended using
+the @code{%parse-param} directive; each occurrence of the directive will
+add a field to the parser class, and an argument to its constructor.
+
address@hidden {YYParser} {} YYParser (@var{type1} @var{arg1}, ...)
+Build a new parser object.  There are no arguments by default, unless
address@hidden @address@hidden @address@hidden was used.
address@hidden deftypemethod
+
address@hidden {YYParser} {boolean} parse ()
+Run the syntactic analysis, and return @code{true} on success,
address@hidden otherwise.
address@hidden deftypemethod
+
address@hidden {YYParser} {boolean} yyrecovering ()
+During the syntactic analysis, return @code{true} if recovering
+from a syntax error.  @xref{Error Recovery}.
address@hidden deftypemethod
+
address@hidden {YYParser} {java.io.PrintStream} getDebugStream ()
address@hidden {YYParser} {void} setDebugStream (java.io.printStream @var{o})
+Get or set the stream used for tracing the parsing.  It defaults to
address@hidden
address@hidden deftypemethod
+
address@hidden {YYParser} {int} getDebugLevel ()
address@hidden {YYParser} {void} setDebugLevel (int @var{l})
+Get or set the tracing level.  Currently its value is either 0, no trace,
+or nonzero, full tracing.
address@hidden deftypemethod
+
address@hidden {YYParser} {void} error (Location @var{l}, String @var{m})
+The definition for this member function must be supplied by the user
+in the same way as the scanner interface (@pxref{Java Scanner
+Interface}); the parser uses it to report a parser error occurring at
address@hidden, described by @var{m}.
address@hidden deftypemethod
+
+
address@hidden Java Scanner Interface
address@hidden Java Scanner Interface
address@hidden - prefix for yylex.
address@hidden - Pure interface to yylex
address@hidden - %lex-param
+
+There are two possible ways to interface a Bison-generated Java parser
+with a scanner.
+
address@hidden pure parser, in Java
+Contrary to C parsers, Java parsers do not use global variables; the
+state of the parser is always local to an instance of the parser class.
+Therefore, all Java parsers are ``pure'' in the C sense.  The
address@hidden directive can still be used in Java, and it
+will control whether the lexer resides in a separate class than the
+Bison-generated parser (therefore, Bison generates a class that is
+``purely'' a parser), or in the same class.  The interface to the scanner
+is similar, though the two cases present a slightly different naming.
+
+For the @code{%pure-parser} case, the scanner implements an interface
+called @code{Lexer} and defined within the parser class (e.g.,
address@hidden  The constructor of the parser object accepts
+an object implementing the interface.  The interface specifies
+the following methods.
+
address@hidden {Lexer} {void} error (Location @var{l}, String @var{m})
+As explained in @pxref{Java Parser Interface}, this method is defined
+by the user to emit an error message.  The first parameter is not used
+unless location tracking is active.  Its type can be changed using
address@hidden "location_type" "@var{class-name}".}
address@hidden deftypemethod
+
address@hidden {Lexer} {int} yylex (@var{type1} @var{arg1}, ...)
+Return the next token.  Its type is the return value, its semantic
+value and location are saved and returned by the ther methods in the
+interface.  Invocations of @samp{%lex-param @address@hidden
address@hidden@}} yield additional arguments.
address@hidden deftypemethod
+
address@hidden {Lexer} {Position} getStartPos ()
address@hidden {Lexer} {Position} getEndPos ()
+Return respectively the first position of the last token that yylex
+returned, and the first position beyond it.  These methods are not
+needed unless location tracking is active.
+
+The return type can be changed using @samp{%define "position_type"
+"@var{class-name}".}
address@hidden deftypemethod
+
address@hidden {Lexer} {Object} getLVal ()
+Return respectively the first position of the last token that yylex
+returned, and the first position beyond it.
+
+The return type can be changed using @samp{%define "union_name"
+"@var{class-name}".}
address@hidden deftypemethod
+
+
+If @code{%pure-parser} is not specified, the lexer interface
+resides in the same class (@code{YYParser}) as the Bison-generated
+parser. The fields and methods that are provided to
+this end are as follows.
+
address@hidden {YYParser} {void} error (Location @var{l}, String @var{m})
+As explained in @pxref{Java Parser Interface}, this method is defined
+by the user to emit an error message.  The first parameter is not used
+unless location tracking is active.  Its type can be changed using
address@hidden "location_type" "@var{class-name}".}
address@hidden deftypemethod
+
address@hidden {YYParser} {int} yylex (@var{type1} @var{arg1}, ...)
+Return the next token.  Its type is the return value, its semantic
+value and location are saved into @code{yylval}, @code{yystartpos},
address@hidden  Invocations of @samp{%lex-param @address@hidden
address@hidden@}} yield additional arguments.
address@hidden deftypemethod
+
address@hidden {Field} {YYParser} Position yystartpos
address@hidden {Field} {YYParser} Position yyendpos
+Contain respectively the first position of the last token that yylex
+returned, and the first position beyond it.  These methods are not
+needed unless location tracking is active.
+
+The field's type can be changed using @samp{%define "position_type"
+"@var{class-name}".}
address@hidden deftypecv
+
address@hidden {Field} {YYParser} Object yylval
+Return respectively the first position of the last token that yylex
+returned, and the first position beyond it.
+
+The field's type can be changed using @samp{%define "union_name"
+"@var{class-name}".}
address@hidden deftypecv
+
+By default the class generated for a non-pure Java parser is abstract,
+and the methods @code{yylex} and @code{yyerror} shall be placed in a
+subclass (possibly defined in the additional code section).  It is
+also possible, using the @code{%define "single_class"} declaration, to
+define the scanner in the same class as the parser; when this
+declaration is present, the class is not declared as abstract.
+In order to place the declarations for the scanner inside the
+parser class, you should use @code{%code} sections.
+
address@hidden Java Differences
address@hidden Differences between C/C++ and Java Grammars
+
+The different structure of the Java language forces several differences
+between C/C++ grammars, and grammars designed for Java parsers.  This
+section summarizes this differences.
+
address@hidden
address@hidden
+Since Java lacks a preprocessor, the @code{YYERROR}, @code{YYACCEPT},
address@hidden symbols (@pxref{Table of Symbols}) cannot obviously be
+macros.  Instead, they should be preceded in an action with
address@hidden  The actual definition of these symbols should be
+opaque to the Bison grammar, and it might change in the future.  The
+only meaningful operation that you can do, is to return them.
+
+Note that of these three symbols, only @code{YYACCEPT} and
address@hidden will cause a return from the @code{yyparse}
address@hidden parsers include the actions in a separate
+method than @code{yyparse} in order to have an intuitive syntax that
+corresponds to these C macros.}.
+
address@hidden
+The prolog declarations have a different meaning than in C/C++ code.
address@hidden @code
address@hidden %code
address@hidden imports} blocks are placed at the beginning of the Java
+source code.  They may include copyright notices.  For a @code{package}
+declarations, it is suggested to use @code{%define package} instead.
+
address@hidden blocks are placed inside the parser class.  If @code{%define
+single_class} is being used, the definitions of @code{yylex} and
address@hidden should be placed here.  Subroutines for the parser actions
+may be included in this kind of block.
+
+Other @code{%code} blocks are not supported in Java parsers.
address@hidden table
address@hidden itemize
+
 @c ================================================= FAQ
 
 @node FAQ
@@ -8326,7 +8652,7 @@ are addressed.
 * I can't build Bison::         Troubleshooting
 * Where can I find help?::      Troubleshouting
 * Bug Reports::                 Troublereporting
-* Other Languages::             Parsers in Java and others
+* More Languages::              Parsers in C++, Java, and so on
 * Beta Testing::                Experimenting development versions
 * Mailing Lists::               Meeting other Bison users
 @end menu
@@ -8649,15 +8975,15 @@ send a bug report just because you can n
 
 Send bug reports to @email{bug-bison@@gnu.org}.
 
address@hidden Other Languages
address@hidden Other Languages
address@hidden More Languages
address@hidden More Languages
 
 @display
-Will Bison ever have C++ support?  How about Java or @var{insert your
+Will Bison ever have C++ and Java support?  How about @var{insert your
 favorite language here}?
 @end display
 
-C++ support is there now, and is documented.  We'd love to add other
+C++ and Java support is there now, and is documented.  We'd love to add other
 languages; contributions are welcome.
 
 @node Beta Testing
@@ -8977,12 +9303,18 @@ Macro to pretend that an unrecoverable s
 making @code{yyparse} return 1 immediately.  The error reporting
 function @code{yyerror} is not called.  @xref{Parser Function, ,The
 Parser Function @code{yyparse}}.
+
+For Java parsers, this functionality is invoked using @code{return YYABORT;}
+instead.
 @end deffn
 
 @deffn {Macro} YYACCEPT
 Macro to pretend that a complete utterance of the language has been
 read, by making @code{yyparse} return 0 immediately.
 @xref{Parser Function, ,The Parser Function @code{yyparse}}.
+
+For Java parsers, this functionality is invoked using @code{return YYACCEPT;}
+instead.
 @end deffn
 
 @deffn {Macro} YYBACKUP
@@ -9023,6 +9355,9 @@ Macro to pretend that a syntax error has
 @code{yyerror} and then perform normal error recovery if possible
 (@pxref{Error Recovery}), or (if recovery is impossible) make
 @code{yyparse} return 1.  @xref{Error Recovery}.
+
+For Java parsers, this functionality is invoked using @code{return YYERROR;}
+instead.
 @end deffn
 
 @deffn {Function} yyerror
Index: m4/.cvsignore
===================================================================
RCS file: /sources/bison/bison/m4/.cvsignore,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -p -r1.25 -r1.26
--- m4/.cvsignore       26 Jan 2007 23:11:59 -0000      1.25
+++ m4/.cvsignore       29 Jan 2007 10:54:42 -0000      1.26
@@ -19,6 +19,8 @@ inline.m4
 inttypes-h.m4
 inttypes-pri.m4
 inttypes.m4
+javacomp.m4
+javaexec.m4
 lib-ld.m4
 lib-link.m4
 lib-prefix.m4
Index: src/getargs.c
===================================================================
RCS file: /sources/bison/bison/src/getargs.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -p -r1.88 -r1.89
--- src/getargs.c       31 Dec 2006 20:29:48 -0000      1.88
+++ src/getargs.c       29 Jan 2007 10:54:42 -0000      1.89
@@ -1,7 +1,7 @@
 /* Parse command line arguments for Bison.
 
    Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006 Free Software Foundation, Inc.
+   2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
@@ -70,6 +70,7 @@ int warnings_flag = warnings_none;
 static struct bison_language const valid_languages[] = {
   { "c", "c-skel.m4", ".c", ".h", true },
   { "c++", "c++-skel.m4", ".cc", ".hh", true },
+  { "java", "java-skel.m4", ".java", ".java", false },
   { "", "", "", "", false }
 };
 
Index: src/getargs.h
===================================================================
RCS file: /sources/bison/bison/src/getargs.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -p -r1.38 -r1.39
--- src/getargs.h       31 Dec 2006 20:29:48 -0000      1.38
+++ src/getargs.h       29 Jan 2007 10:54:42 -0000      1.39
@@ -1,6 +1,7 @@
 /* Parse command line arguments for bison.
-   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005, 
2006
-   Free Software Foundation, Inc.
+
+   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
+   2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
@@ -75,10 +76,10 @@ extern bool nondeterministic_parser;
 /* --language.  */
 struct bison_language
 {
-  char language[sizeof "c++"];
-  char skeleton[sizeof "c++-skel.m4"];
-  char src_extension[sizeof ".cc"];
-  char header_extension[sizeof ".hh"];
+  char language[sizeof "Java"];
+  char skeleton[sizeof "java-skel.m4"];
+  char src_extension[sizeof ".java"];
+  char header_extension[sizeof ".java"];
   bool add_tab;
 };
 
Index: tests/Makefile.am
===================================================================
RCS file: /sources/bison/bison/tests/Makefile.am,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -p -r1.45 -r1.46
--- tests/Makefile.am   18 Jan 2007 02:18:17 -0000      1.45
+++ tests/Makefile.am   29 Jan 2007 10:54:42 -0000      1.46
@@ -52,6 +52,7 @@ TESTSUITE_AT = \
        calc.at \
         torture.at existing.at regression.at \
         c++.at \
+        java.at \
        cxx-type.at glr-regression.at
 
 TESTSUITE = $(srcdir)/testsuite
Index: tests/atlocal.in
===================================================================
RCS file: /sources/bison/bison/tests/atlocal.in,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -p -r1.19 -r1.20
--- tests/atlocal.in    13 Oct 2006 05:00:26 -0000      1.19
+++ tests/atlocal.in    29 Jan 2007 10:54:42 -0000      1.20
@@ -30,3 +30,9 @@ LDFLAGS='@LDFLAGS@'
 
 # Are special libraries needed?
 LIBS='@LIBS@ @INTLLIBS@'
+
+# Empty if no javac was found
+CONF_JAVAC='@CONF_JAVAC@'
+
+# Empty if no Java VM was found
+CONF_JAVA='@CONF_JAVA@'
Index: tests/input.at
===================================================================
RCS file: /sources/bison/bison/tests/input.at,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -p -r1.75 -r1.76
--- tests/input.at      17 Jan 2007 08:36:07 -0000      1.75
+++ tests/input.at      29 Jan 2007 10:54:42 -0000      1.76
@@ -714,6 +714,7 @@ AT_DATA([input-c.y],
 [[%code q {}
 %code bad {}
 %code bad {}
+%code format {}
 %%
 start: ;
 ]])
@@ -721,6 +722,7 @@ AT_CHECK([[bison input-c.y]], [0], [],
 [[input-c.y:1.7: warning: %code qualifier `q' is not used
 input-c.y:2.7-9: warning: %code qualifier `bad' is not used
 input-c.y:3.7-9: warning: %code qualifier `bad' is not used
+input-c.y:4.7-12: warning: %code qualifier `format' is not used
 ]])
 
 AT_DATA([input-c-glr.y],
Index: tests/java.at
===================================================================
RCS file: tests/java.at
diff -N tests/java.at
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ tests/java.at       29 Jan 2007 10:54:42 -0000      1.1
@@ -0,0 +1,415 @@
+# Simple calculator.                         -*- Autotest -*-
+
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
+# Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+AT_BANNER([[Java Calculator.]])
+
+
+# ------------------------- #
+# Helping Autotest macros.  #
+# ------------------------- #
+
+
+# _AT_DATA_JAVA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES], [BISON-EPILOGUE])
+# ----------------------------------------------------------------------
+# Produce `calc.y'.  Don't call this macro directly, because it contains
+# some occurrences of `$1' etc. which will be interpreted by m4.  So
+# you should call it with $1, $2, and $3 as arguments, which is what
+# AT_DATA_JAVA_CALC_Y does.
+m4_define([_AT_DATA_JAVA_CALC_Y],
+[m4_if([$1$2$3], $[1]$[2]$[3], [],
+       [m4_fatal([$0: Invalid arguments: address@hidden)])dnl
+AT_DATA([Calc.y],
+[[/* Infix notation calculator--calc */
+%language "Java"
+%name-prefix "Calc"]
+%define parser_class_name "Calc"
+%define public
+
+$4[
+%code imports {
+  import java.io.StreamTokenizer;
+  import java.io.InputStream;
+  import java.io.InputStreamReader;
+  import java.io.Reader;
+  import java.io.IOException;
+}
+
+/* Bison Declarations */
+%token <Integer> NUM "number"
+%type  <Integer> exp
+
+%nonassoc '=' /* comparison            */
+%left '-' '+'
+%left '*' '/'
+%left NEG     /* negation--unary minus */
+%right '^'    /* exponentiation        */
+
+/* Grammar follows */
+%%
+input:
+  line
+| input line
+;
+
+line:
+  '\n'
+| exp '\n'
+| error '\n'
+;
+
+exp:
+  NUM                { $$ = $1;                                             }
+| exp '=' exp
+  {
+    if ($1.intValue () != $3.intValue ())
+      yyerror ("calc: error: " + $1 + " != " + $3);
+  }
+| exp '+' exp        { $$ = new Integer ($1.intValue () + $3.intValue ());  }
+| exp '-' exp        { $$ = new Integer ($1.intValue () - $3.intValue ());  }
+| exp '*' exp        { $$ = new Integer ($1.intValue () * $3.intValue ());  }
+| exp '/' exp        { $$ = new Integer ($1.intValue () / $3.intValue ());  }
+| '-' exp  %prec NEG { $$ = new Integer (-$2.intValue ());                  }
+| exp '^' exp        { $$ = new Integer ((int)
+                                         Math.pow ($1.intValue (),
+                                                   $3.intValue ()));        }
+| '(' exp ')'        { $$ = $2;                                             }
+| '(' error ')'      { $$ = new Integer (1111);                             }
+| '!'                { $$ = new Integer (0); return YYERROR;                }
+| '-' error          { $$ = new Integer (0); return YYERROR;                }
+;
+%%
+
+  class Position {
+    public int line;
+
+    public Position ()
+    {
+      line = 0;
+    }
+
+    public Position (int l)
+    {
+      line = l;
+    }
+
+    public long getHashCode ()
+    {
+      return line;
+    }
+
+    public boolean equals (Position l)
+    {
+      return l.line == line;
+    }
+
+    public String toString ()
+    {
+      return Integer.toString (line);
+    }
+
+    public int lineno ()
+    {
+      return line;
+    }
+  }
+
+]$5
+])
+])# _AT_DATA_JAVA_CALC_Y
+
+
+# AT_DATA_CALC_Y([BISON-OPTIONS], [BISON-EPILOGUE])
+# -------------------------------------------------
+# Produce `calc.y'.
+m4_define([AT_DATA_JAVA_CALC_Y],
+[_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1], [$2])
+])
+
+
+
+# AT_JAVA_COMPILE(SOURCE)
+# -----------------------
+# Compile SOURCES into Java class files.  Skip the test if java or javac is
+# not installed.
+m4_define([AT_JAVA_COMPILE],
+[AT_CHECK([test -n "$CONF_JAVA$CONF_JAVAC" || exit 77])
+AT_CHECK([$SHELL ../../../javacomp.sh $1],
+         0, [ignore], [ignore])])
+
+
+# AT_JAVA_PARSER_CHECK(COMMAND, EXIT-STATUS, EXPOUT, EXPERR, [PRE])
+# -----------------------------------------------------------------
+m4_define([AT_JAVA_PARSER_CHECK],
+[AT_CHECK([$5 $SHELL ../../../javaexec.sh $1], [$2], [$3], [$4])])
+
+
+# _AT_CHECK_JAVA_CALC_ERROR(BISON-OPTIONS, INPUT,
+#                           [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
+# ---------------------------------------------------------
+# Run `calc' on INPUT, and expect a `syntax error' message.
+#
+# If INPUT starts with a slash, it is used as absolute input file name,
+# otherwise as contents.
+#
+# The VERBOSE-AND-LOCATED-ERROR-MESSAGE is stripped of locations
+# and expected tokens if necessary, and compared with the output.
+m4_define([_AT_CHECK_JAVA_CALC_ERROR],
+[m4_bmatch([$2], [^/],
+           [AT_JAVA_PARSER_CHECK([Calc < $2], 0, [], [stderr])],
+           [AT_DATA([[input]],
+[[$2
+]])
+AT_JAVA_PARSER_CHECK([Calc < input], 0, [], [stderr])])
+
+# Normalize the observed and expected error messages, depending upon the
+# options.
+# 1. Create the reference error message.
+AT_DATA([[expout]],
+[$3
+])
+# 2. If locations are not used, remove them.
+AT_YYERROR_SEES_LOC_IF([],
+[[sed 's/^[-0-9.]*: //' expout >at-expout
+mv at-expout expout]])
+# 3. If error-verbose is not used, strip the`, unexpected....' part.
+m4_bmatch([$1], [%error-verbose], [],
+[[sed 's/syntax error, .*$/syntax error/' expout >at-expout
+mv at-expout expout]])
+# 4. Check
+AT_CHECK([cat stderr], 0, [expout])
+])
+
+# _AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-CODE], [BISON-EPILOGUE])
+# -----------------------------------------------------------------------
+# Start a testing chunk which compiles `calc' grammar with
+# BISON-DIRECTIVES, and performs several tests over the parser.
+m4_define([_AT_CHECK_JAVA_CALC],
+[# We use integers to avoid dependencies upon the precision of doubles.
+AT_SETUP([Calculator $1])
+
+AT_BISON_OPTION_PUSHDEFS([$1])
+
+AT_DATA_JAVA_CALC_Y([$1
+%code {
+$2
+}], [$3])
+
+AT_CHECK([bison -o Calc.java Calc.y])
+AT_JAVA_COMPILE([Calc.java])
+
+# Test the priorities.
+AT_DATA([[input]],
+[[1 + 2 * 3 = 7
+1 + 2 * -3 = -5
+
+-1^2 = -1
+(-1)^2 = 1
+
+---1 = -1
+
+1 - 2 - 3 = -4
+1 - (2 - 3) = 2
+
+2^2^3 = 256
+(2^2)^3 = 64
+]])
+AT_JAVA_PARSER_CHECK([Calc < input], 0, [], [stderr])
+
+
+# Some syntax errors.
+_AT_CHECK_JAVA_CALC_ERROR([$1], [0 0],
+                          [1: syntax error, unexpected number])
+_AT_CHECK_JAVA_CALC_ERROR([$1], [1//2],
+                          [1: syntax error, unexpected '/', expecting number 
or '-' or '(' or '!'])
+_AT_CHECK_JAVA_CALC_ERROR([$1], [error],
+                          [1: syntax error, unexpected $undefined])
+_AT_CHECK_JAVA_CALC_ERROR([$1], [1 = 2 = 3],
+                          [1: syntax error, unexpected '='])
+_AT_CHECK_JAVA_CALC_ERROR([$1], [
++1],
+                          [2: syntax error, unexpected '+'])
+# Exercise error messages with EOF: work on an empty file.
+_AT_CHECK_JAVA_CALC_ERROR([$1], [/dev/null],
+                          [1: syntax error, unexpected end of input])
+
+# Exercise the error token: without it, we die at the first error,
+# hence be sure to
+#
+# - have several errors which exercise different shift/discardings
+#   - (): nothing to pop, nothing to discard
+#   - (1 + 1 + 1 +): a lot to pop, nothing to discard
+#   - (* * *): nothing to pop, a lot to discard
+#   - (1 + 2 * *): some to pop and discard
+#
+# - test the action associated to `error'
+#
+# - check the lookahead that triggers an error is not discarded
+#   when we enter error recovery.  Below, the lookahead causing the
+#   first error is ")", which is needed to recover from the error and
+#   produce the "0" that triggers the "0 != 1" error.
+#
+_AT_CHECK_JAVA_CALC_ERROR([$1], 
+                          [() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1],
+[1: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
+1: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
+1: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
+1: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
+calc: error: 4444 != 1])
+
+# The same, but this time exercising explicitly triggered syntax errors.
+# POSIX says the lookahead causing the error should not be discarded.
+_AT_CHECK_JAVA_CALC_ERROR([$1], [(!) + (0 0) = 1],
+[1: syntax error, unexpected number
+calc: error: 2222 != 1])
+_AT_CHECK_JAVA_CALC_ERROR([$1], [(- *) + (0 0) = 1],
+[1: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
+1: syntax error, unexpected number
+calc: error: 2222 != 1])
+AT_BISON_OPTION_POPDEFS
+
+AT_CLEANUP
+])# _AT_CHECK_JAVA_CALC
+
+
+# AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-EPILOGUE])
+# --------------------------------------------------------
+# Start a testing chunk which compiles `calc' grammar with
+# BISON-DIRECTIVES, and performs several tests over the parser.
+# Run the test with and without %error-verbose.
+m4_define([AT_CHECK_JAVA_CALC],
+[_AT_CHECK_JAVA_CALC([$1], [$2], [$3])
+_AT_CHECK_JAVA_CALC([%error-verbose $1], [$2], [$3])
+])# AT_CHECK_JAVA_CALC
+
+
+# ------------------------ #
+# Simple LALR Calculator.  #
+# ------------------------ #
+
+dnl AT_CHECK_JAVA_CALC([], [])
+
+AT_CHECK_JAVA_CALC([%define single_class %locations], [[
+  StreamTokenizer st;
+
+  public Calc (InputStream is)
+  {
+    Reader r = new InputStreamReader (is);
+    st = new StreamTokenizer(r);
+    st.resetSyntax ();
+    st.eolIsSignificant (true);
+    st.whitespaceChars (9, 9);
+    st.whitespaceChars (32, 32);
+    st.wordChars (48, 57);
+
+    yyendpos = new Position (1);
+  }
+
+  public int yylex () throws IOException {
+    int ttype = st.nextToken ();
+    yystartpos = yyendpos;
+    if (ttype == st.TT_EOF)
+      return EOF;
+
+    else if (ttype == st.TT_EOL)
+      {
+        yyendpos = new Position (yyendpos.lineno () + 1);
+        return (int) '\n';
+      }
+
+    else if (ttype == st.TT_WORD)
+      {
+        yylval = new Integer (st.sval);
+        return NUM;
+      }
+
+    else
+      return st.ttype;
+  }
+
+  public void yyerror (Location l, String s)
+  {
+    if (l == null)
+      System.err.println (s);
+    else
+      System.err.println (l.begin + ": " + s);
+  }
+
+  public static void main (String args[]) throws IOException
+  {
+    new Calc (System.in).parse ();
+  }
+]])
+
+AT_CHECK_JAVA_CALC([%pure-parser], [[
+  public static void main (String args[]) throws IOException
+  {
+    CalcLexer l = new CalcLexer (System.in);
+    Calc p = new Calc (l);
+    p.parse ();
+  }
+]], [[
+class CalcLexer implements Calc.Lexer {
+  Integer yylval;
+
+  StreamTokenizer st;
+  
+  public Object getLVal ()
+  {
+    return yylval;
+  }
+  
+  public CalcLexer (InputStream is)
+  {
+    Reader r = new InputStreamReader (is);
+    st = new StreamTokenizer(r);
+    st.resetSyntax ();
+    st.eolIsSignificant (true);
+    st.whitespaceChars (9, 9);
+    st.whitespaceChars (32, 32);
+    st.wordChars (48, 57);
+  }
+  
+  public int yylex () throws IOException {
+    int ttype = st.nextToken ();
+    if (ttype == st.TT_EOF)
+      return Calc.EOF;
+        
+    else if (ttype == st.TT_EOL)
+      return (int) '\n';
+        
+    else if (ttype == st.TT_WORD)
+      {
+        yylval = new Integer (st.sval);
+        return Calc.NUM;
+      }
+        
+    else
+      return st.ttype;
+  }
+
+  
+  public void yyerror (String s)
+  {
+    System.err.println (s); 
+  }
+}
+]])
+
+dnl AT_CHECK_JAVA_CALC([%pure-parser %locations], [])
Index: tests/testsuite.at
===================================================================
RCS file: /sources/bison/bison/tests/testsuite.at,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -p -r1.33 -r1.34
--- tests/testsuite.at  18 Jan 2007 02:18:17 -0000      1.33
+++ tests/testsuite.at  29 Jan 2007 10:54:42 -0000      1.34
@@ -71,6 +71,9 @@ m4_include([regression.at])
 # Some C++ specific tests.
 m4_include([c++.at])
 
+# And some Java specific tests.
+m4_include([java.at])
+
 # GLR tests:
 # C++ types, simplified
 m4_include([cxx-type.at])

reply via email to

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