# Java skeleton for Bison -*- autoconf -*-
-# Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2007-2013 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
b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java],
[b4_skeleton])])
-# We don't depend on %debug in Java, but pacify warnings about non-used flags.
+# We do not depend on %debug in Java, but pacify warnings about
+# non-used flags.
b4_parse_trace_if([0], [0])
m4_define([b4_symbol_no_destructor_assert],
[b4_symbol_action_location([$1], [destructor])])])])
b4_symbol_foreach([b4_symbol_no_destructor_assert])
-m4_divert_push(0)dnl
-@output(b4_parser_file_name@)@
+# Setup some macros for api.push-pull.
+b4_percent_define_default([[api.push-pull]], [[pull]])
+b4_percent_define_check_values([[[[api.push-pull]],
+ [[pull]], [[push]], [[both]]]])
+
+# Define m4 conditional macros that encode the value
+# of the api.push-pull flag.
+b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
+b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
+m4_case(b4_percent_define_get([[api.push-pull]]),
+ [pull], [m4_define([b4_push_flag], [[0]])],
+ [push], [m4_define([b4_pull_flag], [[0]])])
+
+# Define a macro to be true when api.push-pull has the value "both".
+m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])])
+
+# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing
+# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
+# behavior of Bison at all when push parsing is already requested.
+b4_define_flag_if([use_push_for_pull])
+b4_use_push_for_pull_if([
+ b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
+ [m4_define([b4_push_flag], [[1]])])])
+
+# Define a macro to encapsulate the parse state variables.
+# This allows them to be defined either in parse() when doing
+# pull parsing, or as class instance variable when doing push parsing.
+m4_define([b4_define_state],[[
+ /* Lookahead and lookahead in internal form. */
+ int yychar = yyempty_;
+ int yytoken = 0;
+
+ /* State. */
+ int yyn = 0;
+ int yylen = 0;
+ int yystate = 0;
+ YYStack yystack = new YYStack ();
+ int label = YYNEWSTATE;
+
+ /* Error handling. */
+ int yynerrs_ = 0;
+ ]b4_locations_if([/* The location where the error started. */
+ b4_location_type yyerrloc = null;
+
+ /* Location. */
+ b4_location_type yylloc = new b4_location_type (null, null);])[
+
+ /* Semantic value of the lookahead. */
+ ]b4_yystype[ yylval = null;
+]])
+
+b4_output_begin([b4_parser_file_name])
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
- [2007, 2008, 2009])
+ [2007-2013])
b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);
])[/* First part of user declarations. */
{
]b4_identification[
]b4_error_verbose_if([[
- /** True if verbose error messages are enabled. */
+ /**
+ * True if verbose error messages are enabled.
+ */
private boolean yyErrorVerbose = true;
/**
* 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. */
+ * and ending positions.
+ */
public class ]b4_location_type[ {
- /** The first, inclusive, position in the range. */
+ /**
+ * The first, inclusive, position in the range.
+ */
public ]b4_position_type[ begin;
- /** The first position beyond the range. */
+ /**
+ * The first position beyond the range.
+ */
public ]b4_position_type[ end;
/**
* Create a <code>]b4_location_type[</code> denoting an empty range located at
* a given point.
- * @@param loc The position at which the range is anchored. */
+ * @@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 end The first position beyond the range. */
+ * @@param end 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. */
+ * method.
+ */
public String toString () {
if (begin.equals (end))
return begin.toString ();
private ]b4_location_type[ yylloc (YYStack rhs, int n)
{
if (n > 0)
- return new ]b4_location_type[ (rhs.locationAt (1).begin, rhs.locationAt (n).end);
+ return new ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
else
return new ]b4_location_type[ (rhs.locationAt (0).end);
}]])[
/** Token returned by the scanner to signal the end of its input. */
public static final int EOF = 0;
-]b4_token_enums(b4_tokens)[
+]b4_token_enums[
]b4_locations_if([[/**
* Method to retrieve the beginning position of the last scanned token.
- * @@return the position at which the last scanned token starts. */
+ * @@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. */
+ * @@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. */
+ * @@return the semantic value of the last scanned token.
+ */
]b4_yystype[ getLVal ();
/**
* Entry point for the scanner. Returns the token identifier corresponding
* to the next token and prepares to return the semantic value
* ]b4_locations_if([and beginning/ending positions ])[of the token.
- * @@return the token identifier corresponding to the next token. */
+ * @@return the token identifier corresponding to the next token.
+ */
int yylex () ]b4_maybe_throws([b4_lex_throws])[;
/**
*
* ]b4_locations_if([[@@param loc The location of the element to which the
* error message is related]])[
- * @@param msg The string for the error message. */
+ * @@param msg The string for the error message.
+ */
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);]
}
]b4_percent_code_get([[lexer]])[
}
- ]])[/** The object doing lexical analysis for us. */
+ ]])[/**
+ * The object doing lexical analysis for us.
+ */
private Lexer yylexer;
]
b4_parse_param_vars
}
public final void pop () {
- height--;
+ pop (1);
}
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);]])[
+ java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);
+ ]b4_locations_if([[java.util.Arrays.fill (locStack, height - num + 1, height + 1, null);]])[
}
height -= num;
}
{
out.print ("Stack now");
- for (int i = 0; i < height; i++)
+ for (int i = 0; i <= height; i++)
{
out.print (' ');
out.print (stateStack[i]);
/**
* Returned by a Bison action in order to stop the parsing process and
- * return success (<tt>true</tt>). */
+ * 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>). */
+ * return failure (<tt>false</tt>).
+ */
public static final int YYABORT = 1;
+]b4_push_if([
+ /**
+ * Returned by a Bison action in order to request a new token.
+ */
+ public static final int YYPUSH_MORE = 4;])[
+
/**
* Returned by a Bison action in order to start error recovery without
- * printing an error message. */
+ * printing an error message.
+ */
public static final int YYERROR = 2;
- // Internal return codes that are not supported for user semantic
- // actions.
+ /**
+ * Internal return codes that are not supported for user semantic
+ * actions.
+ */
private static final int YYERRLAB = 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;
+]b4_push_if([[ private static final int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing. */]])[
private int yyerrstatus_ = 0;
+]b4_push_if([dnl
+b4_define_state])[
/**
* 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. */
+ * operation.
+ */
public final boolean recovering ()
{
return yyerrstatus_ == 0;
]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.
+ '$$ = $1'. Otherwise, use the top of the stack.
Otherwise, the following line sets YYVAL to garbage.
This behavior is undocumented and Bison
+ (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
}
+]b4_push_if([],[[
/**
* 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_list2([b4_lex_throws], [b4_throws])])[
+ public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[
+]b4_push_if([
+ /**
+ * Push Parse input from external lexer
+ *
+ * @@param yylextoken current token
+ * @@param yylexval current lval
+]b4_locations_if([ * @@param yylexloc current position])[
+ *
+ * @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
+ */
+ public int push_parse (int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc]))
+ b4_maybe_throws([b4_list2([b4_lex_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;
-
- YYStack yystack = new YYStack ();
-
- /* 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_yystype[ yylval = null;
-
- int yyresult;
-
+ ]b4_locations_if([/* @@$. */
+ b4_location_type yyloc;])[
+]b4_push_if([],[[
+]b4_define_state[
yycdebug ("Starting parse\n");
yyerrstatus_ = 0;
+ /* Initialize the stack. */
+ yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[);
]m4_ifdef([b4_initial_action], [
-m4_pushdef([b4_at_dollar], [yylloc])dnl
-m4_pushdef([b4_dollar_dollar], [yylval])dnl
+b4_dollar_pushdef([yylval], [], [yylloc])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;
+b4_dollar_popdef[]dnl
+])[
+]])[
+]b4_push_if([[
+ if (!this.push_parse_initialized)
+ {
+ push_parse_initialize ();
+]m4_ifdef([b4_initial_action], [
+b4_dollar_pushdef([yylval], [], [yylloc])dnl
+ /* User initialization code. */
+ b4_user_initial_action
+b4_dollar_popdef[]dnl
+])[
+ yycdebug ("Starting parse\n");
+ yyerrstatus_ = 0;
+ } else
+ label = YYGETTOKEN;
+
+ boolean push_token_consumed = true;
+]])[
for (;;)
switch (label)
{
/* Accept? */
if (yystate == yyfinal_)
- return true;
+ ]b4_push_if([{label = YYACCEPT; break;}],
+ [return true;])[
/* Take a decision. First try without lookahead. */
yyn = yypact_[yystate];
label = YYDEFAULT;
break;
}
+]b4_push_if([ /* Fall Through */
+ case YYGETTOKEN:])[
/* Read a lookahead token. */
if (yychar == yyempty_)
{
+]b4_push_if([[
+ if (!push_token_consumed)
+ return YYPUSH_MORE;
+ yycdebug ("Reading a token: ");
+ yychar = yylextoken;
+ yylval = yylexval;]b4_locations_if([
+ yylloc = yylexloc;])[
+ push_token_consumed = false;]])[
+]b4_push_if([],[[
yycdebug ("Reading a token: ");
- yychar = yylexer.yylex ();]
- b4_locations_if([[
- yylloc = new ]b4_location_type[(yylexer.getStartPos (),
- yylexer.getEndPos ());]])
- yylval = yylexer.getLVal ();[
+ yychar = yylexer.yylex ();
+ yylval = yylexer.getLVal ();]b4_locations_if([
+ yylloc = new b4_location_type (yylexer.getStartPos (),
+ yylexer.getEndPos ());])[
+]])[
}
/* Convert token to internal form. */
if (yyerrstatus_ == 0)
{
++yynerrs_;
+ if (yychar == yyempty_)
+ yytoken = yyempty_;
yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
}
{
/* Return failure if at end of input. */
if (yychar == Lexer.EOF)
- return false;
+ ]b4_push_if([{label = YYABORT; break;}],[return false;])[
}
else
- yychar = yyempty_;
+ yychar = yyempty_;
}
/* Else will try to reuse lookahead token after shifting the error
label = YYERRLAB1;
break;
- /*---------------------------------------------------.
+ /*-------------------------------------------------.
| errorlab -- error raised explicitly by YYERROR. |
- `---------------------------------------------------*/
+ `-------------------------------------------------*/
case YYERROR:
]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[
}
}
- /* Pop the current state because it cannot handle the error token. */
- if (yystack.height == 1)
- return false;
+ /* Pop the current state because it cannot handle the
+ * error token. */
+ if (yystack.height == 0)
+ ]b4_push_if([{label = YYABORT; break;}],[return false;])[
]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
yystack.pop ();
yystack.print (yyDebugStream);
}
- ]b4_locations_if([
+ if (label == YYABORT)
+ /* Leave the switch. */
+ break;
+
+]b4_locations_if([
/* Muck with the stack to setup for yylloc. */
yystack.push (0, null, yylloc);
yystack.push (0, null, yyerrloc);
/* Accept. */
case YYACCEPT:
- return true;
+ ]b4_push_if([this.push_parse_initialized = false; return YYACCEPT;],
+ [return true;])[
/* Abort. */
case YYABORT:
- return false;
+ ]b4_push_if([this.push_parse_initialized = false; return YYABORT;],
+ [return false;])[
}
+}
+]b4_push_if([[
+ boolean push_parse_initialized = false;
+
+ /**
+ * (Re-)Initialize the state of the push parser.
+ */
+ public void push_parse_initialize()
+ {
+ /* Lookahead and lookahead in internal form. */
+ this.yychar = yyempty_;
+ this.yytoken = 0;
+
+ /* State. */
+ this.yyn = 0;
+ this.yylen = 0;
+ this.yystate = 0;
+ this.yystack = new YYStack ();
+ this.label = YYNEWSTATE;
+
+ /* Error handling. */
+ this.yynerrs_ = 0;
+ ]b4_locations_if([/* The location where the error started. */
+ this.yyerrloc = null;
+ this.yylloc = new b4_location_type (null, null);])[
+
+ /* Semantic value of the lookahead. */
+ this.yylval = null;
+
+ yystack.push (this.yystate, this.yylval]b4_locations_if([, this.yylloc])[);
+
+ this.push_parse_initialized = true;
+
+ }
+]b4_locations_if([
+ /**
+ * Push parse given input from an external lexer.
+ *
+ * @@param yylextoken current token
+ * @@param yylexval current lval
+ * @@param yyylexpos current position
+ *
+ * @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
+ */
+ public int push_parse (int yylextoken, b4_yystype yylexval, b4_position_type yylexpos)
+ b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])
+ {
+ return push_parse (yylextoken, yylexval, new b4_location_type (yylexpos));
+ }
+])[]])
+
+b4_both_if([[
+ /**
+ * Parse input from the scanner that was specified at object construction
+ * time. Return whether the end of the input was reached successfully.
+ * This version of parse () is defined only when api.push-push=both.
+ *
+ * @@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_list2([b4_lex_throws], [b4_throws])])[
+ {
+ if (yylexer == null)
+ throw new NullPointerException("Null Lexer");
+ int status;
+ do {
+ int token = yylexer.yylex();
+ ]b4_yystype[ lval = yylexer.getLVal();
+]b4_locations_if([dnl
+ b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (),
+ yylexer.getEndPos ());])[
+ ]b4_locations_if([status = push_parse(token,lval,yyloc);],[
+ status = push_parse(token,lval);])[
+ } while (status == YYPUSH_MORE);
+ return (status == YYACCEPT);
}
+]])[
// Generate an error message.
private String yysyntax_error (int yystate, int tok)
{]b4_error_verbose_if([[
if (yyErrorVerbose)
{
- int yyn = yypact_[yystate];
- if (yypact_ninf_ < yyn && yyn <= yylast_)
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action,
+ then the only way this function was invoked is if the
+ default action is an error action. In that case, don't
+ check for expected tokens because there are none.
+ - The only way there can be no lookahead present (in tok) is
+ if this state is a consistent state with a default action.
+ Thus, detecting the absence of a lookahead is sufficient to
+ determine that there is no unexpected or expected token to
+ report. In that case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this
+ state is a consistent state with a default action. There
+ might have been a previous inconsistent state, consistent
+ state with a non-default action, or user semantic action
+ that manipulated yychar. (However, yychar is currently out
+ of scope during semantic actions.)
+ - Of course, the expected token list depends on states to
+ have correct lookahead information, and it depends on the
+ parser not to perform extra reductions after fetching a
+ lookahead from the scanner and before detecting a syntax
+ error. Thus, state merging (from LALR or IELR) and default
+ reductions corrupt the expected token list. However, the
+ list is correct for canonical LR with one exception: it
+ will still contain any token that will not be accepted due
+ to an error action in a later state.
+ */
+ if (tok != yyempty_)
{
- StringBuffer res;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. In other words, skip the first -YYN actions for this
- state because they are default actions. */
- 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_
- && !yy_table_value_is_error_ (yytable_[x + yyn]))
- ++count;
-
- // FIXME: This method of building the message is not compatible
- // with internationalization.
- res = new StringBuffer ("syntax error, unexpected ");
+ /* FIXME: This method of building the message is not compatible
+ with internationalization. */
+ StringBuffer res =
+ new StringBuffer ("syntax error, unexpected ");
res.append (yytnamerr_ (yytname_[tok]));
- if (count < 5)
+ int yyn = yypact_[yystate];
+ if (!yy_pact_value_is_default_ (yyn))
{
- count = 0;
+ /* Start YYX at -YYN if negative to avoid negative
+ indexes in YYCHECK. In other words, skip the first
+ -YYN actions for this state because they are default
+ actions. */
+ 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_
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
- {
- res.append (count++ == 0 ? ", expecting " : " or ");
- res.append (yytnamerr_ (yytname_[x]));
- }
+ ++count;
+ if (count < 5)
+ {
+ count = 0;
+ for (int x = yyxbegin; x < yyxend; ++x)
+ if (yycheck_[x + yyn] == x && x != yyterror_
+ && !yy_table_value_is_error_ (yytable_[x + yyn]))
+ {
+ res.append (count++ == 0 ? ", expecting " : " or ");
+ res.append (yytnamerr_ (yytname_[x]));
+ }
+ }
}
return res.toString ();
}
}
/**
- * Whether the given <code>yytable_</code> value indicates a syntax error.
- * @@param yyvalue the value to check
+ * Whether the given <code>yytable_</code>
+ * value indicates a syntax error.
+ * @@param yyvalue the value to check
*/
private static boolean yy_table_value_is_error_ (int yyvalue)
{
]b4_parser_tables_define[
]b4_integral_parser_table_define([token_number], [b4_toknum],
- [TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding
- to YYLEX-NUM.])[
+ [[YYTOKEN_NUMBER[YYLEX-NUM] -- Internal symbol number corresponding
+ to YYLEX-NUM.]])[
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at \a yyntokens_, nonterminals. */
]b4_typed_parser_table_define([String], [tname], [b4_tname])[
]b4_integral_parser_table_define([rline], [b4_rline],
- [YYRLINE[YYN] -- Source line where rule number YYN was defined.])[
+ [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
+
// Report on the debug stream that the rule yyrule is going to be reduced.
private void yy_reduce_print (int yyrule, YYStack yystack)
/* The symbols being reduced. */
for (int yyi = 0; yyi < yynrhs; yyi++)
yy_symbol_print (" $" + (yyi + 1) + " =",
- yystos_[yystack.stateAt(yyi + 1 - yynrhs)],
+ yystos_[yystack.stateAt(yynrhs - (yyi + 1))],
]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([,
b4_rhs_location(yynrhs, yyi + 1)])[);
}
}
b4_epilogue[]dnl
-m4_divert_pop(0)dnl
+b4_output_end()