[Top][All Lists]
[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 }
};
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] Java support,
Paolo Bonzini <=