xref: /aosp_15_r20/prebuilts/build-tools/common/bison/skeletons/lalr1.d (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker # D skeleton for Bison -*- autoconf -*-
2*cda5da8dSAndroid Build Coastguard Worker 
3*cda5da8dSAndroid Build Coastguard Worker # Copyright (C) 2007-2012, 2019-2021 Free Software Foundation, Inc.
4*cda5da8dSAndroid Build Coastguard Worker 
5*cda5da8dSAndroid Build Coastguard Worker # This program is free software: you can redistribute it and/or modify
6*cda5da8dSAndroid Build Coastguard Worker # it under the terms of the GNU General Public License as published by
7*cda5da8dSAndroid Build Coastguard Worker # the Free Software Foundation, either version 3 of the License, or
8*cda5da8dSAndroid Build Coastguard Worker # (at your option) any later version.
9*cda5da8dSAndroid Build Coastguard Worker #
10*cda5da8dSAndroid Build Coastguard Worker # This program is distributed in the hope that it will be useful,
11*cda5da8dSAndroid Build Coastguard Worker # but WITHOUT ANY WARRANTY; without even the implied warranty of
12*cda5da8dSAndroid Build Coastguard Worker # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*cda5da8dSAndroid Build Coastguard Worker # GNU General Public License for more details.
14*cda5da8dSAndroid Build Coastguard Worker #
15*cda5da8dSAndroid Build Coastguard Worker # You should have received a copy of the GNU General Public License
16*cda5da8dSAndroid Build Coastguard Worker # along with this program.  If not, see <https://www.gnu.org/licenses/>.
17*cda5da8dSAndroid Build Coastguard Worker 
18*cda5da8dSAndroid Build Coastguard Worker m4_include(b4_skeletonsdir/[d.m4])
19*cda5da8dSAndroid Build Coastguard Worker 
20*cda5da8dSAndroid Build Coastguard Worker b4_header_if([b4_complain([%header/%defines does not make sense in D])])
21*cda5da8dSAndroid Build Coastguard Worker 
22*cda5da8dSAndroid Build Coastguard Worker # parse.lac
23*cda5da8dSAndroid Build Coastguard Worker b4_percent_define_default([[parse.lac]], [[none]])
24*cda5da8dSAndroid Build Coastguard Worker b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]])
25*cda5da8dSAndroid Build Coastguard Worker b4_define_flag_if([lac])
26*cda5da8dSAndroid Build Coastguard Worker m4_define([b4_lac_flag],
27*cda5da8dSAndroid Build Coastguard Worker           [m4_if(b4_percent_define_get([[parse.lac]]),
28*cda5da8dSAndroid Build Coastguard Worker                  [none], [[0]], [[1]])])
29*cda5da8dSAndroid Build Coastguard Worker 
30*cda5da8dSAndroid Build Coastguard Worker 
31*cda5da8dSAndroid Build Coastguard Worker ## --------------- ##
32*cda5da8dSAndroid Build Coastguard Worker ## api.push-pull.  ##
33*cda5da8dSAndroid Build Coastguard Worker ## --------------- ##
34*cda5da8dSAndroid Build Coastguard Worker 
35*cda5da8dSAndroid Build Coastguard Worker b4_percent_define_default([[api.push-pull]], [[pull]])
36*cda5da8dSAndroid Build Coastguard Worker b4_percent_define_check_values([[[[api.push-pull]],
37*cda5da8dSAndroid Build Coastguard Worker                                  [[pull]], [[push]], [[both]]]])
38*cda5da8dSAndroid Build Coastguard Worker 
39*cda5da8dSAndroid Build Coastguard Worker # Define m4 conditional macros that encode the value
40*cda5da8dSAndroid Build Coastguard Worker # of the api.push-pull flag.
41*cda5da8dSAndroid Build Coastguard Worker b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
42*cda5da8dSAndroid Build Coastguard Worker b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
43*cda5da8dSAndroid Build Coastguard Worker m4_case(b4_percent_define_get([[api.push-pull]]),
44*cda5da8dSAndroid Build Coastguard Worker         [pull], [m4_define([b4_push_flag], [[0]])],
45*cda5da8dSAndroid Build Coastguard Worker         [push], [m4_define([b4_pull_flag], [[0]])])
46*cda5da8dSAndroid Build Coastguard Worker 
47*cda5da8dSAndroid Build Coastguard Worker # Define a macro to be true when api.push-pull has the value "both".
48*cda5da8dSAndroid Build Coastguard Worker m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])])
49*cda5da8dSAndroid Build Coastguard Worker 
50*cda5da8dSAndroid Build Coastguard Worker # Handle BISON_USE_PUSH_FOR_PULL for the test suite.  So that push parsing
51*cda5da8dSAndroid Build Coastguard Worker # tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
52*cda5da8dSAndroid Build Coastguard Worker # behavior of Bison at all when push parsing is already requested.
53*cda5da8dSAndroid Build Coastguard Worker b4_define_flag_if([use_push_for_pull])
54*cda5da8dSAndroid Build Coastguard Worker b4_use_push_for_pull_if([
55*cda5da8dSAndroid Build Coastguard Worker   b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
56*cda5da8dSAndroid Build Coastguard Worker              [m4_define([b4_push_flag], [[1]])])])
57*cda5da8dSAndroid Build Coastguard Worker 
58*cda5da8dSAndroid Build Coastguard Worker 
59*cda5da8dSAndroid Build Coastguard Worker # Define a macro to encapsulate the parse state variables.  This
60*cda5da8dSAndroid Build Coastguard Worker # allows them to be defined either in parse() when doing pull parsing,
61*cda5da8dSAndroid Build Coastguard Worker # or as class instance variable when doing push parsing.
62*cda5da8dSAndroid Build Coastguard Worker b4_output_begin([b4_parser_file_name])
63*cda5da8dSAndroid Build Coastguard Worker b4_copyright([Skeleton implementation for Bison LALR(1) parsers in D],
64*cda5da8dSAndroid Build Coastguard Worker              [2007-2012, 2019-2021])[
65*cda5da8dSAndroid Build Coastguard Worker ]b4_disclaimer[
66*cda5da8dSAndroid Build Coastguard Worker ]b4_percent_define_ifdef([package], [module b4_percent_define_get([package]);
67*cda5da8dSAndroid Build Coastguard Worker ])[
68*cda5da8dSAndroid Build Coastguard Worker version(D_Version2) {
69*cda5da8dSAndroid Build Coastguard Worker } else {
70*cda5da8dSAndroid Build Coastguard Worker   static assert(false, "need compiler for D Version 2");
71*cda5da8dSAndroid Build Coastguard Worker }
72*cda5da8dSAndroid Build Coastguard Worker 
73*cda5da8dSAndroid Build Coastguard Worker ]b4_user_pre_prologue[
74*cda5da8dSAndroid Build Coastguard Worker ]b4_user_post_prologue[
75*cda5da8dSAndroid Build Coastguard Worker ]b4_percent_code_get([[imports]])[
76*cda5da8dSAndroid Build Coastguard Worker import std.format;
77*cda5da8dSAndroid Build Coastguard Worker import std.conv;
78*cda5da8dSAndroid Build Coastguard Worker 
79*cda5da8dSAndroid Build Coastguard Worker /**
80*cda5da8dSAndroid Build Coastguard Worker  * Handle error message internationalisation.
81*cda5da8dSAndroid Build Coastguard Worker  */
82*cda5da8dSAndroid Build Coastguard Worker static if (!is(typeof(YY_))) {
83*cda5da8dSAndroid Build Coastguard Worker   version(YYENABLE_NLS)
84*cda5da8dSAndroid Build Coastguard Worker   {
85*cda5da8dSAndroid Build Coastguard Worker     version(ENABLE_NLS)
86*cda5da8dSAndroid Build Coastguard Worker     {
87*cda5da8dSAndroid Build Coastguard Worker       extern(C) char* dgettext(const char*, const char*);
88*cda5da8dSAndroid Build Coastguard Worker       string YY_(const char* s)
89*cda5da8dSAndroid Build Coastguard Worker       {
90*cda5da8dSAndroid Build Coastguard Worker         return to!string(dgettext("bison-runtime", s));
91*cda5da8dSAndroid Build Coastguard Worker       }
92*cda5da8dSAndroid Build Coastguard Worker     }
93*cda5da8dSAndroid Build Coastguard Worker   }
94*cda5da8dSAndroid Build Coastguard Worker   static if (!is(typeof(YY_)))
95*cda5da8dSAndroid Build Coastguard Worker   {
96*cda5da8dSAndroid Build Coastguard Worker     pragma(inline, true)
97*cda5da8dSAndroid Build Coastguard Worker     string YY_(string msg) { return msg; }
98*cda5da8dSAndroid Build Coastguard Worker   }
99*cda5da8dSAndroid Build Coastguard Worker }
100*cda5da8dSAndroid Build Coastguard Worker 
101*cda5da8dSAndroid Build Coastguard Worker /**
102*cda5da8dSAndroid Build Coastguard Worker  * A Bison parser, automatically generated from <tt>]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[</tt>.
103*cda5da8dSAndroid Build Coastguard Worker  *
104*cda5da8dSAndroid Build Coastguard Worker  * @@author LALR (1) parser skeleton written by Paolo Bonzini.
105*cda5da8dSAndroid Build Coastguard Worker  * Port to D language was done by Oliver Mangold.
106*cda5da8dSAndroid Build Coastguard Worker  */
107*cda5da8dSAndroid Build Coastguard Worker 
108*cda5da8dSAndroid Build Coastguard Worker /**
109*cda5da8dSAndroid Build Coastguard Worker  * Communication interface between the scanner and the Bison-generated
110*cda5da8dSAndroid Build Coastguard Worker  * parser <tt>]b4_parser_class[</tt>.
111*cda5da8dSAndroid Build Coastguard Worker  */
112*cda5da8dSAndroid Build Coastguard Worker public interface Lexer
113*cda5da8dSAndroid Build Coastguard Worker {
114*cda5da8dSAndroid Build Coastguard Worker   /**
115*cda5da8dSAndroid Build Coastguard Worker    * Entry point for the scanner.  Returns the token identifier corresponding
116*cda5da8dSAndroid Build Coastguard Worker    * to the next token and prepares to return the semantic value
117*cda5da8dSAndroid Build Coastguard Worker    * ]b4_locations_if([and beginning/ending positions ])[of the token.
118*cda5da8dSAndroid Build Coastguard Worker    * @@return the token identifier corresponding to the next token. */
119*cda5da8dSAndroid Build Coastguard Worker   Symbol yylex ();
120*cda5da8dSAndroid Build Coastguard Worker 
121*cda5da8dSAndroid Build Coastguard Worker   /**
122*cda5da8dSAndroid Build Coastguard Worker    * Entry point for error reporting.  Emits an error
123*cda5da8dSAndroid Build Coastguard Worker    * ]b4_locations_if([referring to the given location ])[in a user-defined way.
124*cda5da8dSAndroid Build Coastguard Worker    *]b4_locations_if([[
125*cda5da8dSAndroid Build Coastguard Worker    * @@param loc The location of the element to which the
126*cda5da8dSAndroid Build Coastguard Worker    *                error message is related]])[
127*cda5da8dSAndroid Build Coastguard Worker    * @@param s The string for the error message.  */
128*cda5da8dSAndroid Build Coastguard Worker    void yyerror (]b4_locations_if([[const Location loc, ]])[string s);
129*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_error_bmatch([custom], [[
130*cda5da8dSAndroid Build Coastguard Worker   /**
131*cda5da8dSAndroid Build Coastguard Worker    * Build and emit a "syntax error" message in a user-defined way.
132*cda5da8dSAndroid Build Coastguard Worker    *
133*cda5da8dSAndroid Build Coastguard Worker    * @@param ctx  The context of the error.
134*cda5da8dSAndroid Build Coastguard Worker    */
135*cda5da8dSAndroid Build Coastguard Worker   void reportSyntaxError(]b4_parser_class[.Context ctx);
136*cda5da8dSAndroid Build Coastguard Worker ]])[
137*cda5da8dSAndroid Build Coastguard Worker }
138*cda5da8dSAndroid Build Coastguard Worker 
139*cda5da8dSAndroid Build Coastguard Worker ]b4_public_types_declare[
140*cda5da8dSAndroid Build Coastguard Worker 
141*cda5da8dSAndroid Build Coastguard Worker ]b4_locations_if([b4_position_type_if([[
142*cda5da8dSAndroid Build Coastguard Worker static assert(__traits(compiles,
143*cda5da8dSAndroid Build Coastguard Worker               (new Position[1])[0]=(new Position[1])[0]),
144*cda5da8dSAndroid Build Coastguard Worker               "struct/class Position must be default-constructible "
145*cda5da8dSAndroid Build Coastguard Worker               "and assignable");
146*cda5da8dSAndroid Build Coastguard Worker static assert(__traits(compiles, (new string[1])[0]=(new Position).toString()),
147*cda5da8dSAndroid Build Coastguard Worker               "error: struct/class Position must have toString method");
148*cda5da8dSAndroid Build Coastguard Worker ]], [[
149*cda5da8dSAndroid Build Coastguard Worker   /**
150*cda5da8dSAndroid Build Coastguard Worker    * A struct denoting a point in the input.*/
151*cda5da8dSAndroid Build Coastguard Worker public struct ]b4_position_type[ {
152*cda5da8dSAndroid Build Coastguard Worker 
153*cda5da8dSAndroid Build Coastguard Worker   /** The column index within the line of input.  */
154*cda5da8dSAndroid Build Coastguard Worker   public int column = 1;
155*cda5da8dSAndroid Build Coastguard Worker   /** The line number within an input file.  */
156*cda5da8dSAndroid Build Coastguard Worker   public int line = 1;
157*cda5da8dSAndroid Build Coastguard Worker   /** The name of the input file.  */
158*cda5da8dSAndroid Build Coastguard Worker   public string filename = null;
159*cda5da8dSAndroid Build Coastguard Worker 
160*cda5da8dSAndroid Build Coastguard Worker   /**
161*cda5da8dSAndroid Build Coastguard Worker    * A string representation of the position. */
162*cda5da8dSAndroid Build Coastguard Worker   public string toString() const {
163*cda5da8dSAndroid Build Coastguard Worker     if (filename)
164*cda5da8dSAndroid Build Coastguard Worker       return format("%s:%d.%d", filename, line, column);
165*cda5da8dSAndroid Build Coastguard Worker     else
166*cda5da8dSAndroid Build Coastguard Worker       return format("%d.%d", line, column);
167*cda5da8dSAndroid Build Coastguard Worker   }
168*cda5da8dSAndroid Build Coastguard Worker }
169*cda5da8dSAndroid Build Coastguard Worker ]])b4_location_type_if([[
170*cda5da8dSAndroid Build Coastguard Worker static assert(__traits(compiles, (new Location((new Position[1])[0]))) &&
171*cda5da8dSAndroid Build Coastguard Worker               __traits(compiles, (new Location((new Position[1])[0], (new Position[1])[0]))),
172*cda5da8dSAndroid Build Coastguard Worker               "error: struct/class Location must have "
173*cda5da8dSAndroid Build Coastguard Worker               "default constructor and constructors this(Position) and this(Position, Position).");
174*cda5da8dSAndroid Build Coastguard Worker static assert(__traits(compiles, (new Location[1])[0].begin=(new Location[1])[0].begin) &&
175*cda5da8dSAndroid Build Coastguard Worker               __traits(compiles, (new Location[1])[0].begin=(new Location[1])[0].end) &&
176*cda5da8dSAndroid Build Coastguard Worker               __traits(compiles, (new Location[1])[0].end=(new Location[1])[0].begin) &&
177*cda5da8dSAndroid Build Coastguard Worker               __traits(compiles, (new Location[1])[0].end=(new Location[1])[0].end),
178*cda5da8dSAndroid Build Coastguard Worker               "error: struct/class Location must have assignment-compatible "
179*cda5da8dSAndroid Build Coastguard Worker               "members/properties 'begin' and 'end'.");
180*cda5da8dSAndroid Build Coastguard Worker static assert(__traits(compiles, (new string[1])[0]=(new Location[1])[0].toString()),
181*cda5da8dSAndroid Build Coastguard Worker               "error: struct/class Location must have toString method.");
182*cda5da8dSAndroid Build Coastguard Worker 
183*cda5da8dSAndroid Build Coastguard Worker private immutable bool yy_location_is_class = !__traits(compiles, *(new Location((new Position[1])[0])));]], [[
184*cda5da8dSAndroid Build Coastguard Worker /**
185*cda5da8dSAndroid Build Coastguard Worker  * A struct defining a pair of positions.  Positions, defined by the
186*cda5da8dSAndroid Build Coastguard Worker  * <code>Position</code> struct, denote a point in the input.
187*cda5da8dSAndroid Build Coastguard Worker  * Locations represent a part of the input through the beginning
188*cda5da8dSAndroid Build Coastguard Worker  * and ending positions.  */
189*cda5da8dSAndroid Build Coastguard Worker public struct ]b4_location_type[
190*cda5da8dSAndroid Build Coastguard Worker {
191*cda5da8dSAndroid Build Coastguard Worker   /** The first, inclusive, position in the range.  */
192*cda5da8dSAndroid Build Coastguard Worker   public Position begin;
193*cda5da8dSAndroid Build Coastguard Worker 
194*cda5da8dSAndroid Build Coastguard Worker   /** The first position beyond the range.  */
195*cda5da8dSAndroid Build Coastguard Worker   public Position end;
196*cda5da8dSAndroid Build Coastguard Worker 
197*cda5da8dSAndroid Build Coastguard Worker   /**
198*cda5da8dSAndroid Build Coastguard Worker    * Create a <code>Location</code> denoting an empty range located at
199*cda5da8dSAndroid Build Coastguard Worker    * a given point.
200*cda5da8dSAndroid Build Coastguard Worker    * @@param loc The position at which the range is anchored.  */
201*cda5da8dSAndroid Build Coastguard Worker   public this(Position loc)
202*cda5da8dSAndroid Build Coastguard Worker   {
203*cda5da8dSAndroid Build Coastguard Worker     this.begin = this.end = loc;
204*cda5da8dSAndroid Build Coastguard Worker   }
205*cda5da8dSAndroid Build Coastguard Worker 
206*cda5da8dSAndroid Build Coastguard Worker   /**
207*cda5da8dSAndroid Build Coastguard Worker    * Create a <code>Location</code> from the endpoints of the range.
208*cda5da8dSAndroid Build Coastguard Worker    * @@param begin The first position included in the range.
209*cda5da8dSAndroid Build Coastguard Worker    * @@param end   The first position beyond the range.  */
210*cda5da8dSAndroid Build Coastguard Worker   public this(Position begin, Position end)
211*cda5da8dSAndroid Build Coastguard Worker   {
212*cda5da8dSAndroid Build Coastguard Worker     this.begin = begin;
213*cda5da8dSAndroid Build Coastguard Worker     this.end = end;
214*cda5da8dSAndroid Build Coastguard Worker   }
215*cda5da8dSAndroid Build Coastguard Worker 
216*cda5da8dSAndroid Build Coastguard Worker   /**
217*cda5da8dSAndroid Build Coastguard Worker    * Reset initial location to final location.
218*cda5da8dSAndroid Build Coastguard Worker    */
219*cda5da8dSAndroid Build Coastguard Worker   public void step()
220*cda5da8dSAndroid Build Coastguard Worker   {
221*cda5da8dSAndroid Build Coastguard Worker     this.begin = this.end;
222*cda5da8dSAndroid Build Coastguard Worker   }
223*cda5da8dSAndroid Build Coastguard Worker 
224*cda5da8dSAndroid Build Coastguard Worker   /**
225*cda5da8dSAndroid Build Coastguard Worker    * A representation of the location.
226*cda5da8dSAndroid Build Coastguard Worker    */
227*cda5da8dSAndroid Build Coastguard Worker   public string toString() const
228*cda5da8dSAndroid Build Coastguard Worker   {
229*cda5da8dSAndroid Build Coastguard Worker     auto end_col = 0 < end.column ? end.column - 1 : 0;
230*cda5da8dSAndroid Build Coastguard Worker     auto res = begin.toString ();
231*cda5da8dSAndroid Build Coastguard Worker     if (end.filename && begin.filename != end.filename)
232*cda5da8dSAndroid Build Coastguard Worker       res ~= "-" ~ format("%s:%d.%d", end.filename, end.line, end_col);
233*cda5da8dSAndroid Build Coastguard Worker     else if (begin.line < end.line)
234*cda5da8dSAndroid Build Coastguard Worker       res ~= "-" ~ format("%d.%d", end.line, end_col);
235*cda5da8dSAndroid Build Coastguard Worker     else if (begin.column < end_col)
236*cda5da8dSAndroid Build Coastguard Worker       res ~= "-" ~ format("%d", end_col);
237*cda5da8dSAndroid Build Coastguard Worker     return res;
238*cda5da8dSAndroid Build Coastguard Worker   }
239*cda5da8dSAndroid Build Coastguard Worker }
240*cda5da8dSAndroid Build Coastguard Worker 
241*cda5da8dSAndroid Build Coastguard Worker private immutable bool yy_location_is_class = false;
242*cda5da8dSAndroid Build Coastguard Worker 
243*cda5da8dSAndroid Build Coastguard Worker ]])])[]b4_value_type_setup[]m4_ifdef([b4_user_union_members], [private union YYSemanticType
244*cda5da8dSAndroid Build Coastguard Worker {
245*cda5da8dSAndroid Build Coastguard Worker b4_user_union_members
246*cda5da8dSAndroid Build Coastguard Worker };],
247*cda5da8dSAndroid Build Coastguard Worker [m4_if(b4_tag_seen_flag, 0,
248*cda5da8dSAndroid Build Coastguard Worker [[private alias int YYSemanticType;]])])[
249*cda5da8dSAndroid Build Coastguard Worker ]b4_token_enums[
250*cda5da8dSAndroid Build Coastguard Worker ]b4_parser_class_declaration[
251*cda5da8dSAndroid Build Coastguard Worker {
252*cda5da8dSAndroid Build Coastguard Worker   ]b4_identification[
253*cda5da8dSAndroid Build Coastguard Worker 
254*cda5da8dSAndroid Build Coastguard Worker ]b4_declare_symbol_enum[
255*cda5da8dSAndroid Build Coastguard Worker 
256*cda5da8dSAndroid Build Coastguard Worker ]b4_locations_if([[
257*cda5da8dSAndroid Build Coastguard Worker   private final Location yylloc_from_stack (ref YYStack rhs, int n)
258*cda5da8dSAndroid Build Coastguard Worker   {
259*cda5da8dSAndroid Build Coastguard Worker     static if (yy_location_is_class) {
260*cda5da8dSAndroid Build Coastguard Worker       if (n > 0)
261*cda5da8dSAndroid Build Coastguard Worker         return new Location (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
262*cda5da8dSAndroid Build Coastguard Worker       else
263*cda5da8dSAndroid Build Coastguard Worker         return new Location (rhs.locationAt (0).end);
264*cda5da8dSAndroid Build Coastguard Worker     } else {
265*cda5da8dSAndroid Build Coastguard Worker       if (n > 0)
266*cda5da8dSAndroid Build Coastguard Worker         return Location (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
267*cda5da8dSAndroid Build Coastguard Worker       else
268*cda5da8dSAndroid Build Coastguard Worker         return Location (rhs.locationAt (0).end);
269*cda5da8dSAndroid Build Coastguard Worker     }
270*cda5da8dSAndroid Build Coastguard Worker   }]])[
271*cda5da8dSAndroid Build Coastguard Worker 
272*cda5da8dSAndroid Build Coastguard Worker ]b4_lexer_if([[  private class YYLexer implements Lexer {
273*cda5da8dSAndroid Build Coastguard Worker ]b4_percent_code_get([[lexer]])[
274*cda5da8dSAndroid Build Coastguard Worker   }
275*cda5da8dSAndroid Build Coastguard Worker ]])[
276*cda5da8dSAndroid Build Coastguard Worker   /** The object doing lexical analysis for us.  */
277*cda5da8dSAndroid Build Coastguard Worker   private Lexer yylexer;
278*cda5da8dSAndroid Build Coastguard Worker 
279*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_param_vars[
280*cda5da8dSAndroid Build Coastguard Worker 
281*cda5da8dSAndroid Build Coastguard Worker ]b4_lexer_if([[
282*cda5da8dSAndroid Build Coastguard Worker   /**
283*cda5da8dSAndroid Build Coastguard Worker    * Instantiate the Bison-generated parser.
284*cda5da8dSAndroid Build Coastguard Worker    */
285*cda5da8dSAndroid Build Coastguard Worker   public this] (b4_parse_param_decl([b4_lex_param_decl])[) {
286*cda5da8dSAndroid Build Coastguard Worker ]b4_percent_code_get([[init]])[]b4_lac_if([[
287*cda5da8dSAndroid Build Coastguard Worker     this.yylacStack = new int[];
288*cda5da8dSAndroid Build Coastguard Worker     this.yylacEstablished = false;]])[
289*cda5da8dSAndroid Build Coastguard Worker     this (new YYLexer(]b4_lex_param_call[));
290*cda5da8dSAndroid Build Coastguard Worker   }
291*cda5da8dSAndroid Build Coastguard Worker ]])[
292*cda5da8dSAndroid Build Coastguard Worker 
293*cda5da8dSAndroid Build Coastguard Worker   /**
294*cda5da8dSAndroid Build Coastguard Worker    * Instantiate the Bison-generated parser.
295*cda5da8dSAndroid Build Coastguard Worker    * @@param yylexer The scanner that will supply tokens to the parser.
296*cda5da8dSAndroid Build Coastguard Worker    */
297*cda5da8dSAndroid Build Coastguard Worker   ]b4_lexer_if([[protected]], [[public]]) [this (]b4_parse_param_decl([[Lexer yylexer]])[) {
298*cda5da8dSAndroid Build Coastguard Worker     this.yylexer = yylexer;]b4_parse_trace_if([[
299*cda5da8dSAndroid Build Coastguard Worker     this.yyDebugStream = stderr;]])[
300*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_param_cons[
301*cda5da8dSAndroid Build Coastguard Worker   }
302*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_trace_if([[
303*cda5da8dSAndroid Build Coastguard Worker   import std.stdio;
304*cda5da8dSAndroid Build Coastguard Worker   private File yyDebugStream;
305*cda5da8dSAndroid Build Coastguard Worker 
306*cda5da8dSAndroid Build Coastguard Worker   /**
307*cda5da8dSAndroid Build Coastguard Worker    * The <tt>File</tt> on which the debugging output is
308*cda5da8dSAndroid Build Coastguard Worker    * printed.
309*cda5da8dSAndroid Build Coastguard Worker    */
310*cda5da8dSAndroid Build Coastguard Worker   public File getDebugStream () { return yyDebugStream; }
311*cda5da8dSAndroid Build Coastguard Worker 
312*cda5da8dSAndroid Build Coastguard Worker   /**
313*cda5da8dSAndroid Build Coastguard Worker    * Set the <tt>std.File</tt> on which the debug output is printed.
314*cda5da8dSAndroid Build Coastguard Worker    * @@param s The stream that is used for debugging output.
315*cda5da8dSAndroid Build Coastguard Worker    */
316*cda5da8dSAndroid Build Coastguard Worker   public final void setDebugStream(File s) { yyDebugStream = s; }
317*cda5da8dSAndroid Build Coastguard Worker 
318*cda5da8dSAndroid Build Coastguard Worker   private int yydebug = 0;
319*cda5da8dSAndroid Build Coastguard Worker 
320*cda5da8dSAndroid Build Coastguard Worker   /**
321*cda5da8dSAndroid Build Coastguard Worker    * Answer the verbosity of the debugging output; 0 means that all kinds of
322*cda5da8dSAndroid Build Coastguard Worker    * output from the parser are suppressed.
323*cda5da8dSAndroid Build Coastguard Worker    */
324*cda5da8dSAndroid Build Coastguard Worker   public final int getDebugLevel() { return yydebug; }
325*cda5da8dSAndroid Build Coastguard Worker 
326*cda5da8dSAndroid Build Coastguard Worker   /**
327*cda5da8dSAndroid Build Coastguard Worker    * Set the verbosity of the debugging output; 0 means that all kinds of
328*cda5da8dSAndroid Build Coastguard Worker    * output from the parser are suppressed.
329*cda5da8dSAndroid Build Coastguard Worker    * @@param level The verbosity level for debugging output.
330*cda5da8dSAndroid Build Coastguard Worker    */
331*cda5da8dSAndroid Build Coastguard Worker   public final void setDebugLevel(int level) { yydebug = level; }
332*cda5da8dSAndroid Build Coastguard Worker 
333*cda5da8dSAndroid Build Coastguard Worker   protected final void yycdebug (string s) {
334*cda5da8dSAndroid Build Coastguard Worker     if (0 < yydebug)
335*cda5da8dSAndroid Build Coastguard Worker       yyDebugStream.write (s);
336*cda5da8dSAndroid Build Coastguard Worker   }
337*cda5da8dSAndroid Build Coastguard Worker 
338*cda5da8dSAndroid Build Coastguard Worker   protected final void yycdebugln (string s) {
339*cda5da8dSAndroid Build Coastguard Worker     if (0 < yydebug)
340*cda5da8dSAndroid Build Coastguard Worker       yyDebugStream.writeln (s);
341*cda5da8dSAndroid Build Coastguard Worker   }
342*cda5da8dSAndroid Build Coastguard Worker ]])[
343*cda5da8dSAndroid Build Coastguard Worker   private final ]b4_parser_class[.Symbol yylex () {
344*cda5da8dSAndroid Build Coastguard Worker     return yylexer.yylex ();
345*cda5da8dSAndroid Build Coastguard Worker   }
346*cda5da8dSAndroid Build Coastguard Worker 
347*cda5da8dSAndroid Build Coastguard Worker   protected final void yyerror (]b4_locations_if([[const Location loc, ]])[string s) {
348*cda5da8dSAndroid Build Coastguard Worker     yylexer.yyerror (]b4_locations_if([loc, ])[s);
349*cda5da8dSAndroid Build Coastguard Worker   }
350*cda5da8dSAndroid Build Coastguard Worker 
351*cda5da8dSAndroid Build Coastguard Worker   /**
352*cda5da8dSAndroid Build Coastguard Worker    * The number of syntax errors so far.
353*cda5da8dSAndroid Build Coastguard Worker    */
354*cda5da8dSAndroid Build Coastguard Worker   public int numberOfErrors() const { return yynerrs_; }
355*cda5da8dSAndroid Build Coastguard Worker   private int yynerrs_ = 0;
356*cda5da8dSAndroid Build Coastguard Worker 
357*cda5da8dSAndroid Build Coastguard Worker   /**
358*cda5da8dSAndroid Build Coastguard Worker    * Returned by a Bison action in order to stop the parsing process and
359*cda5da8dSAndroid Build Coastguard Worker    * return success (<tt>true</tt>).  */
360*cda5da8dSAndroid Build Coastguard Worker   public static immutable int YYACCEPT = 0;
361*cda5da8dSAndroid Build Coastguard Worker 
362*cda5da8dSAndroid Build Coastguard Worker   /**
363*cda5da8dSAndroid Build Coastguard Worker    * Returned by a Bison action in order to stop the parsing process and
364*cda5da8dSAndroid Build Coastguard Worker    * return failure (<tt>false</tt>).  */
365*cda5da8dSAndroid Build Coastguard Worker   public static immutable int YYABORT = 1;
366*cda5da8dSAndroid Build Coastguard Worker ]b4_push_if([
367*cda5da8dSAndroid Build Coastguard Worker   /**
368*cda5da8dSAndroid Build Coastguard Worker    * Returned by a Bison action in order to request a new token.
369*cda5da8dSAndroid Build Coastguard Worker    */
370*cda5da8dSAndroid Build Coastguard Worker   public static immutable int YYPUSH_MORE = 4;])[
371*cda5da8dSAndroid Build Coastguard Worker 
372*cda5da8dSAndroid Build Coastguard Worker   /**
373*cda5da8dSAndroid Build Coastguard Worker    * Returned by a Bison action in order to start error recovery without
374*cda5da8dSAndroid Build Coastguard Worker    * printing an error message.  */
375*cda5da8dSAndroid Build Coastguard Worker   public static immutable int YYERROR = 2;
376*cda5da8dSAndroid Build Coastguard Worker 
377*cda5da8dSAndroid Build Coastguard Worker   // Internal return codes that are not supported for user semantic
378*cda5da8dSAndroid Build Coastguard Worker   // actions.
379*cda5da8dSAndroid Build Coastguard Worker   private static immutable int YYERRLAB = 3;
380*cda5da8dSAndroid Build Coastguard Worker   private static immutable int YYNEWSTATE = 4;
381*cda5da8dSAndroid Build Coastguard Worker   private static immutable int YYDEFAULT = 5;
382*cda5da8dSAndroid Build Coastguard Worker   private static immutable int YYREDUCE = 6;
383*cda5da8dSAndroid Build Coastguard Worker   private static immutable int YYERRLAB1 = 7;
384*cda5da8dSAndroid Build Coastguard Worker   private static immutable int YYRETURN = 8;
385*cda5da8dSAndroid Build Coastguard Worker ]b4_push_if([[  private static immutable int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing.  */]])[
386*cda5da8dSAndroid Build Coastguard Worker 
387*cda5da8dSAndroid Build Coastguard Worker ]b4_locations_if([
388*cda5da8dSAndroid Build Coastguard Worker   private static immutable YYSemanticType yy_semantic_null;])[
389*cda5da8dSAndroid Build Coastguard Worker   private int yyerrstatus_ = 0;
390*cda5da8dSAndroid Build Coastguard Worker 
391*cda5da8dSAndroid Build Coastguard Worker   private void yyerrok()
392*cda5da8dSAndroid Build Coastguard Worker   {
393*cda5da8dSAndroid Build Coastguard Worker     yyerrstatus_ = 0;
394*cda5da8dSAndroid Build Coastguard Worker   }
395*cda5da8dSAndroid Build Coastguard Worker 
396*cda5da8dSAndroid Build Coastguard Worker   // Lookahead symbol kind.
397*cda5da8dSAndroid Build Coastguard Worker   SymbolKind yytoken = ]b4_symbol(empty, kind)[;
398*cda5da8dSAndroid Build Coastguard Worker 
399*cda5da8dSAndroid Build Coastguard Worker   /* State.  */
400*cda5da8dSAndroid Build Coastguard Worker   int yyn = 0;
401*cda5da8dSAndroid Build Coastguard Worker   int yylen = 0;
402*cda5da8dSAndroid Build Coastguard Worker   int yystate = 0;
403*cda5da8dSAndroid Build Coastguard Worker 
404*cda5da8dSAndroid Build Coastguard Worker   YYStack yystack;
405*cda5da8dSAndroid Build Coastguard Worker 
406*cda5da8dSAndroid Build Coastguard Worker   int label = YYNEWSTATE;
407*cda5da8dSAndroid Build Coastguard Worker 
408*cda5da8dSAndroid Build Coastguard Worker   /* Error handling.  */
409*cda5da8dSAndroid Build Coastguard Worker ]b4_locations_if([[
410*cda5da8dSAndroid Build Coastguard Worker   /// The location where the error started.
411*cda5da8dSAndroid Build Coastguard Worker   Location yyerrloc;
412*cda5da8dSAndroid Build Coastguard Worker 
413*cda5da8dSAndroid Build Coastguard Worker   /// Location of the lookahead.
414*cda5da8dSAndroid Build Coastguard Worker   Location yylloc;
415*cda5da8dSAndroid Build Coastguard Worker 
416*cda5da8dSAndroid Build Coastguard Worker   /// @@$.
417*cda5da8dSAndroid Build Coastguard Worker   Location yyloc;]])[
418*cda5da8dSAndroid Build Coastguard Worker 
419*cda5da8dSAndroid Build Coastguard Worker   /// Semantic value of the lookahead.
420*cda5da8dSAndroid Build Coastguard Worker   Value yylval;
421*cda5da8dSAndroid Build Coastguard Worker 
422*cda5da8dSAndroid Build Coastguard Worker   /**
423*cda5da8dSAndroid Build Coastguard Worker    * Whether error recovery is being done.  In this state, the parser
424*cda5da8dSAndroid Build Coastguard Worker    * reads token until it reaches a known state, and then restarts normal
425*cda5da8dSAndroid Build Coastguard Worker    * operation.  */
426*cda5da8dSAndroid Build Coastguard Worker   public final bool recovering ()
427*cda5da8dSAndroid Build Coastguard Worker   {
428*cda5da8dSAndroid Build Coastguard Worker     return yyerrstatus_ == 0;
429*cda5da8dSAndroid Build Coastguard Worker   }
430*cda5da8dSAndroid Build Coastguard Worker 
431*cda5da8dSAndroid Build Coastguard Worker   /** Compute post-reduction state.
432*cda5da8dSAndroid Build Coastguard Worker    * @@param yystate   the current state
433*cda5da8dSAndroid Build Coastguard Worker    * @@param yysym     the nonterminal to push on the stack
434*cda5da8dSAndroid Build Coastguard Worker    */
435*cda5da8dSAndroid Build Coastguard Worker   private int yyLRGotoState(int yystate, int yysym) {
436*cda5da8dSAndroid Build Coastguard Worker     int yyr = yypgoto_[yysym - yyntokens_] + yystate;
437*cda5da8dSAndroid Build Coastguard Worker     if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
438*cda5da8dSAndroid Build Coastguard Worker       return yytable_[yyr];
439*cda5da8dSAndroid Build Coastguard Worker     else
440*cda5da8dSAndroid Build Coastguard Worker       return yydefgoto_[yysym - yyntokens_];
441*cda5da8dSAndroid Build Coastguard Worker   }
442*cda5da8dSAndroid Build Coastguard Worker 
443*cda5da8dSAndroid Build Coastguard Worker   private int yyaction (int yyn, ref YYStack yystack, int yylen)
444*cda5da8dSAndroid Build Coastguard Worker   {
445*cda5da8dSAndroid Build Coastguard Worker     Value yyval;]b4_locations_if([[
446*cda5da8dSAndroid Build Coastguard Worker     Location yyloc = yylloc_from_stack (yystack, yylen);]])[
447*cda5da8dSAndroid Build Coastguard Worker 
448*cda5da8dSAndroid Build Coastguard Worker     /* If YYLEN is nonzero, implement the default value of the action:
449*cda5da8dSAndroid Build Coastguard Worker        `$$ = $1'.  Otherwise, use the top of the stack.
450*cda5da8dSAndroid Build Coastguard Worker 
451*cda5da8dSAndroid Build Coastguard Worker        Otherwise, the following line sets YYVAL to garbage.
452*cda5da8dSAndroid Build Coastguard Worker        This behavior is undocumented and Bison
453*cda5da8dSAndroid Build Coastguard Worker        users should not rely upon it.  */
454*cda5da8dSAndroid Build Coastguard Worker     if (yylen > 0)
455*cda5da8dSAndroid Build Coastguard Worker       yyval = yystack.valueAt (yylen - 1);
456*cda5da8dSAndroid Build Coastguard Worker     else
457*cda5da8dSAndroid Build Coastguard Worker       yyval = yystack.valueAt (0);
458*cda5da8dSAndroid Build Coastguard Worker 
459*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_trace_if([[
460*cda5da8dSAndroid Build Coastguard Worker     yy_reduce_print (yyn, yystack);]])[
461*cda5da8dSAndroid Build Coastguard Worker 
462*cda5da8dSAndroid Build Coastguard Worker     switch (yyn)
463*cda5da8dSAndroid Build Coastguard Worker     {
464*cda5da8dSAndroid Build Coastguard Worker ]b4_user_actions[
465*cda5da8dSAndroid Build Coastguard Worker       default: break;
466*cda5da8dSAndroid Build Coastguard Worker     }
467*cda5da8dSAndroid Build Coastguard Worker 
468*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_trace_if([[
469*cda5da8dSAndroid Build Coastguard Worker     yy_symbol_print ("-> $$ =", to!SymbolKind (yyr1_[yyn]), yyval]b4_locations_if([, yyloc])[);]])[
470*cda5da8dSAndroid Build Coastguard Worker 
471*cda5da8dSAndroid Build Coastguard Worker     yystack.pop (yylen);
472*cda5da8dSAndroid Build Coastguard Worker     yylen = 0;
473*cda5da8dSAndroid Build Coastguard Worker 
474*cda5da8dSAndroid Build Coastguard Worker     /* Shift the result of the reduction.  */
475*cda5da8dSAndroid Build Coastguard Worker     int yystate = yyLRGotoState(yystack.stateAt(0), yyr1_[yyn]);
476*cda5da8dSAndroid Build Coastguard Worker     yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
477*cda5da8dSAndroid Build Coastguard Worker     return YYNEWSTATE;
478*cda5da8dSAndroid Build Coastguard Worker   }
479*cda5da8dSAndroid Build Coastguard Worker 
480*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_trace_if([[
481*cda5da8dSAndroid Build Coastguard Worker   /*--------------------------------.
482*cda5da8dSAndroid Build Coastguard Worker   | Print this symbol on YYOUTPUT.  |
483*cda5da8dSAndroid Build Coastguard Worker   `--------------------------------*/
484*cda5da8dSAndroid Build Coastguard Worker 
485*cda5da8dSAndroid Build Coastguard Worker   private final void yy_symbol_print (string s, SymbolKind yykind,
486*cda5da8dSAndroid Build Coastguard Worker     ref Value yyval]b4_locations_if([, ref Location yyloc])[)
487*cda5da8dSAndroid Build Coastguard Worker   {
488*cda5da8dSAndroid Build Coastguard Worker     if (0 < yydebug)
489*cda5da8dSAndroid Build Coastguard Worker     {
490*cda5da8dSAndroid Build Coastguard Worker       File yyo = yyDebugStream;
491*cda5da8dSAndroid Build Coastguard Worker       yyo.write(s);
492*cda5da8dSAndroid Build Coastguard Worker       yyo.write(yykind < yyntokens_ ? " token " : " nterm ");
493*cda5da8dSAndroid Build Coastguard Worker       yyo.write(format("%s", yykind));
494*cda5da8dSAndroid Build Coastguard Worker       yyo.write(" ("]b4_locations_if([ ~ yyloc.toString() ~ ": "])[);
495*cda5da8dSAndroid Build Coastguard Worker       ]b4_symbol_actions([printer])[
496*cda5da8dSAndroid Build Coastguard Worker       yyo.write(")\n");
497*cda5da8dSAndroid Build Coastguard Worker     }
498*cda5da8dSAndroid Build Coastguard Worker   }
499*cda5da8dSAndroid Build Coastguard Worker ]])[
500*cda5da8dSAndroid Build Coastguard Worker ]b4_symbol_type_define[
501*cda5da8dSAndroid Build Coastguard Worker ]b4_push_if([[
502*cda5da8dSAndroid Build Coastguard Worker   /**
503*cda5da8dSAndroid Build Coastguard Worker    * Push Parse input from external lexer
504*cda5da8dSAndroid Build Coastguard Worker    *
505*cda5da8dSAndroid Build Coastguard Worker    * @@param yyla current Symbol
506*cda5da8dSAndroid Build Coastguard Worker    *
507*cda5da8dSAndroid Build Coastguard Worker    * @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
508*cda5da8dSAndroid Build Coastguard Worker    */
509*cda5da8dSAndroid Build Coastguard Worker   public int pushParse(Symbol yyla)]], [[
510*cda5da8dSAndroid Build Coastguard Worker   /**
511*cda5da8dSAndroid Build Coastguard Worker    * Parse input from the scanner that was specified at object construction
512*cda5da8dSAndroid Build Coastguard Worker    * time.  Return whether the end of the input was reached successfully.
513*cda5da8dSAndroid Build Coastguard Worker    *
514*cda5da8dSAndroid Build Coastguard Worker    * @@return <tt>true</tt> if the parsing succeeds.  Note that this does not
515*cda5da8dSAndroid Build Coastguard Worker    *          imply that there were no syntax errors.
516*cda5da8dSAndroid Build Coastguard Worker    */
517*cda5da8dSAndroid Build Coastguard Worker   public bool parse()]])[
518*cda5da8dSAndroid Build Coastguard Worker   {]b4_push_if([[
519*cda5da8dSAndroid Build Coastguard Worker     if (!this.pushParseInitialized)
520*cda5da8dSAndroid Build Coastguard Worker     {
521*cda5da8dSAndroid Build Coastguard Worker       pushParseInitialize();
522*cda5da8dSAndroid Build Coastguard Worker       yyerrstatus_ = 0;
523*cda5da8dSAndroid Build Coastguard Worker     }
524*cda5da8dSAndroid Build Coastguard Worker     else
525*cda5da8dSAndroid Build Coastguard Worker       label = YYGETTOKEN;
526*cda5da8dSAndroid Build Coastguard Worker 
527*cda5da8dSAndroid Build Coastguard Worker     bool push_token_consumed = true;
528*cda5da8dSAndroid Build Coastguard Worker ]], [[  bool yyresult;]b4_lac_if([[
529*cda5da8dSAndroid Build Coastguard Worker     // Discard the LAC context in case there still is one left from a
530*cda5da8dSAndroid Build Coastguard Worker     // previous invocation.
531*cda5da8dSAndroid Build Coastguard Worker     yylacDiscard("init");]])[]b4_parse_trace_if([[
532*cda5da8dSAndroid Build Coastguard Worker 
533*cda5da8dSAndroid Build Coastguard Worker     yycdebugln ("Starting parse");]])[
534*cda5da8dSAndroid Build Coastguard Worker     yyerrstatus_ = 0;
535*cda5da8dSAndroid Build Coastguard Worker 
536*cda5da8dSAndroid Build Coastguard Worker ]m4_ifdef([b4_initial_action], [
537*cda5da8dSAndroid Build Coastguard Worker m4_pushdef([b4_at_dollar],     [yylloc])dnl
538*cda5da8dSAndroid Build Coastguard Worker m4_pushdef([b4_dollar_dollar], [yylval])dnl
539*cda5da8dSAndroid Build Coastguard Worker     /* User initialization code.  */
540*cda5da8dSAndroid Build Coastguard Worker     b4_user_initial_action
541*cda5da8dSAndroid Build Coastguard Worker m4_popdef([b4_dollar_dollar])dnl
542*cda5da8dSAndroid Build Coastguard Worker m4_popdef([b4_at_dollar])])dnl
543*cda5da8dSAndroid Build Coastguard Worker 
544*cda5da8dSAndroid Build Coastguard Worker   [  /* Initialize the stack.  */
545*cda5da8dSAndroid Build Coastguard Worker     yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
546*cda5da8dSAndroid Build Coastguard Worker 
547*cda5da8dSAndroid Build Coastguard Worker     label = YYNEWSTATE;]])[
548*cda5da8dSAndroid Build Coastguard Worker     for (;;)
549*cda5da8dSAndroid Build Coastguard Worker       final switch (label)
550*cda5da8dSAndroid Build Coastguard Worker       {
551*cda5da8dSAndroid Build Coastguard Worker         /* New state.  Unlike in the C/C++ skeletons, the state is already
552*cda5da8dSAndroid Build Coastguard Worker            pushed when we come here.  */
553*cda5da8dSAndroid Build Coastguard Worker       case YYNEWSTATE:]b4_parse_trace_if([[
554*cda5da8dSAndroid Build Coastguard Worker         yycdebugln (format("Entering state %d", yystate));
555*cda5da8dSAndroid Build Coastguard Worker         if (0 < yydebug)
556*cda5da8dSAndroid Build Coastguard Worker           yystack.print (yyDebugStream);]])[
557*cda5da8dSAndroid Build Coastguard Worker 
558*cda5da8dSAndroid Build Coastguard Worker         /* Accept?  */
559*cda5da8dSAndroid Build Coastguard Worker         if (yystate == yyfinal_)]b4_push_if([[
560*cda5da8dSAndroid Build Coastguard Worker         {
561*cda5da8dSAndroid Build Coastguard Worker           label = YYACCEPT;
562*cda5da8dSAndroid Build Coastguard Worker           break;
563*cda5da8dSAndroid Build Coastguard Worker         }]], [[
564*cda5da8dSAndroid Build Coastguard Worker           return true;]])[
565*cda5da8dSAndroid Build Coastguard Worker 
566*cda5da8dSAndroid Build Coastguard Worker         /* Take a decision.  First try without lookahead.  */
567*cda5da8dSAndroid Build Coastguard Worker         yyn = yypact_[yystate];
568*cda5da8dSAndroid Build Coastguard Worker         if (yyPactValueIsDefault(yyn))
569*cda5da8dSAndroid Build Coastguard Worker         {
570*cda5da8dSAndroid Build Coastguard Worker           label = YYDEFAULT;
571*cda5da8dSAndroid Build Coastguard Worker           break;
572*cda5da8dSAndroid Build Coastguard Worker         }]b4_push_if([[
573*cda5da8dSAndroid Build Coastguard Worker         goto case;
574*cda5da8dSAndroid Build Coastguard Worker 
575*cda5da8dSAndroid Build Coastguard Worker         case YYGETTOKEN:]])[
576*cda5da8dSAndroid Build Coastguard Worker 
577*cda5da8dSAndroid Build Coastguard Worker         /* Read a lookahead token.  */
578*cda5da8dSAndroid Build Coastguard Worker         if (yytoken == ]b4_symbol(empty, kind)[)
579*cda5da8dSAndroid Build Coastguard Worker         {]b4_push_if([[
580*cda5da8dSAndroid Build Coastguard Worker           if (!push_token_consumed)
581*cda5da8dSAndroid Build Coastguard Worker             return YYPUSH_MORE;]])[]b4_parse_trace_if([[
582*cda5da8dSAndroid Build Coastguard Worker           yycdebugln ("Reading a token");]])[]b4_push_if([[
583*cda5da8dSAndroid Build Coastguard Worker           yytoken = yyla.token;
584*cda5da8dSAndroid Build Coastguard Worker           yylval = yyla.value;]b4_locations_if([[
585*cda5da8dSAndroid Build Coastguard Worker           yylloc = yyla.location;]])[
586*cda5da8dSAndroid Build Coastguard Worker           push_token_consumed = false;]], [[
587*cda5da8dSAndroid Build Coastguard Worker           Symbol yysymbol = yylex();
588*cda5da8dSAndroid Build Coastguard Worker           yytoken = yysymbol.token();
589*cda5da8dSAndroid Build Coastguard Worker           yylval = yysymbol.value();]b4_locations_if([[
590*cda5da8dSAndroid Build Coastguard Worker           yylloc = yysymbol.location();]])[]])[
591*cda5da8dSAndroid Build Coastguard Worker         }
592*cda5da8dSAndroid Build Coastguard Worker 
593*cda5da8dSAndroid Build Coastguard Worker         /* Token already converted to internal form.  */]b4_parse_trace_if([[
594*cda5da8dSAndroid Build Coastguard Worker         yy_symbol_print ("Next token is", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
595*cda5da8dSAndroid Build Coastguard Worker 
596*cda5da8dSAndroid Build Coastguard Worker         if (yytoken == ]b4_symbol(error, kind)[)
597*cda5da8dSAndroid Build Coastguard Worker         {
598*cda5da8dSAndroid Build Coastguard Worker           // The scanner already issued an error message, process directly
599*cda5da8dSAndroid Build Coastguard Worker           // to error recovery.  But do not keep the error token as
600*cda5da8dSAndroid Build Coastguard Worker           // lookahead, it is too special and may lead us to an endless
601*cda5da8dSAndroid Build Coastguard Worker           // loop in error recovery. */
602*cda5da8dSAndroid Build Coastguard Worker           yytoken = ]b4_symbol(undef, kind)[;]b4_locations_if([[
603*cda5da8dSAndroid Build Coastguard Worker           yyerrloc = yylloc;]])[
604*cda5da8dSAndroid Build Coastguard Worker           label = YYERRLAB1;
605*cda5da8dSAndroid Build Coastguard Worker         }
606*cda5da8dSAndroid Build Coastguard Worker         else
607*cda5da8dSAndroid Build Coastguard Worker         {
608*cda5da8dSAndroid Build Coastguard Worker           /* If the proper action on seeing token YYTOKEN is to reduce or to
609*cda5da8dSAndroid Build Coastguard Worker              detect an error, take that action.  */
610*cda5da8dSAndroid Build Coastguard Worker           yyn += yytoken;
611*cda5da8dSAndroid Build Coastguard Worker           if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) {]b4_lac_if([[
612*cda5da8dSAndroid Build Coastguard Worker             if (!yylacEstablish(yystack, yytoken))
613*cda5da8dSAndroid Build Coastguard Worker               label = YYERRLAB;
614*cda5da8dSAndroid Build Coastguard Worker             else]])[
615*cda5da8dSAndroid Build Coastguard Worker               label = YYDEFAULT;
616*cda5da8dSAndroid Build Coastguard Worker           }
617*cda5da8dSAndroid Build Coastguard Worker           /* <= 0 means reduce or error.  */
618*cda5da8dSAndroid Build Coastguard Worker           else if ((yyn = yytable_[yyn]) <= 0)
619*cda5da8dSAndroid Build Coastguard Worker           {
620*cda5da8dSAndroid Build Coastguard Worker             if (yyTableValueIsError(yyn))
621*cda5da8dSAndroid Build Coastguard Worker               label = YYERRLAB;]b4_lac_if([[
622*cda5da8dSAndroid Build Coastguard Worker             else if (!yylacEstablish(yystack, yytoken))
623*cda5da8dSAndroid Build Coastguard Worker               label = YYERRLAB;]])[
624*cda5da8dSAndroid Build Coastguard Worker             else
625*cda5da8dSAndroid Build Coastguard Worker             {
626*cda5da8dSAndroid Build Coastguard Worker               yyn = -yyn;
627*cda5da8dSAndroid Build Coastguard Worker               label = YYREDUCE;
628*cda5da8dSAndroid Build Coastguard Worker             }
629*cda5da8dSAndroid Build Coastguard Worker           }
630*cda5da8dSAndroid Build Coastguard Worker           else
631*cda5da8dSAndroid Build Coastguard Worker           {
632*cda5da8dSAndroid Build Coastguard Worker             /* Shift the lookahead token.  */]b4_parse_trace_if([[
633*cda5da8dSAndroid Build Coastguard Worker             yy_symbol_print ("Shifting", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
634*cda5da8dSAndroid Build Coastguard Worker 
635*cda5da8dSAndroid Build Coastguard Worker             /* Discard the token being shifted.  */
636*cda5da8dSAndroid Build Coastguard Worker             yytoken = ]b4_symbol(empty, kind)[;
637*cda5da8dSAndroid Build Coastguard Worker 
638*cda5da8dSAndroid Build Coastguard Worker             /* Count tokens shifted since error; after three, turn off error
639*cda5da8dSAndroid Build Coastguard Worker              * status.  */
640*cda5da8dSAndroid Build Coastguard Worker             if (yyerrstatus_ > 0)
641*cda5da8dSAndroid Build Coastguard Worker               --yyerrstatus_;
642*cda5da8dSAndroid Build Coastguard Worker 
643*cda5da8dSAndroid Build Coastguard Worker             yystate = yyn;
644*cda5da8dSAndroid Build Coastguard Worker             yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);]b4_lac_if([[
645*cda5da8dSAndroid Build Coastguard Worker             yylacDiscard("shift");]])[
646*cda5da8dSAndroid Build Coastguard Worker             label = YYNEWSTATE;
647*cda5da8dSAndroid Build Coastguard Worker           }
648*cda5da8dSAndroid Build Coastguard Worker         }
649*cda5da8dSAndroid Build Coastguard Worker         break;
650*cda5da8dSAndroid Build Coastguard Worker 
651*cda5da8dSAndroid Build Coastguard Worker       /*-----------------------------------------------------------.
652*cda5da8dSAndroid Build Coastguard Worker       | yydefault -- do the default action for the current state.  |
653*cda5da8dSAndroid Build Coastguard Worker       `-----------------------------------------------------------*/
654*cda5da8dSAndroid Build Coastguard Worker       case YYDEFAULT:
655*cda5da8dSAndroid Build Coastguard Worker         yyn = yydefact_[yystate];
656*cda5da8dSAndroid Build Coastguard Worker         if (yyn == 0)
657*cda5da8dSAndroid Build Coastguard Worker           label = YYERRLAB;
658*cda5da8dSAndroid Build Coastguard Worker         else
659*cda5da8dSAndroid Build Coastguard Worker           label = YYREDUCE;
660*cda5da8dSAndroid Build Coastguard Worker         break;
661*cda5da8dSAndroid Build Coastguard Worker 
662*cda5da8dSAndroid Build Coastguard Worker       /*-----------------------------.
663*cda5da8dSAndroid Build Coastguard Worker       | yyreduce -- Do a reduction.  |
664*cda5da8dSAndroid Build Coastguard Worker       `-----------------------------*/
665*cda5da8dSAndroid Build Coastguard Worker       case YYREDUCE:
666*cda5da8dSAndroid Build Coastguard Worker         yylen = yyr2_[yyn];
667*cda5da8dSAndroid Build Coastguard Worker         label = yyaction (yyn, yystack, yylen);
668*cda5da8dSAndroid Build Coastguard Worker         yystate = yystack.stateAt (0);
669*cda5da8dSAndroid Build Coastguard Worker         break;
670*cda5da8dSAndroid Build Coastguard Worker 
671*cda5da8dSAndroid Build Coastguard Worker       /*--------------------------------------.
672*cda5da8dSAndroid Build Coastguard Worker       | yyerrlab -- here on detecting error.  |
673*cda5da8dSAndroid Build Coastguard Worker       `--------------------------------------*/
674*cda5da8dSAndroid Build Coastguard Worker       case YYERRLAB:
675*cda5da8dSAndroid Build Coastguard Worker         /* If not already recovering from an error, report this error.  */
676*cda5da8dSAndroid Build Coastguard Worker         if (yyerrstatus_ == 0)
677*cda5da8dSAndroid Build Coastguard Worker         {
678*cda5da8dSAndroid Build Coastguard Worker           ++yynerrs_;
679*cda5da8dSAndroid Build Coastguard Worker           yyreportSyntaxError(new Context(]b4_lac_if([[this, ]])[yystack, yytoken]b4_locations_if([[, yylloc]])[));
680*cda5da8dSAndroid Build Coastguard Worker         }
681*cda5da8dSAndroid Build Coastguard Worker ]b4_locations_if([
682*cda5da8dSAndroid Build Coastguard Worker         yyerrloc = yylloc;])[
683*cda5da8dSAndroid Build Coastguard Worker         if (yyerrstatus_ == 3)
684*cda5da8dSAndroid Build Coastguard Worker         {
685*cda5da8dSAndroid Build Coastguard Worker           /* If just tried and failed to reuse lookahead token after an
686*cda5da8dSAndroid Build Coastguard Worker            * error, discard it.  */
687*cda5da8dSAndroid Build Coastguard Worker 
688*cda5da8dSAndroid Build Coastguard Worker           /* Return failure if at end of input.  */
689*cda5da8dSAndroid Build Coastguard Worker           if (yytoken == ]b4_symbol(eof, [kind])[)]b4_push_if([[
690*cda5da8dSAndroid Build Coastguard Worker           {
691*cda5da8dSAndroid Build Coastguard Worker             label = YYABORT;
692*cda5da8dSAndroid Build Coastguard Worker             break;
693*cda5da8dSAndroid Build Coastguard Worker           }]], [[
694*cda5da8dSAndroid Build Coastguard Worker           return false;]])[
695*cda5da8dSAndroid Build Coastguard Worker           else
696*cda5da8dSAndroid Build Coastguard Worker             yytoken = ]b4_symbol(empty, kind)[;
697*cda5da8dSAndroid Build Coastguard Worker         }
698*cda5da8dSAndroid Build Coastguard Worker 
699*cda5da8dSAndroid Build Coastguard Worker         /* Else will try to reuse lookahead token after shifting the error
700*cda5da8dSAndroid Build Coastguard Worker          * token.  */
701*cda5da8dSAndroid Build Coastguard Worker         label = YYERRLAB1;
702*cda5da8dSAndroid Build Coastguard Worker         break;
703*cda5da8dSAndroid Build Coastguard Worker 
704*cda5da8dSAndroid Build Coastguard Worker       /*-------------------------------------------------.
705*cda5da8dSAndroid Build Coastguard Worker       | errorlab -- error raised explicitly by YYERROR.  |
706*cda5da8dSAndroid Build Coastguard Worker       `-------------------------------------------------*/
707*cda5da8dSAndroid Build Coastguard Worker       case YYERROR:]b4_locations_if([
708*cda5da8dSAndroid Build Coastguard Worker         yyerrloc = yystack.locationAt (yylen - 1);])[
709*cda5da8dSAndroid Build Coastguard Worker         /* Do not reclaim the symbols of the rule which action triggered
710*cda5da8dSAndroid Build Coastguard Worker            this YYERROR.  */
711*cda5da8dSAndroid Build Coastguard Worker         yystack.pop (yylen);
712*cda5da8dSAndroid Build Coastguard Worker         yylen = 0;
713*cda5da8dSAndroid Build Coastguard Worker         yystate = yystack.stateAt (0);
714*cda5da8dSAndroid Build Coastguard Worker         label = YYERRLAB1;
715*cda5da8dSAndroid Build Coastguard Worker         break;
716*cda5da8dSAndroid Build Coastguard Worker 
717*cda5da8dSAndroid Build Coastguard Worker       /*-------------------------------------------------------------.
718*cda5da8dSAndroid Build Coastguard Worker       | yyerrlab1 -- common code for both syntax error and YYERROR.  |
719*cda5da8dSAndroid Build Coastguard Worker       `-------------------------------------------------------------*/
720*cda5da8dSAndroid Build Coastguard Worker       case YYERRLAB1:
721*cda5da8dSAndroid Build Coastguard Worker         yyerrstatus_ = 3;       /* Each real token shifted decrements this.  */
722*cda5da8dSAndroid Build Coastguard Worker 
723*cda5da8dSAndroid Build Coastguard Worker         // Pop stack until we find a state that shifts the error token.
724*cda5da8dSAndroid Build Coastguard Worker         for (;;)
725*cda5da8dSAndroid Build Coastguard Worker         {
726*cda5da8dSAndroid Build Coastguard Worker           yyn = yypact_[yystate];
727*cda5da8dSAndroid Build Coastguard Worker           if (!yyPactValueIsDefault(yyn))
728*cda5da8dSAndroid Build Coastguard Worker           {
729*cda5da8dSAndroid Build Coastguard Worker             yyn += ]b4_symbol(error, kind)[;
730*cda5da8dSAndroid Build Coastguard Worker             if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == ]b4_symbol(error, kind)[)
731*cda5da8dSAndroid Build Coastguard Worker             {
732*cda5da8dSAndroid Build Coastguard Worker               yyn = yytable_[yyn];
733*cda5da8dSAndroid Build Coastguard Worker               if (0 < yyn)
734*cda5da8dSAndroid Build Coastguard Worker                 break;
735*cda5da8dSAndroid Build Coastguard Worker                   }
736*cda5da8dSAndroid Build Coastguard Worker           }
737*cda5da8dSAndroid Build Coastguard Worker 
738*cda5da8dSAndroid Build Coastguard Worker           /* Pop the current state because it cannot handle the error token.  */
739*cda5da8dSAndroid Build Coastguard Worker           if (yystack.height == 1)]b4_push_if([[
740*cda5da8dSAndroid Build Coastguard Worker           {
741*cda5da8dSAndroid Build Coastguard Worker             label = YYABORT;
742*cda5da8dSAndroid Build Coastguard Worker             break;
743*cda5da8dSAndroid Build Coastguard Worker           }]],[[
744*cda5da8dSAndroid Build Coastguard Worker             return false;]])[
745*cda5da8dSAndroid Build Coastguard Worker 
746*cda5da8dSAndroid Build Coastguard Worker ]b4_locations_if([          yyerrloc = yystack.locationAt (0);])[
747*cda5da8dSAndroid Build Coastguard Worker           yystack.pop ();
748*cda5da8dSAndroid Build Coastguard Worker           yystate = yystack.stateAt (0);]b4_parse_trace_if([[
749*cda5da8dSAndroid Build Coastguard Worker           if (0 < yydebug)
750*cda5da8dSAndroid Build Coastguard Worker             yystack.print (yyDebugStream);]])[
751*cda5da8dSAndroid Build Coastguard Worker         }]b4_push_if([[
752*cda5da8dSAndroid Build Coastguard Worker         if (label == YYABORT)
753*cda5da8dSAndroid Build Coastguard Worker           /* Leave the switch.  */
754*cda5da8dSAndroid Build Coastguard Worker           break;
755*cda5da8dSAndroid Build Coastguard Worker ]])[
756*cda5da8dSAndroid Build Coastguard Worker ]b4_locations_if([
757*cda5da8dSAndroid Build Coastguard Worker         /* Muck with the stack to setup for yylloc.  */
758*cda5da8dSAndroid Build Coastguard Worker         yystack.push (0, yy_semantic_null, yylloc);
759*cda5da8dSAndroid Build Coastguard Worker         yystack.push (0, yy_semantic_null, yyerrloc);
760*cda5da8dSAndroid Build Coastguard Worker         yyloc = yylloc_from_stack (yystack, 2);
761*cda5da8dSAndroid Build Coastguard Worker         yystack.pop (2);])[
762*cda5da8dSAndroid Build Coastguard Worker 
763*cda5da8dSAndroid Build Coastguard Worker         /* Shift the error token.  */]b4_lac_if([[
764*cda5da8dSAndroid Build Coastguard Worker         yylacDiscard("error recovery");]])[]b4_parse_trace_if([[
765*cda5da8dSAndroid Build Coastguard Worker         yy_symbol_print ("Shifting", to!SymbolKind (yystos_[yyn]), yylval]b4_locations_if([, yyloc])[);]])[
766*cda5da8dSAndroid Build Coastguard Worker         yystate = yyn;
767*cda5da8dSAndroid Build Coastguard Worker         yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
768*cda5da8dSAndroid Build Coastguard Worker         label = YYNEWSTATE;
769*cda5da8dSAndroid Build Coastguard Worker         break;
770*cda5da8dSAndroid Build Coastguard Worker 
771*cda5da8dSAndroid Build Coastguard Worker       /* Accept.  */
772*cda5da8dSAndroid Build Coastguard Worker       case YYACCEPT:]b4_push_if([[
773*cda5da8dSAndroid Build Coastguard Worker         this.pushParseInitialized = false;]b4_parse_trace_if([[
774*cda5da8dSAndroid Build Coastguard Worker         if (0 < yydebug)
775*cda5da8dSAndroid Build Coastguard Worker           yystack.print (yyDebugStream);]])[
776*cda5da8dSAndroid Build Coastguard Worker         return YYACCEPT;]], [[
777*cda5da8dSAndroid Build Coastguard Worker         yyresult = true;
778*cda5da8dSAndroid Build Coastguard Worker         label = YYRETURN;
779*cda5da8dSAndroid Build Coastguard Worker         break;]])[
780*cda5da8dSAndroid Build Coastguard Worker 
781*cda5da8dSAndroid Build Coastguard Worker       /* Abort.  */
782*cda5da8dSAndroid Build Coastguard Worker       case YYABORT:]b4_push_if([[
783*cda5da8dSAndroid Build Coastguard Worker         this.pushParseInitialized = false;]b4_parse_trace_if([[
784*cda5da8dSAndroid Build Coastguard Worker         if (0 < yydebug)
785*cda5da8dSAndroid Build Coastguard Worker           yystack.print (yyDebugStream);]])[
786*cda5da8dSAndroid Build Coastguard Worker         return YYABORT;]], [[
787*cda5da8dSAndroid Build Coastguard Worker         yyresult = false;
788*cda5da8dSAndroid Build Coastguard Worker         label = YYRETURN;
789*cda5da8dSAndroid Build Coastguard Worker         break;]])[
790*cda5da8dSAndroid Build Coastguard Worker ]b4_push_if([[]], [[      ][case YYRETURN:]b4_parse_trace_if([[
791*cda5da8dSAndroid Build Coastguard Worker         if (0 < yydebug)
792*cda5da8dSAndroid Build Coastguard Worker           yystack.print (yyDebugStream);]])[
793*cda5da8dSAndroid Build Coastguard Worker         return yyresult;]])[
794*cda5da8dSAndroid Build Coastguard Worker     }
795*cda5da8dSAndroid Build Coastguard Worker     assert(0);
796*cda5da8dSAndroid Build Coastguard Worker   }
797*cda5da8dSAndroid Build Coastguard Worker 
798*cda5da8dSAndroid Build Coastguard Worker ]b4_push_if([[
799*cda5da8dSAndroid Build Coastguard Worker   bool pushParseInitialized = false;
800*cda5da8dSAndroid Build Coastguard Worker 
801*cda5da8dSAndroid Build Coastguard Worker   /**
802*cda5da8dSAndroid Build Coastguard Worker    * (Re-)Initialize the state of the push parser.
803*cda5da8dSAndroid Build Coastguard Worker    */
804*cda5da8dSAndroid Build Coastguard Worker   public void pushParseInitialize()
805*cda5da8dSAndroid Build Coastguard Worker   {
806*cda5da8dSAndroid Build Coastguard Worker 
807*cda5da8dSAndroid Build Coastguard Worker     /* Lookahead and lookahead in internal form.  */
808*cda5da8dSAndroid Build Coastguard Worker     this.yytoken = ]b4_symbol(empty, kind)[;
809*cda5da8dSAndroid Build Coastguard Worker 
810*cda5da8dSAndroid Build Coastguard Worker     /* State.  */
811*cda5da8dSAndroid Build Coastguard Worker     this.yyn = 0;
812*cda5da8dSAndroid Build Coastguard Worker     this.yylen = 0;
813*cda5da8dSAndroid Build Coastguard Worker     this.yystate = 0;
814*cda5da8dSAndroid Build Coastguard Worker     destroy(this.yystack);
815*cda5da8dSAndroid Build Coastguard Worker     this.label = YYNEWSTATE;
816*cda5da8dSAndroid Build Coastguard Worker ]b4_lac_if([[
817*cda5da8dSAndroid Build Coastguard Worker     destroy(this.yylacStack);
818*cda5da8dSAndroid Build Coastguard Worker     this.yylacEstablished = false;]])[
819*cda5da8dSAndroid Build Coastguard Worker 
820*cda5da8dSAndroid Build Coastguard Worker     /* Error handling.  */
821*cda5da8dSAndroid Build Coastguard Worker     this.yynerrs_ = 0;
822*cda5da8dSAndroid Build Coastguard Worker ]b4_locations_if([
823*cda5da8dSAndroid Build Coastguard Worker     /* The location where the error started.  */
824*cda5da8dSAndroid Build Coastguard Worker     this.yyerrloc = Location(Position(), Position());
825*cda5da8dSAndroid Build Coastguard Worker     this.yylloc = Location(Position(), Position());])[
826*cda5da8dSAndroid Build Coastguard Worker 
827*cda5da8dSAndroid Build Coastguard Worker     /* Semantic value of the lookahead.  */
828*cda5da8dSAndroid Build Coastguard Worker     //destroy(this.yylval);
829*cda5da8dSAndroid Build Coastguard Worker 
830*cda5da8dSAndroid Build Coastguard Worker     /* Initialize the stack.  */
831*cda5da8dSAndroid Build Coastguard Worker     yystack.push(this.yystate, this.yylval]b4_locations_if([, this.yylloc])[);
832*cda5da8dSAndroid Build Coastguard Worker 
833*cda5da8dSAndroid Build Coastguard Worker     this.pushParseInitialized = true;
834*cda5da8dSAndroid Build Coastguard Worker   }]])[]b4_both_if([[
835*cda5da8dSAndroid Build Coastguard Worker   /**
836*cda5da8dSAndroid Build Coastguard Worker    * Parse input from the scanner that was specified at object construction
837*cda5da8dSAndroid Build Coastguard Worker    * time.  Return whether the end of the input was reached successfully.
838*cda5da8dSAndroid Build Coastguard Worker    * This version of parse() is defined only when api.push-push=both.
839*cda5da8dSAndroid Build Coastguard Worker    *
840*cda5da8dSAndroid Build Coastguard Worker    * @@return <tt>true</tt> if the parsing succeeds.  Note that this does not
841*cda5da8dSAndroid Build Coastguard Worker    *          imply that there were no syntax errors.
842*cda5da8dSAndroid Build Coastguard Worker    */
843*cda5da8dSAndroid Build Coastguard Worker   bool parse()
844*cda5da8dSAndroid Build Coastguard Worker   {
845*cda5da8dSAndroid Build Coastguard Worker     int status = 0;
846*cda5da8dSAndroid Build Coastguard Worker     do {
847*cda5da8dSAndroid Build Coastguard Worker       status = this.pushParse(yylex());
848*cda5da8dSAndroid Build Coastguard Worker     } while (status == YYPUSH_MORE);
849*cda5da8dSAndroid Build Coastguard Worker     return status == YYACCEPT;
850*cda5da8dSAndroid Build Coastguard Worker   }]])[
851*cda5da8dSAndroid Build Coastguard Worker 
852*cda5da8dSAndroid Build Coastguard Worker   // Generate an error message.
853*cda5da8dSAndroid Build Coastguard Worker   private final void yyreportSyntaxError(Context yyctx)
854*cda5da8dSAndroid Build Coastguard Worker   {]b4_parse_error_bmatch(
855*cda5da8dSAndroid Build Coastguard Worker [custom], [[
856*cda5da8dSAndroid Build Coastguard Worker     yylexer.reportSyntaxError(yyctx);]],
857*cda5da8dSAndroid Build Coastguard Worker [detailed], [[
858*cda5da8dSAndroid Build Coastguard Worker     if (yyctx.getToken() != ]b4_symbol(empty, kind)[)
859*cda5da8dSAndroid Build Coastguard Worker     {
860*cda5da8dSAndroid Build Coastguard Worker       // FIXME: This method of building the message is not compatible
861*cda5da8dSAndroid Build Coastguard Worker       // with internationalization.
862*cda5da8dSAndroid Build Coastguard Worker       immutable int argmax = 5;
863*cda5da8dSAndroid Build Coastguard Worker       SymbolKind[] yyarg = new SymbolKind[argmax];
864*cda5da8dSAndroid Build Coastguard Worker       int yycount = yysyntaxErrorArguments(yyctx, yyarg, argmax);
865*cda5da8dSAndroid Build Coastguard Worker       string res, yyformat;
866*cda5da8dSAndroid Build Coastguard Worker       switch (yycount)
867*cda5da8dSAndroid Build Coastguard Worker       {
868*cda5da8dSAndroid Build Coastguard Worker         case  1:
869*cda5da8dSAndroid Build Coastguard Worker           yyformat = YY_("syntax error, unexpected %s");
870*cda5da8dSAndroid Build Coastguard Worker           res = format(yyformat, yyarg[0]);
871*cda5da8dSAndroid Build Coastguard Worker          break;
872*cda5da8dSAndroid Build Coastguard Worker         case  2:
873*cda5da8dSAndroid Build Coastguard Worker           yyformat = YY_("syntax error, unexpected %s, expecting %s");
874*cda5da8dSAndroid Build Coastguard Worker           res = format(yyformat, yyarg[0], yyarg[1]);
875*cda5da8dSAndroid Build Coastguard Worker           break;
876*cda5da8dSAndroid Build Coastguard Worker         case  3:
877*cda5da8dSAndroid Build Coastguard Worker           yyformat = YY_("syntax error, unexpected %s, expecting %s or %s");
878*cda5da8dSAndroid Build Coastguard Worker           res = format(yyformat, yyarg[0], yyarg[1], yyarg[2]);
879*cda5da8dSAndroid Build Coastguard Worker           break;
880*cda5da8dSAndroid Build Coastguard Worker         case  4:
881*cda5da8dSAndroid Build Coastguard Worker           yyformat = YY_("syntax error, unexpected %s, expecting %s or %s or %s");
882*cda5da8dSAndroid Build Coastguard Worker           res = format(yyformat, yyarg[0], yyarg[1], yyarg[2], yyarg[3]);
883*cda5da8dSAndroid Build Coastguard Worker           break;
884*cda5da8dSAndroid Build Coastguard Worker         case  5:
885*cda5da8dSAndroid Build Coastguard Worker           yyformat = YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
886*cda5da8dSAndroid Build Coastguard Worker           res = format(yyformat, yyarg[0], yyarg[1], yyarg[2], yyarg[3], yyarg[4]);
887*cda5da8dSAndroid Build Coastguard Worker           break;
888*cda5da8dSAndroid Build Coastguard Worker         default:
889*cda5da8dSAndroid Build Coastguard Worker           res = YY_("syntax error");
890*cda5da8dSAndroid Build Coastguard Worker           break;
891*cda5da8dSAndroid Build Coastguard Worker       }
892*cda5da8dSAndroid Build Coastguard Worker       yyerror(]b4_locations_if([yyctx.getLocation(), ])[res);
893*cda5da8dSAndroid Build Coastguard Worker     }]],
894*cda5da8dSAndroid Build Coastguard Worker [[simple]], [[
895*cda5da8dSAndroid Build Coastguard Worker     yyerror(]b4_locations_if([yyctx.getLocation(), ])[YY_("syntax error"));]])[
896*cda5da8dSAndroid Build Coastguard Worker   }
897*cda5da8dSAndroid Build Coastguard Worker 
898*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_error_bmatch(
899*cda5da8dSAndroid Build Coastguard Worker [detailed], [[
900*cda5da8dSAndroid Build Coastguard Worker   private int yysyntaxErrorArguments(Context yyctx, SymbolKind[] yyarg, int yyargn) {
901*cda5da8dSAndroid Build Coastguard Worker     /* There are many possibilities here to consider:
902*cda5da8dSAndroid Build Coastguard Worker        - If this state is a consistent state with a default action,
903*cda5da8dSAndroid Build Coastguard Worker          then the only way this function was invoked is if the
904*cda5da8dSAndroid Build Coastguard Worker          default action is an error action.  In that case, don't
905*cda5da8dSAndroid Build Coastguard Worker          check for expected tokens because there are none.
906*cda5da8dSAndroid Build Coastguard Worker        - The only way there can be no lookahead present (in tok) is
907*cda5da8dSAndroid Build Coastguard Worker          if this state is a consistent state with a default action.
908*cda5da8dSAndroid Build Coastguard Worker          Thus, detecting the absence of a lookahead is sufficient to
909*cda5da8dSAndroid Build Coastguard Worker          determine that there is no unexpected or expected token to
910*cda5da8dSAndroid Build Coastguard Worker          report.  In that case, just report a simple "syntax error".
911*cda5da8dSAndroid Build Coastguard Worker        - Don't assume there isn't a lookahead just because this
912*cda5da8dSAndroid Build Coastguard Worker          state is a consistent state with a default action.  There
913*cda5da8dSAndroid Build Coastguard Worker          might have been a previous inconsistent state, consistent
914*cda5da8dSAndroid Build Coastguard Worker          state with a non-default action, or user semantic action
915*cda5da8dSAndroid Build Coastguard Worker          that manipulated yychar.  (However, yychar is currently out
916*cda5da8dSAndroid Build Coastguard Worker          of scope during semantic actions.)
917*cda5da8dSAndroid Build Coastguard Worker        - Of course, the expected token list depends on states to
918*cda5da8dSAndroid Build Coastguard Worker          have correct lookahead information, and it depends on the
919*cda5da8dSAndroid Build Coastguard Worker          parser not to perform extra reductions after fetching a
920*cda5da8dSAndroid Build Coastguard Worker          lookahead from the scanner and before detecting a syntax
921*cda5da8dSAndroid Build Coastguard Worker          error.  Thus, state merging (from LALR or IELR) and default
922*cda5da8dSAndroid Build Coastguard Worker          reductions corrupt the expected token list.  However, the
923*cda5da8dSAndroid Build Coastguard Worker          list is correct for canonical LR with one exception: it
924*cda5da8dSAndroid Build Coastguard Worker          will still contain any token that will not be accepted due
925*cda5da8dSAndroid Build Coastguard Worker          to an error action in a later state.
926*cda5da8dSAndroid Build Coastguard Worker     */
927*cda5da8dSAndroid Build Coastguard Worker     int yycount = 0;
928*cda5da8dSAndroid Build Coastguard Worker     if (yyctx.getToken() != ]b4_symbol(empty, kind)[)
929*cda5da8dSAndroid Build Coastguard Worker       {
930*cda5da8dSAndroid Build Coastguard Worker         if (yyarg !is null)
931*cda5da8dSAndroid Build Coastguard Worker           yyarg[yycount] = yyctx.getToken();
932*cda5da8dSAndroid Build Coastguard Worker         yycount += 1;
933*cda5da8dSAndroid Build Coastguard Worker         yycount += yyctx.getExpectedTokens(yyarg, 1, yyargn);
934*cda5da8dSAndroid Build Coastguard Worker       }
935*cda5da8dSAndroid Build Coastguard Worker     return yycount;
936*cda5da8dSAndroid Build Coastguard Worker   }
937*cda5da8dSAndroid Build Coastguard Worker ]])[
938*cda5da8dSAndroid Build Coastguard Worker 
939*cda5da8dSAndroid Build Coastguard Worker 
940*cda5da8dSAndroid Build Coastguard Worker   /**
941*cda5da8dSAndroid Build Coastguard Worker    * Information needed to get the list of expected tokens and to forge
942*cda5da8dSAndroid Build Coastguard Worker    * a syntax error diagnostic.
943*cda5da8dSAndroid Build Coastguard Worker    */
944*cda5da8dSAndroid Build Coastguard Worker   public static final class Context
945*cda5da8dSAndroid Build Coastguard Worker   {]b4_lac_if([[
946*cda5da8dSAndroid Build Coastguard Worker     private ]b4_parser_class[ yyparser;]])[
947*cda5da8dSAndroid Build Coastguard Worker     private const(YYStack) yystack;
948*cda5da8dSAndroid Build Coastguard Worker     private SymbolKind yytoken;]b4_locations_if([[
949*cda5da8dSAndroid Build Coastguard Worker     private const(Location) yylocation;]])[
950*cda5da8dSAndroid Build Coastguard Worker 
951*cda5da8dSAndroid Build Coastguard Worker     this(]b4_lac_if([[]b4_parser_class[ parser, ]])[YYStack stack, SymbolKind kind]b4_locations_if([[, Location loc]])[)
952*cda5da8dSAndroid Build Coastguard Worker     {]b4_lac_if([[
953*cda5da8dSAndroid Build Coastguard Worker         yyparser = parser;]])[
954*cda5da8dSAndroid Build Coastguard Worker       yystack = stack;
955*cda5da8dSAndroid Build Coastguard Worker       yytoken = kind;]b4_locations_if([[
956*cda5da8dSAndroid Build Coastguard Worker       yylocation = loc;]])[
957*cda5da8dSAndroid Build Coastguard Worker     }
958*cda5da8dSAndroid Build Coastguard Worker 
959*cda5da8dSAndroid Build Coastguard Worker     final SymbolKind getToken() const
960*cda5da8dSAndroid Build Coastguard Worker     {
961*cda5da8dSAndroid Build Coastguard Worker       return yytoken;
962*cda5da8dSAndroid Build Coastguard Worker     }]b4_locations_if([[
963*cda5da8dSAndroid Build Coastguard Worker 
964*cda5da8dSAndroid Build Coastguard Worker     final const(Location) getLocation() const
965*cda5da8dSAndroid Build Coastguard Worker     {
966*cda5da8dSAndroid Build Coastguard Worker       return yylocation;
967*cda5da8dSAndroid Build Coastguard Worker     }]])[
968*cda5da8dSAndroid Build Coastguard Worker     /**
969*cda5da8dSAndroid Build Coastguard Worker      * Put in YYARG at most YYARGN of the expected tokens given the
970*cda5da8dSAndroid Build Coastguard Worker      * current YYCTX, and return the number of tokens stored in YYARG.  If
971*cda5da8dSAndroid Build Coastguard Worker      * YYARG is null, return the number of expected tokens (guaranteed to
972*cda5da8dSAndroid Build Coastguard Worker      * be less than YYNTOKENS).
973*cda5da8dSAndroid Build Coastguard Worker      */
974*cda5da8dSAndroid Build Coastguard Worker     int getExpectedTokens(SymbolKind[] yyarg, int yyargn)]b4_lac_if([[]], [[ const]])[
975*cda5da8dSAndroid Build Coastguard Worker     {
976*cda5da8dSAndroid Build Coastguard Worker       return getExpectedTokens(yyarg, 0, yyargn);
977*cda5da8dSAndroid Build Coastguard Worker     }
978*cda5da8dSAndroid Build Coastguard Worker 
979*cda5da8dSAndroid Build Coastguard Worker     int getExpectedTokens(SymbolKind[] yyarg, int yyoffset, int yyargn)]b4_lac_if([[]], [[ const]])[
980*cda5da8dSAndroid Build Coastguard Worker     {
981*cda5da8dSAndroid Build Coastguard Worker       int yycount = yyoffset;]b4_lac_if([b4_parse_trace_if([[
982*cda5da8dSAndroid Build Coastguard Worker       // Execute LAC once. We don't care if it is successful, we
983*cda5da8dSAndroid Build Coastguard Worker       // only do it for the sake of debugging output.
984*cda5da8dSAndroid Build Coastguard Worker 
985*cda5da8dSAndroid Build Coastguard Worker       if (!yyparser.yylacEstablished)
986*cda5da8dSAndroid Build Coastguard Worker         yyparser.yylacCheck(yystack, yytoken);
987*cda5da8dSAndroid Build Coastguard Worker ]])[
988*cda5da8dSAndroid Build Coastguard Worker       for (int yyx = 0; yyx < yyntokens_; ++yyx)
989*cda5da8dSAndroid Build Coastguard Worker         {
990*cda5da8dSAndroid Build Coastguard Worker           SymbolKind yysym = SymbolKind(yyx);
991*cda5da8dSAndroid Build Coastguard Worker           if (yysym != ]b4_symbol(error, kind)[
992*cda5da8dSAndroid Build Coastguard Worker               && yysym != ]b4_symbol(undef, kind)[
993*cda5da8dSAndroid Build Coastguard Worker               && yyparser.yylacCheck(yystack, yysym))
994*cda5da8dSAndroid Build Coastguard Worker             {
995*cda5da8dSAndroid Build Coastguard Worker               if (yyarg == null)
996*cda5da8dSAndroid Build Coastguard Worker                 yycount += 1;
997*cda5da8dSAndroid Build Coastguard Worker               else if (yycount == yyargn)
998*cda5da8dSAndroid Build Coastguard Worker                 return 0;
999*cda5da8dSAndroid Build Coastguard Worker               else
1000*cda5da8dSAndroid Build Coastguard Worker                 yyarg[yycount++] = yysym;
1001*cda5da8dSAndroid Build Coastguard Worker             }
1002*cda5da8dSAndroid Build Coastguard Worker         }]], [[
1003*cda5da8dSAndroid Build Coastguard Worker       int yyn = yypact_[this.yystack.stateAt(0)];
1004*cda5da8dSAndroid Build Coastguard Worker       if (!yyPactValueIsDefault(yyn))
1005*cda5da8dSAndroid Build Coastguard Worker       {
1006*cda5da8dSAndroid Build Coastguard Worker         /* Start YYX at -YYN if negative to avoid negative
1007*cda5da8dSAndroid Build Coastguard Worker            indexes in YYCHECK.  In other words, skip the first
1008*cda5da8dSAndroid Build Coastguard Worker            -YYN actions for this state because they are default
1009*cda5da8dSAndroid Build Coastguard Worker            actions.  */
1010*cda5da8dSAndroid Build Coastguard Worker         int yyxbegin = yyn < 0 ? -yyn : 0;
1011*cda5da8dSAndroid Build Coastguard Worker         /* Stay within bounds of both yycheck and yytname.  */
1012*cda5da8dSAndroid Build Coastguard Worker         int yychecklim = yylast_ - yyn + 1;
1013*cda5da8dSAndroid Build Coastguard Worker         int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
1014*cda5da8dSAndroid Build Coastguard Worker         for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
1015*cda5da8dSAndroid Build Coastguard Worker           if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
1016*cda5da8dSAndroid Build Coastguard Worker               && !yyTableValueIsError(yytable_[yyx + yyn]))
1017*cda5da8dSAndroid Build Coastguard Worker           {
1018*cda5da8dSAndroid Build Coastguard Worker             if (yyarg is null)
1019*cda5da8dSAndroid Build Coastguard Worker               ++yycount;
1020*cda5da8dSAndroid Build Coastguard Worker             else if (yycount == yyargn)
1021*cda5da8dSAndroid Build Coastguard Worker               return 0;
1022*cda5da8dSAndroid Build Coastguard Worker             else
1023*cda5da8dSAndroid Build Coastguard Worker               yyarg[yycount++] = SymbolKind(yyx);
1024*cda5da8dSAndroid Build Coastguard Worker           }
1025*cda5da8dSAndroid Build Coastguard Worker       }]])[
1026*cda5da8dSAndroid Build Coastguard Worker       if (yyarg !is null && yycount == yyoffset && yyoffset < yyargn)
1027*cda5da8dSAndroid Build Coastguard Worker         yyarg[yyoffset] = ]b4_symbol(empty, kind)[;
1028*cda5da8dSAndroid Build Coastguard Worker       return yycount - yyoffset;
1029*cda5da8dSAndroid Build Coastguard Worker     }
1030*cda5da8dSAndroid Build Coastguard Worker   }
1031*cda5da8dSAndroid Build Coastguard Worker 
1032*cda5da8dSAndroid Build Coastguard Worker ]b4_lac_if([[
1033*cda5da8dSAndroid Build Coastguard Worker   /** Check the lookahead yytoken.
1034*cda5da8dSAndroid Build Coastguard Worker    * \returns  true iff the token will be eventually shifted.
1035*cda5da8dSAndroid Build Coastguard Worker    */
1036*cda5da8dSAndroid Build Coastguard Worker   bool yylacCheck(const YYStack yystack, SymbolKind yytoken)
1037*cda5da8dSAndroid Build Coastguard Worker   {
1038*cda5da8dSAndroid Build Coastguard Worker     // Logically, the yylacStack's lifetime is confined to this function.
1039*cda5da8dSAndroid Build Coastguard Worker     // Clear it, to get rid of potential left-overs from previous call.
1040*cda5da8dSAndroid Build Coastguard Worker     destroy(yylacStack);
1041*cda5da8dSAndroid Build Coastguard Worker     // Reduce until we encounter a shift and thereby accept the token.
1042*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_trace_if([[
1043*cda5da8dSAndroid Build Coastguard Worker     yycdebug("LAC: checking lookahead " ~ format("%s", yytoken) ~ ":");]])[
1044*cda5da8dSAndroid Build Coastguard Worker     int lacTop = 0;
1045*cda5da8dSAndroid Build Coastguard Worker     while (true)
1046*cda5da8dSAndroid Build Coastguard Worker     {
1047*cda5da8dSAndroid Build Coastguard Worker       int topState = (yylacStack.length == 0
1048*cda5da8dSAndroid Build Coastguard Worker                       ? yystack.stateAt(lacTop)
1049*cda5da8dSAndroid Build Coastguard Worker                       : yylacStack[$ - 1]);
1050*cda5da8dSAndroid Build Coastguard Worker       int yyrule = yypact_[topState];
1051*cda5da8dSAndroid Build Coastguard Worker       if (yyPactValueIsDefault(yyrule)
1052*cda5da8dSAndroid Build Coastguard Worker           || (yyrule += yytoken) < 0 || yylast_ < yyrule
1053*cda5da8dSAndroid Build Coastguard Worker           || yycheck_[yyrule] != yytoken)
1054*cda5da8dSAndroid Build Coastguard Worker       {
1055*cda5da8dSAndroid Build Coastguard Worker         // Use the default action.
1056*cda5da8dSAndroid Build Coastguard Worker         yyrule = yydefact_[+topState];
1057*cda5da8dSAndroid Build Coastguard Worker         if (yyrule == 0)
1058*cda5da8dSAndroid Build Coastguard Worker         {]b4_parse_trace_if([[
1059*cda5da8dSAndroid Build Coastguard Worker           yycdebugln(" Err");]])[
1060*cda5da8dSAndroid Build Coastguard Worker           return false;
1061*cda5da8dSAndroid Build Coastguard Worker         }
1062*cda5da8dSAndroid Build Coastguard Worker       }
1063*cda5da8dSAndroid Build Coastguard Worker       else
1064*cda5da8dSAndroid Build Coastguard Worker       {
1065*cda5da8dSAndroid Build Coastguard Worker         // Use the action from yytable.
1066*cda5da8dSAndroid Build Coastguard Worker         yyrule = yytable_[yyrule];
1067*cda5da8dSAndroid Build Coastguard Worker         if (yyTableValueIsError(yyrule))
1068*cda5da8dSAndroid Build Coastguard Worker         {]b4_parse_trace_if([[
1069*cda5da8dSAndroid Build Coastguard Worker           yycdebugln(" Err");]])[
1070*cda5da8dSAndroid Build Coastguard Worker           return false;
1071*cda5da8dSAndroid Build Coastguard Worker         }
1072*cda5da8dSAndroid Build Coastguard Worker         if (0 < yyrule)
1073*cda5da8dSAndroid Build Coastguard Worker         {]b4_parse_trace_if([[
1074*cda5da8dSAndroid Build Coastguard Worker           yycdebugln(" S" ~ to!string(yyrule));]])[
1075*cda5da8dSAndroid Build Coastguard Worker           return true;
1076*cda5da8dSAndroid Build Coastguard Worker         }
1077*cda5da8dSAndroid Build Coastguard Worker         yyrule = -yyrule;
1078*cda5da8dSAndroid Build Coastguard Worker       }
1079*cda5da8dSAndroid Build Coastguard Worker       // By now we know we have to simulate a reduce.
1080*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_trace_if([[
1081*cda5da8dSAndroid Build Coastguard Worker       yycdebug(" R" ~ to!string(yyrule - 1));]])[
1082*cda5da8dSAndroid Build Coastguard Worker       // Pop the corresponding number of values from the stack.
1083*cda5da8dSAndroid Build Coastguard Worker       {
1084*cda5da8dSAndroid Build Coastguard Worker         int yylen = yyr2_[yyrule];
1085*cda5da8dSAndroid Build Coastguard Worker         // First pop from the LAC stack as many tokens as possible.
1086*cda5da8dSAndroid Build Coastguard Worker         int lacSize = cast (int) yylacStack.length;
1087*cda5da8dSAndroid Build Coastguard Worker         if (yylen < lacSize)
1088*cda5da8dSAndroid Build Coastguard Worker         {
1089*cda5da8dSAndroid Build Coastguard Worker           yylacStack.length -= yylen;
1090*cda5da8dSAndroid Build Coastguard Worker           yylen = 0;
1091*cda5da8dSAndroid Build Coastguard Worker         }
1092*cda5da8dSAndroid Build Coastguard Worker         else if (lacSize != 0)
1093*cda5da8dSAndroid Build Coastguard Worker         {
1094*cda5da8dSAndroid Build Coastguard Worker           destroy(yylacStack);
1095*cda5da8dSAndroid Build Coastguard Worker           yylen -= lacSize;
1096*cda5da8dSAndroid Build Coastguard Worker         }
1097*cda5da8dSAndroid Build Coastguard Worker         // Only afterwards look at the main stack.
1098*cda5da8dSAndroid Build Coastguard Worker         // We simulate popping elements by incrementing lacTop.
1099*cda5da8dSAndroid Build Coastguard Worker         lacTop += yylen;
1100*cda5da8dSAndroid Build Coastguard Worker       }
1101*cda5da8dSAndroid Build Coastguard Worker       // Keep topState in sync with the updated stack.
1102*cda5da8dSAndroid Build Coastguard Worker       topState = (yylacStack.length == 0
1103*cda5da8dSAndroid Build Coastguard Worker                   ? yystack.stateAt(lacTop)
1104*cda5da8dSAndroid Build Coastguard Worker                   : yylacStack[$ - 1]);
1105*cda5da8dSAndroid Build Coastguard Worker       // Push the resulting state of the reduction.
1106*cda5da8dSAndroid Build Coastguard Worker       int state = yyLRGotoState(topState, yyr1_[yyrule]);]b4_parse_trace_if([[
1107*cda5da8dSAndroid Build Coastguard Worker       yycdebug(" G" ~ to!string(state));]])[
1108*cda5da8dSAndroid Build Coastguard Worker       yylacStack.length++;
1109*cda5da8dSAndroid Build Coastguard Worker       yylacStack[$ - 1] = state;
1110*cda5da8dSAndroid Build Coastguard Worker     }
1111*cda5da8dSAndroid Build Coastguard Worker   }
1112*cda5da8dSAndroid Build Coastguard Worker 
1113*cda5da8dSAndroid Build Coastguard Worker   /** Establish the initial context if no initial context currently exists.
1114*cda5da8dSAndroid Build Coastguard Worker    * \returns  true iff the token will be eventually shifted.
1115*cda5da8dSAndroid Build Coastguard Worker    */
1116*cda5da8dSAndroid Build Coastguard Worker   bool yylacEstablish(YYStack yystack, SymbolKind yytoken)
1117*cda5da8dSAndroid Build Coastguard Worker   {
1118*cda5da8dSAndroid Build Coastguard Worker   /* Establish the initial context for the current lookahead if no initial
1119*cda5da8dSAndroid Build Coastguard Worker      context is currently established.
1120*cda5da8dSAndroid Build Coastguard Worker 
1121*cda5da8dSAndroid Build Coastguard Worker      We define a context as a snapshot of the parser stacks.  We define
1122*cda5da8dSAndroid Build Coastguard Worker      the initial context for a lookahead as the context in which the
1123*cda5da8dSAndroid Build Coastguard Worker      parser initially examines that lookahead in order to select a
1124*cda5da8dSAndroid Build Coastguard Worker      syntactic action.  Thus, if the lookahead eventually proves
1125*cda5da8dSAndroid Build Coastguard Worker      syntactically unacceptable (possibly in a later context reached via a
1126*cda5da8dSAndroid Build Coastguard Worker      series of reductions), the initial context can be used to determine
1127*cda5da8dSAndroid Build Coastguard Worker      the exact set of tokens that would be syntactically acceptable in the
1128*cda5da8dSAndroid Build Coastguard Worker      lookahead's place.  Moreover, it is the context after which any
1129*cda5da8dSAndroid Build Coastguard Worker      further semantic actions would be erroneous because they would be
1130*cda5da8dSAndroid Build Coastguard Worker      determined by a syntactically unacceptable token.
1131*cda5da8dSAndroid Build Coastguard Worker 
1132*cda5da8dSAndroid Build Coastguard Worker      yylacEstablish should be invoked when a reduction is about to be
1133*cda5da8dSAndroid Build Coastguard Worker      performed in an inconsistent state (which, for the purposes of LAC,
1134*cda5da8dSAndroid Build Coastguard Worker      includes consistent states that don't know they're consistent because
1135*cda5da8dSAndroid Build Coastguard Worker      their default reductions have been disabled).
1136*cda5da8dSAndroid Build Coastguard Worker 
1137*cda5da8dSAndroid Build Coastguard Worker      For parse.lac=full, the implementation of yylacEstablish is as
1138*cda5da8dSAndroid Build Coastguard Worker      follows.  If no initial context is currently established for the
1139*cda5da8dSAndroid Build Coastguard Worker      current lookahead, then check if that lookahead can eventually be
1140*cda5da8dSAndroid Build Coastguard Worker      shifted if syntactic actions continue from the current context.  */
1141*cda5da8dSAndroid Build Coastguard Worker     if (yylacEstablished)
1142*cda5da8dSAndroid Build Coastguard Worker       return true;
1143*cda5da8dSAndroid Build Coastguard Worker     else
1144*cda5da8dSAndroid Build Coastguard Worker     {]b4_parse_trace_if([[
1145*cda5da8dSAndroid Build Coastguard Worker         yycdebugln("LAC: initial context established for " ~ format("%s", yytoken));]])[
1146*cda5da8dSAndroid Build Coastguard Worker         yylacEstablished = true;
1147*cda5da8dSAndroid Build Coastguard Worker         return yylacCheck(yystack, yytoken);
1148*cda5da8dSAndroid Build Coastguard Worker     }
1149*cda5da8dSAndroid Build Coastguard Worker   }
1150*cda5da8dSAndroid Build Coastguard Worker 
1151*cda5da8dSAndroid Build Coastguard Worker   /** Discard any previous initial lookahead context because of event.
1152*cda5da8dSAndroid Build Coastguard Worker    * \param event  the event which caused the lookahead to be discarded.
1153*cda5da8dSAndroid Build Coastguard Worker    *               Only used for debbuging output.  */
1154*cda5da8dSAndroid Build Coastguard Worker   void yylacDiscard(string event)
1155*cda5da8dSAndroid Build Coastguard Worker   {
1156*cda5da8dSAndroid Build Coastguard Worker   /* Discard any previous initial lookahead context because of Event,
1157*cda5da8dSAndroid Build Coastguard Worker      which may be a lookahead change or an invalidation of the currently
1158*cda5da8dSAndroid Build Coastguard Worker      established initial context for the current lookahead.
1159*cda5da8dSAndroid Build Coastguard Worker 
1160*cda5da8dSAndroid Build Coastguard Worker      The most common example of a lookahead change is a shift.  An example
1161*cda5da8dSAndroid Build Coastguard Worker      of both cases is syntax error recovery.  That is, a syntax error
1162*cda5da8dSAndroid Build Coastguard Worker      occurs when the lookahead is syntactically erroneous for the
1163*cda5da8dSAndroid Build Coastguard Worker      currently established initial context, so error recovery manipulates
1164*cda5da8dSAndroid Build Coastguard Worker      the parser stacks to try to find a new initial context in which the
1165*cda5da8dSAndroid Build Coastguard Worker      current lookahead is syntactically acceptable.  If it fails to find
1166*cda5da8dSAndroid Build Coastguard Worker      such a context, it discards the lookahead.  */
1167*cda5da8dSAndroid Build Coastguard Worker     if (yylacEstablished)
1168*cda5da8dSAndroid Build Coastguard Worker     {]b4_parse_trace_if([[
1169*cda5da8dSAndroid Build Coastguard Worker       yycdebugln("LAC: initial context discarded due to " ~ event);]])[
1170*cda5da8dSAndroid Build Coastguard Worker       yylacEstablished = false;
1171*cda5da8dSAndroid Build Coastguard Worker     }
1172*cda5da8dSAndroid Build Coastguard Worker   }
1173*cda5da8dSAndroid Build Coastguard Worker 
1174*cda5da8dSAndroid Build Coastguard Worker   /** The stack for LAC.
1175*cda5da8dSAndroid Build Coastguard Worker    * Logically, the yylacStack's lifetime is confined to the function
1176*cda5da8dSAndroid Build Coastguard Worker    * yylacCheck. We just store it as a member of this class to hold
1177*cda5da8dSAndroid Build Coastguard Worker    * on to the memory and to avoid frequent reallocations.
1178*cda5da8dSAndroid Build Coastguard Worker    */
1179*cda5da8dSAndroid Build Coastguard Worker   int[] yylacStack;
1180*cda5da8dSAndroid Build Coastguard Worker   /**  Whether an initial LAC context was established. */
1181*cda5da8dSAndroid Build Coastguard Worker   bool yylacEstablished;
1182*cda5da8dSAndroid Build Coastguard Worker ]])[
1183*cda5da8dSAndroid Build Coastguard Worker 
1184*cda5da8dSAndroid Build Coastguard Worker   /**
1185*cda5da8dSAndroid Build Coastguard Worker    * Whether the given <code>yypact_</code> value indicates a defaulted state.
1186*cda5da8dSAndroid Build Coastguard Worker    * @@param yyvalue   the value to check
1187*cda5da8dSAndroid Build Coastguard Worker    */
1188*cda5da8dSAndroid Build Coastguard Worker   private static bool yyPactValueIsDefault(int yyvalue)
1189*cda5da8dSAndroid Build Coastguard Worker   {
1190*cda5da8dSAndroid Build Coastguard Worker     return yyvalue == yypact_ninf_;
1191*cda5da8dSAndroid Build Coastguard Worker   }
1192*cda5da8dSAndroid Build Coastguard Worker 
1193*cda5da8dSAndroid Build Coastguard Worker   /**
1194*cda5da8dSAndroid Build Coastguard Worker    * Whether the given <code>yytable_</code> value indicates a syntax error.
1195*cda5da8dSAndroid Build Coastguard Worker    * @@param yyvalue   the value to check
1196*cda5da8dSAndroid Build Coastguard Worker    */
1197*cda5da8dSAndroid Build Coastguard Worker   private static bool yyTableValueIsError(int yyvalue)
1198*cda5da8dSAndroid Build Coastguard Worker   {
1199*cda5da8dSAndroid Build Coastguard Worker     return yyvalue == yytable_ninf_;
1200*cda5da8dSAndroid Build Coastguard Worker   }
1201*cda5da8dSAndroid Build Coastguard Worker 
1202*cda5da8dSAndroid Build Coastguard Worker   /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
1203*cda5da8dSAndroid Build Coastguard Worker      STATE-NUM.  */
1204*cda5da8dSAndroid Build Coastguard Worker   private static immutable ]b4_int_type_for([b4_pact])[ yypact_ninf_ = ]b4_pact_ninf[;
1205*cda5da8dSAndroid Build Coastguard Worker 
1206*cda5da8dSAndroid Build Coastguard Worker   /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
1207*cda5da8dSAndroid Build Coastguard Worker      positive, shift that token.  If negative, reduce the rule which
1208*cda5da8dSAndroid Build Coastguard Worker      number is the opposite.  If YYTABLE_NINF_, syntax error.  */
1209*cda5da8dSAndroid Build Coastguard Worker   private static immutable ]b4_int_type_for([b4_table])[ yytable_ninf_ = ]b4_table_ninf[;
1210*cda5da8dSAndroid Build Coastguard Worker 
1211*cda5da8dSAndroid Build Coastguard Worker   ]b4_parser_tables_define[
1212*cda5da8dSAndroid Build Coastguard Worker 
1213*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_trace_if([[
1214*cda5da8dSAndroid Build Coastguard Worker   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
1215*cda5da8dSAndroid Build Coastguard Worker   private static immutable ]b4_int_type_for([b4_rline])[[] yyrline_ =
1216*cda5da8dSAndroid Build Coastguard Worker   @{
1217*cda5da8dSAndroid Build Coastguard Worker   ]b4_rline[
1218*cda5da8dSAndroid Build Coastguard Worker   @};
1219*cda5da8dSAndroid Build Coastguard Worker 
1220*cda5da8dSAndroid Build Coastguard Worker   // Report on the debug stream that the rule yyrule is going to be reduced.
1221*cda5da8dSAndroid Build Coastguard Worker   private final void yy_reduce_print (int yyrule, ref YYStack yystack)
1222*cda5da8dSAndroid Build Coastguard Worker   {
1223*cda5da8dSAndroid Build Coastguard Worker     if (yydebug == 0)
1224*cda5da8dSAndroid Build Coastguard Worker       return;
1225*cda5da8dSAndroid Build Coastguard Worker 
1226*cda5da8dSAndroid Build Coastguard Worker     int yylno = yyrline_[yyrule];
1227*cda5da8dSAndroid Build Coastguard Worker     int yynrhs = yyr2_[yyrule];
1228*cda5da8dSAndroid Build Coastguard Worker     /* Print the symbols being reduced, and their result.  */
1229*cda5da8dSAndroid Build Coastguard Worker     yycdebugln (format("Reducing stack by rule %d (line %d):",
1230*cda5da8dSAndroid Build Coastguard Worker                 yyrule - 1, yylno));
1231*cda5da8dSAndroid Build Coastguard Worker 
1232*cda5da8dSAndroid Build Coastguard Worker     /* The symbols being reduced.  */
1233*cda5da8dSAndroid Build Coastguard Worker     for (int yyi = 0; yyi < yynrhs; yyi++)
1234*cda5da8dSAndroid Build Coastguard Worker       yy_symbol_print (format("   $%d =", yyi + 1),
1235*cda5da8dSAndroid Build Coastguard Worker                        to!SymbolKind (yystos_[yystack.stateAt(yynrhs - (yyi + 1))]),
1236*cda5da8dSAndroid Build Coastguard Worker                        ]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([,
1237*cda5da8dSAndroid Build Coastguard Worker                        b4_rhs_location(yynrhs, yyi + 1)])[);
1238*cda5da8dSAndroid Build Coastguard Worker   }
1239*cda5da8dSAndroid Build Coastguard Worker ]])[
1240*cda5da8dSAndroid Build Coastguard Worker 
1241*cda5da8dSAndroid Build Coastguard Worker   private static auto yytranslate_ (int t)
1242*cda5da8dSAndroid Build Coastguard Worker   {
1243*cda5da8dSAndroid Build Coastguard Worker ]b4_api_token_raw_if(
1244*cda5da8dSAndroid Build Coastguard Worker [[    return SymbolKind(t);]],
1245*cda5da8dSAndroid Build Coastguard Worker [[    /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
1246*cda5da8dSAndroid Build Coastguard Worker     immutable ]b4_int_type_for([b4_translate])[[] translate_table =
1247*cda5da8dSAndroid Build Coastguard Worker     @{
1248*cda5da8dSAndroid Build Coastguard Worker   ]b4_translate[
1249*cda5da8dSAndroid Build Coastguard Worker     @};
1250*cda5da8dSAndroid Build Coastguard Worker 
1251*cda5da8dSAndroid Build Coastguard Worker     // Last valid token kind.
1252*cda5da8dSAndroid Build Coastguard Worker     immutable int code_max = ]b4_code_max[;
1253*cda5da8dSAndroid Build Coastguard Worker 
1254*cda5da8dSAndroid Build Coastguard Worker     if (t <= 0)
1255*cda5da8dSAndroid Build Coastguard Worker       return ]b4_symbol(eof, kind)[;
1256*cda5da8dSAndroid Build Coastguard Worker     else if (t <= code_max)
1257*cda5da8dSAndroid Build Coastguard Worker       return SymbolKind(translate_table[t]);
1258*cda5da8dSAndroid Build Coastguard Worker     else
1259*cda5da8dSAndroid Build Coastguard Worker       return ]b4_symbol(undef, kind)[;]])[
1260*cda5da8dSAndroid Build Coastguard Worker   }
1261*cda5da8dSAndroid Build Coastguard Worker 
1262*cda5da8dSAndroid Build Coastguard Worker   private static immutable int yylast_ = ]b4_last[;
1263*cda5da8dSAndroid Build Coastguard Worker   private static immutable int yynnts_ = ]b4_nterms_number[;
1264*cda5da8dSAndroid Build Coastguard Worker   private static immutable int yyfinal_ = ]b4_final_state_number[;
1265*cda5da8dSAndroid Build Coastguard Worker   private static immutable int yyntokens_ = ]b4_tokens_number[;
1266*cda5da8dSAndroid Build Coastguard Worker 
1267*cda5da8dSAndroid Build Coastguard Worker   private final struct YYStackElement {
1268*cda5da8dSAndroid Build Coastguard Worker     int state;
1269*cda5da8dSAndroid Build Coastguard Worker     Value value;]b4_locations_if(
1270*cda5da8dSAndroid Build Coastguard Worker     b4_location_type[[] location;])[
1271*cda5da8dSAndroid Build Coastguard Worker   }
1272*cda5da8dSAndroid Build Coastguard Worker 
1273*cda5da8dSAndroid Build Coastguard Worker   private final struct YYStack {
1274*cda5da8dSAndroid Build Coastguard Worker     private YYStackElement[] stack = [];
1275*cda5da8dSAndroid Build Coastguard Worker 
1276*cda5da8dSAndroid Build Coastguard Worker     public final ulong height()
1277*cda5da8dSAndroid Build Coastguard Worker     {
1278*cda5da8dSAndroid Build Coastguard Worker       return stack.length;
1279*cda5da8dSAndroid Build Coastguard Worker     }
1280*cda5da8dSAndroid Build Coastguard Worker 
1281*cda5da8dSAndroid Build Coastguard Worker     public final void push (int state, Value value]dnl
1282*cda5da8dSAndroid Build Coastguard Worker   b4_locations_if([, ref Location loc])[)
1283*cda5da8dSAndroid Build Coastguard Worker     {
1284*cda5da8dSAndroid Build Coastguard Worker       stack ~= YYStackElement(state, value]b4_locations_if([, loc])[);
1285*cda5da8dSAndroid Build Coastguard Worker     }
1286*cda5da8dSAndroid Build Coastguard Worker 
1287*cda5da8dSAndroid Build Coastguard Worker     public final void pop ()
1288*cda5da8dSAndroid Build Coastguard Worker     {
1289*cda5da8dSAndroid Build Coastguard Worker       pop (1);
1290*cda5da8dSAndroid Build Coastguard Worker     }
1291*cda5da8dSAndroid Build Coastguard Worker 
1292*cda5da8dSAndroid Build Coastguard Worker     public final void pop (int num)
1293*cda5da8dSAndroid Build Coastguard Worker     {
1294*cda5da8dSAndroid Build Coastguard Worker       stack.length -= num;
1295*cda5da8dSAndroid Build Coastguard Worker     }
1296*cda5da8dSAndroid Build Coastguard Worker 
1297*cda5da8dSAndroid Build Coastguard Worker     public final int stateAt (int i) const
1298*cda5da8dSAndroid Build Coastguard Worker     {
1299*cda5da8dSAndroid Build Coastguard Worker       return stack[$-i-1].state;
1300*cda5da8dSAndroid Build Coastguard Worker     }
1301*cda5da8dSAndroid Build Coastguard Worker 
1302*cda5da8dSAndroid Build Coastguard Worker ]b4_locations_if([[
1303*cda5da8dSAndroid Build Coastguard Worker     public final ref Location locationAt (int i)
1304*cda5da8dSAndroid Build Coastguard Worker     {
1305*cda5da8dSAndroid Build Coastguard Worker       return stack[$-i-1].location;
1306*cda5da8dSAndroid Build Coastguard Worker     }]])[
1307*cda5da8dSAndroid Build Coastguard Worker 
1308*cda5da8dSAndroid Build Coastguard Worker     public final ref Value valueAt (int i)
1309*cda5da8dSAndroid Build Coastguard Worker     {
1310*cda5da8dSAndroid Build Coastguard Worker       return stack[$-i-1].value;
1311*cda5da8dSAndroid Build Coastguard Worker     }
1312*cda5da8dSAndroid Build Coastguard Worker ]b4_parse_trace_if([[
1313*cda5da8dSAndroid Build Coastguard Worker     // Print the state stack on the debug stream.
1314*cda5da8dSAndroid Build Coastguard Worker     public final void print (File stream)
1315*cda5da8dSAndroid Build Coastguard Worker     {
1316*cda5da8dSAndroid Build Coastguard Worker       stream.write ("Stack now");
1317*cda5da8dSAndroid Build Coastguard Worker       for (int i = 0; i < stack.length; i++)
1318*cda5da8dSAndroid Build Coastguard Worker         stream.write (" ", stack[i].state);
1319*cda5da8dSAndroid Build Coastguard Worker       stream.writeln ();
1320*cda5da8dSAndroid Build Coastguard Worker     }]])[
1321*cda5da8dSAndroid Build Coastguard Worker   }
1322*cda5da8dSAndroid Build Coastguard Worker ]b4_percent_code_get[
1323*cda5da8dSAndroid Build Coastguard Worker }
1324*cda5da8dSAndroid Build Coastguard Worker ]b4_percent_code_get([[epilogue]])[]dnl
1325*cda5da8dSAndroid Build Coastguard Worker b4_epilogue[]dnl
1326*cda5da8dSAndroid Build Coastguard Worker b4_output_end
1327