bison-patches
[Top][All Lists]
Advanced

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

[PATCH] Java support


From: Paolo Bonzini
Subject: [PATCH] Java support
Date: Mon, 09 Oct 2006 11:30:17 +0200
User-agent: Thunderbird 1.5.0.7 (Macintosh/20060909)

This patch (whose prerequisites are the %language and %provides/%requires/%code patches) finally adds Java support.

It adds documentation but no tests for now. I will do so, but a patch to that end will have a different scope than this one (touching, for example, the configury), so I prefer to keep the two separated.

I hope the documentation is complete; in addition to that, generated parsers have complete Javadoc comments.

Ok?  Should I wait for the tests to be also approved, before committing?

Paolo
2006-10-09  Paolo Bonzini  <address@hidden>

        * NEWS: Document Java parsers.
        * TODO: Clean up.
        * data/java.m4, data/java-skel.m4, data/lalr1.java: New.
        * doc/bison.texinfo (A Complete C++ Example): Move under
        C++ Parsers.
        (Java Parsers): New.
        (Other Languages): Rename to More languages, Java is there now.
        (Table Of Symbols): Update YYACCEPT, YYERROR, YYABORT for Java.
        
Index: NEWS
===================================================================
RCS file: /sources/bison/bison/NEWS,v
retrieving revision 1.160
diff -u -r1.160 NEWS
--- NEWS        13 Sep 2006 19:42:04 -0000      1.160
+++ NEWS        9 Oct 2006 07:37:20 -0000
@@ -3,6 +3,9 @@
 
 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.97
diff -u -r1.97 TODO
--- TODO        10 Jun 2006 03:02:22 -0000      1.97
+++ TODO        9 Oct 2006 07:32:09 -0000
@@ -14,13 +14,6 @@
 
 * 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.
@@ -151,23 +144,6 @@
 * 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:
 
@@ -228,9 +204,6 @@
 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: 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   9 Oct 2006 07:32:09 -0000
@@ -0,0 +1,28 @@
+m4_divert(-1)                                               -*- Autoconf -*-
+
+# Java skeleton dispatching for Bison.
+# Copyright (C) 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 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(             [m4_fatal([%glr-parser not supported for Java])])
+b4_nondeterministic_if([m4_fatal([%nondeterministic-parser not supported for 
Java])])
+b4_push_if(            [m4_fatal([%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        9 Oct 2006 07:32:09 -0000
@@ -0,0 +1,294 @@
+m4_divert(-1)                                               -*- Autoconf -*-
+
+# Java skeleton for Bison
+
+# Copyright (C) 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 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
+
+# If the %union is not named, it can have any Object.
+m4_define_default([b4_union_name], [Object])
+
+# If the %name-prefix is not given, it is YY (uppercase).
+m4_define_default([b4_prefix], [YY])
+
+
+# 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)
+# -------------------------
+m4_define_default([b4_public], [0])
+m4_define([b4_public_if],
+[m4_if(b4_public, [1], [$1], [$2])])
+
+
+# b4_single_class_if(TRUE, FALSE)
+# -------------------------------
+m4_define_default([b4_single_class], [0])
+m4_define([b4_single_class_if],
+[m4_if(b4_single_class, [1], [$1], [$2])])
+
+# b4_abstract_if(TRUE, FALSE)
+# ---------------------------
+m4_define([b4_abstract_if],
+[m4_if(b4_nonabstract, [0], [$1], [$2])])
+b4_pure_if(
+[m4_define([b4_nonabstract], [1])],
+[m4_define([b4_nonabstract], [b4_single_class])])
+
+
+# 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.  ##
+## ---------------- ##
+
+# Default parser class name.
+m4_define_default([b4_parser_class_name], m4_defn([b4_prefix])[Parser])
+m4_define_default([b4_location_type], [Location])
+m4_define_default([b4_position_type], [Position])
+m4_define_default([b4_lex_throws], [java.io.IOException])
+m4_define_default([b4_throws], [b4_lex_throws])
+
+
+
+## ----------------- ##
+## 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))))])
+
+# In this alternative implementation, the user can specify a %union
+# and use the member name between the angle brackets.  Therefore,
+# we need to map the names to types, to create the casts.  This
+# looks cool but is quite brittle.
+#
+### _b4_stype_process defines a macro b4_stype(MEMBER-NAME) which
+### maps to the corresponding type name.
+# m4_define([b4_stype_process], [m4_indir([_b4_stype_process], $*)])
+# m4_define([_b4_stype_process], [
+# m4_define([b4_stype($2)], [($1)])
+# m4_case($#, 2, [], 3, [], [$0(m4_shiftn(2, $@))])])
+# 
+### Sanitize the %union.  Remove braces, and turn the sequence of "TYPE 
MEMBER;"
+### into "TYPE, MEMBER, TYPE, MEMBER, ..."
+# m4_define([_b4_stype_braces],
+# [m4_bpatsubst([$1], [[{}]], [])])
+#
+# m4_define([_b4_stype_comma],
+# [m4_bpatsubst([$1],
+#              [[ \t]*\([A-Za-z_]+\)[ \t]+\([A-Za-z_]+\)[ \t]*;[ \t]*],
+#           [\1, \2,])])
+# 
+### Create the macros
+# m4_pushdef([b4_syncline], [])
+# b4_stype_process(_b4_stype_comma(_b4_stype_braces(b4_stype)))
+# m4_popdef([b4_syncline])
+#
+### And use them here.
+# m4_define([b4_rhs_value],
+# [(m4_ifval([$3], [m4_indir([b4_stype($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.
+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     9 Oct 2006 07:32:09 -0000
@@ -0,0 +1,889 @@
+m4_divert(-1)
+
+# Java skeleton for Bison -*- autoconf -*-
+
+# Copyright (C) 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 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])
+
+# TODO: should be in bison.m4
+m4_define_default([b4_lex_param], [])
+
+b4_defines_if([m4_fatal(b4_skeleton[: %defines does not make sense in Java])])
+m4_if([m4_defn([b4_symbol_destructors]))],
+      [m4_fatal(b4_skeleton[: %destructor does not make sense in Java])],
+      [])
+
+m4_divert(0)dnl
+dnl
address@hidden @output_parser_name@
+b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
+  [2006])
+
+[/* First part of user declarations.  */
+]b4_pre_prologue
+
+m4_ifdef([b4_requires],
+[[/* Copy the %requires blocks.  */
+]b4_user_requires])[
+
+/**
+ * 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 = -1;]
+
+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 (]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 ();
+            }
+      }
+
+    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 <= yyeof_)
+          {
+           yychar = yytoken = yyeof_;
+           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 <= yyeof_)
+             {
+             /* Return failure if at end of input.  */
+             if (yychar == yyeof_)
+               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 yyeof_ = 0;
+  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 prologue.  */
+b4_user_post_prologue[
+
+}
+
+]m4_ifdef([b4_provides],
+[[/* Copy the %provides blocks.  */
+]b4_user_provides])
+
+b4_epilogue
+m4_divert(-1)
Index: doc/bison.texinfo
===================================================================
RCS file: /sources/bison/bison/doc/bison.texinfo,v
retrieving revision 1.205
diff -u -r1.205 bison.texinfo
--- doc/bison.texinfo   11 Sep 2006 18:56:58 -0000      1.205
+++ doc/bison.texinfo   9 Oct 2006 07:32:11 -0000
@@ -104,7 +104,7 @@
                         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.
@@ -284,10 +284,10 @@
 * 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
 
@@ -296,6 +296,7 @@
 * 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
 
@@ -305,6 +306,15 @@
 * 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
@@ -7137,12 +7144,12 @@
 
 @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
@@ -7154,6 +7161,7 @@
 * 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
@@ -7360,7 +7378,7 @@
 
 
 @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,
@@ -7380,7 +7398,7 @@
 @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
@@ -7395,7 +7413,7 @@
 @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
@@ -7543,7 +7561,7 @@
 @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
@@ -7713,7 +7731,7 @@
 @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.
@@ -7834,7 +7852,7 @@
 @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.
 
@@ -7860,6 +7878,325 @@
 @}
 @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, @samp{%language "Java"}, or the synonymous
+command-line option @option{--language=java}.
+
+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 the @samp{%provides}
+directive.
+
+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 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}"}.  The name of
+the location class, @code{YYParser.Location} by default, may also be
+renamed using @code{%define "location_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} method
+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{%requires} section.  The class name
+defaults to @code{YYParser}, but may be changed using
address@hidden or @samp{%define "parser_class_name"
+"@var{name}"}.  The interface of this class is detailed below.  It can
+be extended using the @code{%parse-param} feature: its semantics is
+slightly changed since it describes an additional member of the parser
+class, and an additional argument for 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 are not using global variables,
+therefore all Java parsers are ``pure'' in the C sense.  However,
+the @code{%pure-parser} directive, in Java, 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 by default @code{YYParser.Lexer}.  An object implementing the
+interface is passed to the constructor of the parser object.  The
+object should implement 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 %requires
address@hidden blocks are placed at the beginning of the Java
+source code.  They may include copyright notices or @code{package}
+declarations
+
address@hidden %code
address@hidden blocks are placed at the end of the parser
+class.  If @code{%define "single_class"} is being used, the definitions
+of @code{yylex} and @code{yyerror} should be placed here.
+Subroutines for the parser actions may be included in this kind of block.
+
address@hidden %provides
address@hidden blocks are equivalent to the additional code section
+for Java parser.  Code in these blocks is placed after the definition of
+the parser class.  Many things can go in this block, including:
+classes used by the parser actions; the definition of the position class;
+for non-pure parsers, a concrete subclass of the Bison-defined class.
address@hidden table
address@hidden itemize
+
 @c ================================================= FAQ
 
 @node FAQ
@@ -7880,7 +8217,7 @@
 * 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
@@ -8203,15 +8540,15 @@
 
 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
@@ -8563,12 +8886,18 @@
 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
@@ -8609,6 +8938,9 @@
 @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: src/getargs.c
===================================================================
RCS file: /sources/bison/bison/src/getargs.c,v
retrieving revision 1.80
diff -u -r1.80 getargs.c
--- src/getargs.c       20 Sep 2006 20:04:28 -0000      1.80
+++ src/getargs.c       9 Oct 2006 07:32:11 -0000
@@ -66,6 +66,7 @@
 static const struct bison_language valid_languages[] = {
   { "c", "c-skel.m4", ".c", ".h", true },
   { "c++", "c++-skel.m4", ".cc", ".hh", true },
+  { "java", "java-skel.m4", ".java", ".java", false },
   { NULL, NULL, NULL, NULL, false }
 };
 

reply via email to

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