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])
+# 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-2013])
{
]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 ();
]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
/**
* 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;
-
+ ]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], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl
/* User initialization code. */
b4_user_initial_action
-b4_dollar_popdef])[]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. */
{
/* 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. */
+ /* Pop the current state because it cannot handle the
+ * error token. */
if (yystack.height == 0)
- return false;
+ ]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)
*/
if (tok != yyempty_)
{
- // FIXME: This method of building the message is not compatible
- // with internationalization.
+ /* FIXME: This method of building the message is not compatible
+ with internationalization. */
StringBuffer res =
new StringBuffer ("syntax error, unexpected ");
res.append (yytnamerr_ (yytname_[tok]));
}
/**
- * 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_integral_parser_table_define([rline], [b4_rline],
[[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)
{