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