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