1 # Java skeleton for Bison -*- autoconf -*- 2 3 # Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc. 4 5 # This program is free software: you can redistribute it and/or modify 6 # it under the terms of the GNU General Public License as published by 7 # the Free Software Foundation, either version 3 of the License, or 8 # (at your option) any later version. 9 # 10 # This program is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public License 16 # along with this program. If not, see <https://www.gnu.org/licenses/>. 17 18 m4_include(b4_skeletonsdir/[java.m4]) 19 20 b4_defines_if([b4_complain([%defines does not make sense in Java])]) 21 22 m4_define([b4_symbol_no_destructor_assert], 23 [b4_symbol_if([$1], [has_destructor], 24 [b4_complain_at(m4_unquote(b4_symbol([$1], [destructor_loc])), 25 [%destructor does not make sense in Java])])]) 26 b4_symbol_foreach([b4_symbol_no_destructor_assert]) 27 28 # Setup some macros for api.push-pull. 29 b4_percent_define_default([[api.push-pull]], [[pull]]) 30 b4_percent_define_check_values([[[[api.push-pull]], 31 [[pull]], [[push]], [[both]]]]) 32 33 # Define m4 conditional macros that encode the value 34 # of the api.push-pull flag. 35 b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]]) 36 b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]]) 37 m4_case(b4_percent_define_get([[api.push-pull]]), 38 [pull], [m4_define([b4_push_flag], [[0]])], 39 [push], [m4_define([b4_pull_flag], [[0]])]) 40 41 # Define a macro to be true when api.push-pull has the value "both". 42 m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])]) 43 44 # Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing 45 # tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the 46 # behavior of Bison at all when push parsing is already requested. 47 b4_define_flag_if([use_push_for_pull]) 48 b4_use_push_for_pull_if([ 49 b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])], 50 [m4_define([b4_push_flag], [[1]])])]) 51 52 # Define a macro to encapsulate the parse state variables. This 53 # allows them to be defined either in parse() when doing pull parsing, 54 # or as class instance variable when doing push parsing. 55 m4_define([b4_define_state],[[ 56 /* Lookahead token kind. */ 57 int yychar = YYEMPTY_; 58 /* Lookahead symbol kind. */ 59 SymbolKind yytoken = null; 60 61 /* State. */ 62 int yyn = 0; 63 int yylen = 0; 64 int yystate = 0; 65 YYStack yystack = new YYStack (); 66 int label = YYNEWSTATE; 67 68 ]b4_locations_if([[ 69 /* The location where the error started. */ 70 ]b4_location_type[ yyerrloc = null; 71 72 /* Location. */ 73 ]b4_location_type[ yylloc = new ]b4_location_type[ (null, null);]])[ 74 75 /* Semantic value of the lookahead. */ 76 ]b4_yystype[ yylval = null; 77 ]])[ 78 79 ]b4_output_begin([b4_parser_file_name])[ 80 ]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java], 81 [2007-2015, 2018-2021])[ 82 ]b4_disclaimer[ 83 ]b4_percent_define_ifdef([api.package], [package b4_percent_define_get([api.package]);[ 84 ]])[ 85 ]b4_user_pre_prologue[ 86 ]b4_user_post_prologue[ 87 import java.text.MessageFormat; 88 ]b4_percent_code_get([[imports]])[ 89 /** 90 * A Bison parser, automatically generated from <tt>]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[</tt>. 91 * 92 * @@author LALR (1) parser skeleton written by Paolo Bonzini. 93 */ 94 ]b4_parser_class_declaration[ 95 { 96 ]b4_identification[ 97 ][ 98 ]b4_parse_error_bmatch( 99 [detailed\|verbose], [[ 100 /** 101 * True if verbose error messages are enabled. 102 */ 103 private boolean yyErrorVerbose = true; 104 105 /** 106 * Whether verbose error messages are enabled. 107 */ 108 public final boolean getErrorVerbose() { return yyErrorVerbose; } 109 110 /** 111 * Set the verbosity of error messages. 112 * @@param verbose True to request verbose error messages. 113 */ 114 public final void setErrorVerbose(boolean verbose) 115 { yyErrorVerbose = verbose; } 116 ]])[ 117 118 ]b4_locations_if([[ 119 /** 120 * A class defining a pair of positions. Positions, defined by the 121 * <code>]b4_position_type[</code> class, denote a point in the input. 122 * Locations represent a part of the input through the beginning 123 * and ending positions. 124 */ 125 public static class ]b4_location_type[ { 126 /** 127 * The first, inclusive, position in the range. 128 */ 129 public ]b4_position_type[ begin; 130 131 /** 132 * The first position beyond the range. 133 */ 134 public ]b4_position_type[ end; 135 136 /** 137 * Create a <code>]b4_location_type[</code> denoting an empty range located at 138 * a given point. 139 * @@param loc The position at which the range is anchored. 140 */ 141 public ]b4_location_type[ (]b4_position_type[ loc) { 142 this.begin = this.end = loc; 143 } 144 145 /** 146 * Create a <code>]b4_location_type[</code> from the endpoints of the range. 147 * @@param begin The first position included in the range. 148 * @@param end The first position beyond the range. 149 */ 150 public ]b4_location_type[ (]b4_position_type[ begin, ]b4_position_type[ end) { 151 this.begin = begin; 152 this.end = end; 153 } 154 155 /** 156 * Print a representation of the location. For this to be correct, 157 * <code>]b4_position_type[</code> should override the <code>equals</code> 158 * method. 159 */ 160 public String toString () { 161 if (begin.equals (end)) 162 return begin.toString (); 163 else 164 return begin.toString () + "-" + end.toString (); 165 } 166 } 167 168 private ]b4_location_type[ yylloc(YYStack rhs, int n) 169 { 170 if (0 < n) 171 return new ]b4_location_type[(rhs.locationAt(n-1).begin, rhs.locationAt(0).end); 172 else 173 return new ]b4_location_type[(rhs.locationAt(0).end); 174 }]])[ 175 176 ]b4_declare_symbol_enum[ 177 178 /** 179 * Communication interface between the scanner and the Bison-generated 180 * parser <tt>]b4_parser_class[</tt>. 181 */ 182 public interface Lexer { 183 ]b4_token_enums[ 184 /** Deprecated, use ]b4_symbol(0, id)[ instead. */ 185 public static final int EOF = ]b4_symbol(0, id)[; 186 ]b4_pull_if([b4_locations_if([[ 187 /** 188 * Method to retrieve the beginning position of the last scanned token. 189 * @@return the position at which the last scanned token starts. 190 */ 191 ]b4_position_type[ getStartPos(); 192 193 /** 194 * Method to retrieve the ending position of the last scanned token. 195 * @@return the first position beyond the last scanned token. 196 */ 197 ]b4_position_type[ getEndPos();]])[ 198 199 /** 200 * Method to retrieve the semantic value of the last scanned token. 201 * @@return the semantic value of the last scanned token. 202 */ 203 ]b4_yystype[ getLVal(); 204 205 /** 206 * Entry point for the scanner. Returns the token identifier corresponding 207 * to the next token and prepares to return the semantic value 208 * ]b4_locations_if([and beginning/ending positions ])[of the token. 209 * @@return the token identifier corresponding to the next token. 210 */ 211 int yylex()]b4_maybe_throws([b4_lex_throws])[; 212 ]])[ 213 /** 214 * Emit an error]b4_locations_if([ referring to the given location])[in a user-defined way. 215 * 216 *]b4_locations_if([[ @@param loc The location of the element to which the 217 * error message is related.]])[ 218 * @@param msg The string for the error message. 219 */ 220 void yyerror(]b4_locations_if([b4_location_type[ loc, ]])[String msg); 221 222 ]b4_parse_error_bmatch( 223 [custom], [[ 224 /** 225 * Build and emit a "syntax error" message in a user-defined way. 226 * 227 * @@param ctx The context of the error. 228 */ 229 void reportSyntaxError (][Context ctx); 230 ]])[ 231 } 232 233 ]b4_lexer_if([[ 234 private class YYLexer implements Lexer { 235 ]b4_percent_code_get([[lexer]])[ 236 } 237 238 ]])[ 239 /** 240 * The object doing lexical analysis for us. 241 */ 242 private Lexer yylexer; 243 244 ]b4_parse_param_vars[ 245 246 ]b4_lexer_if([[ 247 /** 248 * Instantiates the Bison-generated parser. 249 */ 250 public ]b4_parser_class (b4_parse_param_decl([b4_lex_param_decl])[)]b4_maybe_throws([b4_init_throws])[ 251 { 252 ]b4_percent_code_get([[init]])[ 253 this.yylexer = new YYLexer (]b4_lex_param_call[); 254 ]b4_parse_param_cons[ 255 } 256 ]])[ 257 258 /** 259 * Instantiates the Bison-generated parser. 260 * @@param yylexer The scanner that will supply tokens to the parser. 261 */ 262 ]b4_lexer_if([[protected]], [[public]]) b4_parser_class[ (]b4_parse_param_decl([[Lexer yylexer]])[)]b4_maybe_throws([b4_init_throws])[ 263 { 264 ]b4_percent_code_get([[init]])[ 265 this.yylexer = yylexer; 266 ]b4_parse_param_cons[ 267 } 268 269 ]b4_parse_trace_if([[ 270 private java.io.PrintStream yyDebugStream = System.err; 271 272 /** 273 * The <tt>PrintStream</tt> on which the debugging output is printed. 274 */ 275 public final java.io.PrintStream getDebugStream () { return yyDebugStream; } 276 277 /** 278 * Set the <tt>PrintStream</tt> on which the debug output is printed. 279 * @@param s The stream that is used for debugging output. 280 */ 281 public final void setDebugStream (java.io.PrintStream s) { yyDebugStream = s; } 282 283 private int yydebug = 0; 284 285 /** 286 * Answer the verbosity of the debugging output; 0 means that all kinds of 287 * output from the parser are suppressed. 288 */ 289 public final int getDebugLevel () { return yydebug; } 290 291 /** 292 * Set the verbosity of the debugging output; 0 means that all kinds of 293 * output from the parser are suppressed. 294 * @@param level The verbosity level for debugging output. 295 */ 296 public final void setDebugLevel (int level) { yydebug = level; } 297 ]])[ 298 299 private int yynerrs = 0; 300 301 /** 302 * The number of syntax errors so far. 303 */ 304 public final int getNumberOfErrors () { return yynerrs; } 305 306 /** 307 * Print an error message via the lexer. 308 *]b4_locations_if([[ Use a <code>null</code> location.]])[ 309 * @@param msg The error message. 310 */ 311 public final void yyerror(String msg) { 312 yylexer.yyerror(]b4_locations_if([[(]b4_location_type[)null, ]])[msg); 313 } 314 ]b4_locations_if([[ 315 /** 316 * Print an error message via the lexer. 317 * @@param loc The location associated with the message. 318 * @@param msg The error message. 319 */ 320 public final void yyerror(]b4_location_type[ loc, String msg) { 321 yylexer.yyerror(loc, msg); 322 } 323 324 /** 325 * Print an error message via the lexer. 326 * @@param pos The position associated with the message. 327 * @@param msg The error message. 328 */ 329 public final void yyerror(]b4_position_type[ pos, String msg) { 330 yylexer.yyerror(new ]b4_location_type[ (pos), msg); 331 }]])[ 332 ]b4_parse_trace_if([[ 333 protected final void yycdebug (String s) { 334 if (0 < yydebug) 335 yyDebugStream.println (s); 336 }]])[ 337 338 private final class YYStack { 339 private int[] stateStack = new int[16];]b4_locations_if([[ 340 private ]b4_location_type[[] locStack = new ]b4_location_type[[16];]])[ 341 private ]b4_yystype[[] valueStack = new ]b4_yystype[[16]; 342 343 public int size = 16; 344 public int height = -1; 345 346 public final void push (int state, ]b4_yystype[ value]b4_locations_if([, ]b4_location_type[ loc])[) { 347 height++; 348 if (size == height) 349 { 350 int[] newStateStack = new int[size * 2]; 351 System.arraycopy (stateStack, 0, newStateStack, 0, height); 352 stateStack = newStateStack;]b4_locations_if([[ 353 ]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2]; 354 System.arraycopy (locStack, 0, newLocStack, 0, height); 355 locStack = newLocStack;]]) 356 357 b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2]; 358 System.arraycopy (valueStack, 0, newValueStack, 0, height); 359 valueStack = newValueStack; 360 361 size *= 2; 362 } 363 364 stateStack[height] = state;]b4_locations_if([[ 365 locStack[height] = loc;]])[ 366 valueStack[height] = value; 367 } 368 369 public final void pop () { 370 pop (1); 371 } 372 373 public final void pop (int num) { 374 // Avoid memory leaks... garbage collection is a white lie! 375 if (0 < num) { 376 java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);]b4_locations_if([[ 377 java.util.Arrays.fill (locStack, height - num + 1, height + 1, null);]])[ 378 } 379 height -= num; 380 } 381 382 public final int stateAt (int i) { 383 return stateStack[height - i]; 384 } 385 ]b4_locations_if([[ 386 387 public final ]b4_location_type[ locationAt (int i) { 388 return locStack[height - i]; 389 } 390 ]])[ 391 public final ]b4_yystype[ valueAt (int i) { 392 return valueStack[height - i]; 393 } 394 395 // Print the state stack on the debug stream. 396 public void print (java.io.PrintStream out) { 397 out.print ("Stack now"); 398 399 for (int i = 0; i <= height; i++) 400 { 401 out.print (' '); 402 out.print (stateStack[i]); 403 } 404 out.println (); 405 } 406 } 407 408 /** 409 * Returned by a Bison action in order to stop the parsing process and 410 * return success (<tt>true</tt>). 411 */ 412 public static final int YYACCEPT = 0; 413 414 /** 415 * Returned by a Bison action in order to stop the parsing process and 416 * return failure (<tt>false</tt>). 417 */ 418 public static final int YYABORT = 1; 419 420 ]b4_push_if([ 421 /** 422 * Returned by a Bison action in order to request a new token. 423 */ 424 public static final int YYPUSH_MORE = 4;])[ 425 426 /** 427 * Returned by a Bison action in order to start error recovery without 428 * printing an error message. 429 */ 430 public static final int YYERROR = 2; 431 432 /** 433 * Internal return codes that are not supported for user semantic 434 * actions. 435 */ 436 private static final int YYERRLAB = 3; 437 private static final int YYNEWSTATE = 4; 438 private static final int YYDEFAULT = 5; 439 private static final int YYREDUCE = 6; 440 private static final int YYERRLAB1 = 7; 441 private static final int YYRETURN = 8; 442 ]b4_push_if([[ private static final int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing. */]])[ 443 444 private int yyerrstatus_ = 0; 445 446 ]b4_push_if([b4_define_state])[ 447 /** 448 * Whether error recovery is being done. In this state, the parser 449 * reads token until it reaches a known state, and then restarts normal 450 * operation. 451 */ 452 public final boolean recovering () 453 { 454 return yyerrstatus_ == 0; 455 } 456 457 /** Compute post-reduction state. 458 * @@param yystate the current state 459 * @@param yysym the nonterminal to push on the stack 460 */ 461 private int yyLRGotoState (int yystate, int yysym) 462 { 463 int yyr = yypgoto_[yysym - YYNTOKENS_] + yystate; 464 if (0 <= yyr && yyr <= YYLAST_ && yycheck_[yyr] == yystate) 465 return yytable_[yyr]; 466 else 467 return yydefgoto_[yysym - YYNTOKENS_]; 468 } 469 470 private int yyaction(int yyn, YYStack yystack, int yylen)]b4_maybe_throws([b4_throws])[ 471 { 472 /* If YYLEN is nonzero, implement the default value of the action: 473 '$$ = $1'. Otherwise, use the top of the stack. 474 475 Otherwise, the following line sets YYVAL to garbage. 476 This behavior is undocumented and Bison 477 users should not rely upon it. */ 478 ]b4_yystype[ yyval = (0 < yylen) ? yystack.valueAt(yylen - 1) : yystack.valueAt(0);]b4_locations_if([[ 479 ]b4_location_type[ yyloc = yylloc(yystack, yylen);]])[]b4_parse_trace_if([[ 480 481 yyReducePrint(yyn, yystack);]])[ 482 483 switch (yyn) 484 { 485 ]b4_user_actions[ 486 default: break; 487 }]b4_parse_trace_if([[ 488 489 yySymbolPrint("-> $$ =", SymbolKind.get(yyr1_[yyn]), yyval]b4_locations_if([, yyloc])[);]])[ 490 491 yystack.pop(yylen); 492 yylen = 0; 493 /* Shift the result of the reduction. */ 494 int yystate = yyLRGotoState(yystack.stateAt(0), yyr1_[yyn]); 495 yystack.push(yystate, yyval]b4_locations_if([, yyloc])[); 496 return YYNEWSTATE; 497 } 498 499 ]b4_parse_trace_if([[ 500 /*--------------------------------. 501 | Print this symbol on YYOUTPUT. | 502 `--------------------------------*/ 503 504 private void yySymbolPrint(String s, SymbolKind yykind, 505 ]b4_yystype[ yyvalue]b4_locations_if([, ]b4_location_type[ yylocation])[) { 506 if (0 < yydebug) { 507 yycdebug(s 508 + (yykind.getCode() < YYNTOKENS_ ? " token " : " nterm ") 509 + yykind.getName() + " ("]b4_locations_if([ 510 + yylocation + ": "])[ 511 + (yyvalue == null ? "(null)" : yyvalue.toString()) + ")"); 512 } 513 }]])[ 514 515 ]b4_push_if([],[[ 516 /** 517 * Parse input from the scanner that was specified at object construction 518 * time. Return whether the end of the input was reached successfully. 519 * 520 * @@return <tt>true</tt> if the parsing succeeds. Note that this does not 521 * imply that there were no syntax errors. 522 */ 523 public boolean parse()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[ 524 ]b4_push_if([ 525 /** 526 * Push Parse input from external lexer 527 * 528 * @@param yylextoken current token 529 * @@param yylexval current lval]b4_locations_if([[ 530 * @@param yylexloc current position]])[ 531 * 532 * @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt> 533 */ 534 public int push_parse(int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc]))b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])])[ 535 {]b4_locations_if([[ 536 /* @@$. */ 537 ]b4_location_type[ yyloc;]])[ 538 ]b4_push_if([],[[ 539 ]b4_define_state[]b4_parse_trace_if([[ 540 yycdebug ("Starting parse");]])[ 541 yyerrstatus_ = 0; 542 yynerrs = 0; 543 544 /* Initialize the stack. */ 545 yystack.push (yystate, yylval]b4_locations_if([, yylloc])[); 546 ]m4_ifdef([b4_initial_action], [ 547 b4_dollar_pushdef([yylval], [], [], [yylloc])dnl 548 b4_user_initial_action 549 b4_dollar_popdef[]dnl 550 ])[ 551 ]])[ 552 ]b4_push_if([[ 553 if (!this.push_parse_initialized) 554 { 555 push_parse_initialize (); 556 ]m4_ifdef([b4_initial_action], [ 557 b4_dollar_pushdef([yylval], [], [], [yylloc])dnl 558 b4_user_initial_action 559 b4_dollar_popdef[]dnl 560 ])[]b4_parse_trace_if([[ 561 yycdebug ("Starting parse");]])[ 562 yyerrstatus_ = 0; 563 } else 564 label = YYGETTOKEN; 565 566 boolean push_token_consumed = true; 567 ]])[ 568 for (;;) 569 switch (label) 570 { 571 /* New state. Unlike in the C/C++ skeletons, the state is already 572 pushed when we come here. */ 573 case YYNEWSTATE:]b4_parse_trace_if([[ 574 yycdebug ("Entering state " + yystate); 575 if (0 < yydebug) 576 yystack.print (yyDebugStream);]])[ 577 578 /* Accept? */ 579 if (yystate == YYFINAL_) 580 ]b4_push_if([{label = YYACCEPT; break;}], 581 [return true;])[ 582 583 /* Take a decision. First try without lookahead. */ 584 yyn = yypact_[yystate]; 585 if (yyPactValueIsDefault (yyn)) 586 { 587 label = YYDEFAULT; 588 break; 589 } 590 ]b4_push_if([ /* Fall Through */ 591 592 case YYGETTOKEN:])[ 593 /* Read a lookahead token. */ 594 if (yychar == YYEMPTY_) 595 { 596 ]b4_push_if([[ 597 if (!push_token_consumed) 598 return YYPUSH_MORE;]b4_parse_trace_if([[ 599 yycdebug ("Reading a token");]])[ 600 yychar = yylextoken; 601 yylval = yylexval;]b4_locations_if([ 602 yylloc = yylexloc;])[ 603 push_token_consumed = false;]], [b4_parse_trace_if([[ 604 yycdebug ("Reading a token");]])[ 605 yychar = yylexer.yylex (); 606 yylval = yylexer.getLVal();]b4_locations_if([[ 607 yylloc = new ]b4_location_type[(yylexer.getStartPos(), 608 yylexer.getEndPos());]])[ 609 ]])[ 610 } 611 612 /* Convert token to internal form. */ 613 yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[ 614 yySymbolPrint("Next token is", yytoken, 615 yylval]b4_locations_if([, yylloc])[);]])[ 616 617 if (yytoken == ]b4_symbol(1, kind)[) 618 { 619 // The scanner already issued an error message, process directly 620 // to error recovery. But do not keep the error token as 621 // lookahead, it is too special and may lead us to an endless 622 // loop in error recovery. */ 623 yychar = Lexer.]b4_symbol(2, id)[; 624 yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[ 625 yyerrloc = yylloc;]])[ 626 label = YYERRLAB1; 627 } 628 else 629 { 630 /* If the proper action on seeing token YYTOKEN is to reduce or to 631 detect an error, take that action. */ 632 yyn += yytoken.getCode(); 633 if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode()) 634 label = YYDEFAULT; 635 636 /* <= 0 means reduce or error. */ 637 else if ((yyn = yytable_[yyn]) <= 0) 638 { 639 if (yyTableValueIsError (yyn)) 640 label = YYERRLAB; 641 else 642 { 643 yyn = -yyn; 644 label = YYREDUCE; 645 } 646 } 647 648 else 649 { 650 /* Shift the lookahead token. */]b4_parse_trace_if([[ 651 yySymbolPrint("Shifting", yytoken, 652 yylval]b4_locations_if([, yylloc])[); 653 ]])[ 654 /* Discard the token being shifted. */ 655 yychar = YYEMPTY_; 656 657 /* Count tokens shifted since error; after three, turn off error 658 status. */ 659 if (yyerrstatus_ > 0) 660 --yyerrstatus_; 661 662 yystate = yyn; 663 yystack.push (yystate, yylval]b4_locations_if([, yylloc])[); 664 label = YYNEWSTATE; 665 } 666 } 667 break; 668 669 /*-----------------------------------------------------------. 670 | yydefault -- do the default action for the current state. | 671 `-----------------------------------------------------------*/ 672 case YYDEFAULT: 673 yyn = yydefact_[yystate]; 674 if (yyn == 0) 675 label = YYERRLAB; 676 else 677 label = YYREDUCE; 678 break; 679 680 /*-----------------------------. 681 | yyreduce -- Do a reduction. | 682 `-----------------------------*/ 683 case YYREDUCE: 684 yylen = yyr2_[yyn]; 685 label = yyaction(yyn, yystack, yylen); 686 yystate = yystack.stateAt (0); 687 break; 688 689 /*------------------------------------. 690 | yyerrlab -- here on detecting error | 691 `------------------------------------*/ 692 case YYERRLAB: 693 /* If not already recovering from an error, report this error. */ 694 if (yyerrstatus_ == 0) 695 { 696 ++yynerrs; 697 if (yychar == YYEMPTY_) 698 yytoken = null; 699 yyreportSyntaxError (new Context (yystack, yytoken]b4_locations_if([[, yylloc]])[)); 700 } 701 ]b4_locations_if([[ 702 yyerrloc = yylloc;]])[ 703 if (yyerrstatus_ == 3) 704 { 705 /* If just tried and failed to reuse lookahead token after an 706 error, discard it. */ 707 708 if (yychar <= Lexer.]b4_symbol(0, id)[) 709 { 710 /* Return failure if at end of input. */ 711 if (yychar == Lexer.]b4_symbol(0, id)[) 712 ]b4_push_if([{label = YYABORT; break;}], [return false;])[ 713 } 714 else 715 yychar = YYEMPTY_; 716 } 717 718 /* Else will try to reuse lookahead token after shifting the error 719 token. */ 720 label = YYERRLAB1; 721 break; 722 723 /*-------------------------------------------------. 724 | errorlab -- error raised explicitly by YYERROR. | 725 `-------------------------------------------------*/ 726 case YYERROR:]b4_locations_if([[ 727 yyerrloc = yystack.locationAt (yylen - 1);]])[ 728 /* Do not reclaim the symbols of the rule which action triggered 729 this YYERROR. */ 730 yystack.pop (yylen); 731 yylen = 0; 732 yystate = yystack.stateAt (0); 733 label = YYERRLAB1; 734 break; 735 736 /*-------------------------------------------------------------. 737 | yyerrlab1 -- common code for both syntax error and YYERROR. | 738 `-------------------------------------------------------------*/ 739 case YYERRLAB1: 740 yyerrstatus_ = 3; /* Each real token shifted decrements this. */ 741 742 // Pop stack until we find a state that shifts the error token. 743 for (;;) 744 { 745 yyn = yypact_[yystate]; 746 if (!yyPactValueIsDefault (yyn)) 747 { 748 yyn += ]b4_symbol(1, kind)[.getCode(); 749 if (0 <= yyn && yyn <= YYLAST_ 750 && yycheck_[yyn] == ]b4_symbol(1, kind)[.getCode()) 751 { 752 yyn = yytable_[yyn]; 753 if (0 < yyn) 754 break; 755 } 756 } 757 758 /* Pop the current state because it cannot handle the 759 * error token. */ 760 if (yystack.height == 0) 761 ]b4_push_if([{label = YYABORT; break;}],[return false;])[ 762 763 ]b4_locations_if([[ 764 yyerrloc = yystack.locationAt (0);]])[ 765 yystack.pop (); 766 yystate = yystack.stateAt (0);]b4_parse_trace_if([[ 767 if (0 < yydebug) 768 yystack.print (yyDebugStream);]])[ 769 } 770 771 if (label == YYABORT) 772 /* Leave the switch. */ 773 break; 774 775 ]b4_locations_if([[ 776 /* Muck with the stack to setup for yylloc. */ 777 yystack.push (0, null, yylloc); 778 yystack.push (0, null, yyerrloc); 779 yyloc = yylloc (yystack, 2); 780 yystack.pop (2);]])[ 781 782 /* Shift the error token. */]b4_parse_trace_if([[ 783 yySymbolPrint("Shifting", SymbolKind.get(yystos_[yyn]), 784 yylval]b4_locations_if([, yyloc])[);]])[ 785 786 yystate = yyn; 787 yystack.push (yyn, yylval]b4_locations_if([, yyloc])[); 788 label = YYNEWSTATE; 789 break; 790 791 /* Accept. */ 792 case YYACCEPT: 793 ]b4_push_if([this.push_parse_initialized = false; return YYACCEPT;], 794 [return true;])[ 795 796 /* Abort. */ 797 case YYABORT: 798 ]b4_push_if([this.push_parse_initialized = false; return YYABORT;], 799 [return false;])[ 800 } 801 } 802 ]b4_push_if([[ 803 boolean push_parse_initialized = false; 804 805 /** 806 * (Re-)Initialize the state of the push parser. 807 */ 808 public void push_parse_initialize () 809 { 810 /* Lookahead and lookahead in internal form. */ 811 this.yychar = YYEMPTY_; 812 this.yytoken = null; 813 814 /* State. */ 815 this.yyn = 0; 816 this.yylen = 0; 817 this.yystate = 0; 818 this.yystack = new YYStack (); 819 this.label = YYNEWSTATE; 820 821 /* Error handling. */ 822 this.yynerrs = 0;]b4_locations_if([[ 823 /* The location where the error started. */ 824 this.yyerrloc = null; 825 this.yylloc = new ]b4_location_type[ (null, null);]])[ 826 827 /* Semantic value of the lookahead. */ 828 this.yylval = null; 829 830 yystack.push (this.yystate, this.yylval]b4_locations_if([, this.yylloc])[); 831 832 this.push_parse_initialized = true; 833 834 } 835 ]b4_locations_if([[ 836 /** 837 * Push parse given input from an external lexer. 838 * 839 * @@param yylextoken current token 840 * @@param yylexval current lval 841 * @@param yyylexpos current position 842 * 843 * @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt> 844 */ 845 public int push_parse(int yylextoken, ]b4_yystype[ yylexval, ]b4_position_type[ yylexpos)]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[ { 846 return push_parse(yylextoken, yylexval, new ]b4_location_type[(yylexpos)); 847 } 848 ]])])[ 849 850 ]b4_both_if([[ 851 /** 852 * Parse input from the scanner that was specified at object construction 853 * time. Return whether the end of the input was reached successfully. 854 * This version of parse() is defined only when api.push-push=both. 855 * 856 * @@return <tt>true</tt> if the parsing succeeds. Note that this does not 857 * imply that there were no syntax errors. 858 */ 859 public boolean parse()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[ { 860 if (yylexer == null) 861 throw new NullPointerException("Null Lexer"); 862 int status; 863 do { 864 int token = yylexer.yylex(); 865 ]b4_yystype[ lval = yylexer.getLVal();]b4_locations_if([[ 866 ]b4_location_type[ yyloc = new ]b4_location_type[(yylexer.getStartPos(), yylexer.getEndPos()); 867 status = push_parse(token, lval, yyloc);]], [[ 868 status = push_parse(token, lval);]])[ 869 } while (status == YYPUSH_MORE); 870 return status == YYACCEPT; 871 } 872 ]])[ 873 874 /** 875 * Information needed to get the list of expected tokens and to forge 876 * a syntax error diagnostic. 877 */ 878 public static final class Context 879 { 880 Context (YYStack stack, SymbolKind token]b4_locations_if([[, ]b4_location_type[ loc]])[) 881 { 882 yystack = stack; 883 yytoken = token;]b4_locations_if([[ 884 yylocation = loc;]])[ 885 } 886 887 private YYStack yystack; 888 889 890 /** 891 * The symbol kind of the lookahead token. 892 */ 893 public final SymbolKind getToken () 894 { 895 return yytoken; 896 } 897 898 private SymbolKind yytoken;]b4_locations_if([[ 899 900 /** 901 * The location of the lookahead. 902 */ 903 public final ]b4_location_type[ getLocation () 904 { 905 return yylocation; 906 } 907 908 private ]b4_location_type[ yylocation;]])[ 909 static final int NTOKENS = ]b4_parser_class[.YYNTOKENS_; 910 911 /** 912 * Put in YYARG at most YYARGN of the expected tokens given the 913 * current YYCTX, and return the number of tokens stored in YYARG. If 914 * YYARG is null, return the number of expected tokens (guaranteed to 915 * be less than YYNTOKENS). 916 */ 917 int getExpectedTokens (SymbolKind yyarg[], int yyargn) 918 { 919 return getExpectedTokens (yyarg, 0, yyargn); 920 } 921 922 int getExpectedTokens (SymbolKind yyarg[], int yyoffset, int yyargn) 923 { 924 int yycount = yyoffset; 925 int yyn = yypact_[this.yystack.stateAt (0)]; 926 if (!yyPactValueIsDefault (yyn)) 927 { 928 /* Start YYX at -YYN if negative to avoid negative 929 indexes in YYCHECK. In other words, skip the first 930 -YYN actions for this state because they are default 931 actions. */ 932 int yyxbegin = yyn < 0 ? -yyn : 0; 933 /* Stay within bounds of both yycheck and yytname. */ 934 int yychecklim = YYLAST_ - yyn + 1; 935 int yyxend = yychecklim < NTOKENS ? yychecklim : NTOKENS; 936 for (int yyx = yyxbegin; yyx < yyxend; ++yyx) 937 if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[.getCode() 938 && !yyTableValueIsError(yytable_[yyx + yyn])) 939 { 940 if (yyarg == null) 941 yycount += 1; 942 else if (yycount == yyargn) 943 return 0; // FIXME: this is incorrect. 944 else 945 yyarg[yycount++] = SymbolKind.get(yyx); 946 } 947 } 948 if (yyarg != null && yycount == yyoffset && yyoffset < yyargn) 949 yyarg[yycount] = null; 950 return yycount - yyoffset; 951 } 952 } 953 954 ]b4_parse_error_bmatch( 955 [detailed\|verbose], [[ 956 private int yysyntaxErrorArguments (Context yyctx, SymbolKind[] yyarg, int yyargn) 957 { 958 /* There are many possibilities here to consider: 959 - If this state is a consistent state with a default action, 960 then the only way this function was invoked is if the 961 default action is an error action. In that case, don't 962 check for expected tokens because there are none. 963 - The only way there can be no lookahead present (in tok) is 964 if this state is a consistent state with a default action. 965 Thus, detecting the absence of a lookahead is sufficient to 966 determine that there is no unexpected or expected token to 967 report. In that case, just report a simple "syntax error". 968 - Don't assume there isn't a lookahead just because this 969 state is a consistent state with a default action. There 970 might have been a previous inconsistent state, consistent 971 state with a non-default action, or user semantic action 972 that manipulated yychar. (However, yychar is currently out 973 of scope during semantic actions.) 974 - Of course, the expected token list depends on states to 975 have correct lookahead information, and it depends on the 976 parser not to perform extra reductions after fetching a 977 lookahead from the scanner and before detecting a syntax 978 error. Thus, state merging (from LALR or IELR) and default 979 reductions corrupt the expected token list. However, the 980 list is correct for canonical LR with one exception: it 981 will still contain any token that will not be accepted due 982 to an error action in a later state. 983 */ 984 int yycount = 0; 985 if (yyctx.getToken() != null) 986 { 987 if (yyarg != null) 988 yyarg[yycount] = yyctx.getToken(); 989 yycount += 1; 990 yycount += yyctx.getExpectedTokens(yyarg, 1, yyargn); 991 } 992 return yycount; 993 } 994 ]])[ 995 996 /** 997 * Build and emit a "syntax error" message in a user-defined way. 998 * 999 * @@param ctx The context of the error. 1000 */ 1001 private void yyreportSyntaxError(Context yyctx) {]b4_parse_error_bmatch( 1002 [custom], [[ 1003 yylexer.reportSyntaxError(yyctx);]], 1004 [detailed\|verbose], [[ 1005 if (yyErrorVerbose) { 1006 final int argmax = 5; 1007 SymbolKind[] yyarg = new SymbolKind[argmax]; 1008 int yycount = yysyntaxErrorArguments(yyctx, yyarg, argmax); 1009 String[] yystr = new String[yycount]; 1010 for (int yyi = 0; yyi < yycount; ++yyi) { 1011 yystr[yyi] = yyarg[yyi].getName(); 1012 } 1013 String yyformat; 1014 switch (yycount) { 1015 default: 1016 case 0: yyformat = ]b4_trans(["syntax error"])[; break; 1017 case 1: yyformat = ]b4_trans(["syntax error, unexpected {0}"])[; break; 1018 case 2: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1}"])[; break; 1019 case 3: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2}"])[; break; 1020 case 4: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3}"])[; break; 1021 case 5: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3} or {4}"])[; break; 1022 } 1023 yyerror(]b4_locations_if([[yyctx.yylocation, ]])[new MessageFormat(yyformat).format(yystr)); 1024 } else { 1025 yyerror(]b4_locations_if([[yyctx.yylocation, ]])[]b4_trans(["syntax error"])[); 1026 }]], 1027 [simple], [[ 1028 yyerror(]b4_locations_if([[yyctx.yylocation, ]])[]b4_trans(["syntax error"])[);]])[ 1029 } 1030 1031 /** 1032 * Whether the given <code>yypact_</code> value indicates a defaulted state. 1033 * @@param yyvalue the value to check 1034 */ 1035 private static boolean yyPactValueIsDefault (int yyvalue) 1036 { 1037 return yyvalue == yypact_ninf_; 1038 } 1039 1040 /** 1041 * Whether the given <code>yytable_</code> 1042 * value indicates a syntax error. 1043 * @@param yyvalue the value to check 1044 */ 1045 private static boolean yyTableValueIsError (int yyvalue) 1046 { 1047 return yyvalue == yytable_ninf_; 1048 } 1049 1050 private static final ]b4_int_type_for([b4_pact])[ yypact_ninf_ = ]b4_pact_ninf[; 1051 private static final ]b4_int_type_for([b4_table])[ yytable_ninf_ = ]b4_table_ninf[; 1052 1053 ]b4_parser_tables_define[ 1054 1055 ]b4_parse_trace_if([[ 1056 ]b4_integral_parser_table_define([rline], [b4_rline], 1057 [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[ 1058 1059 1060 // Report on the debug stream that the rule yyrule is going to be reduced. 1061 private void yyReducePrint (int yyrule, YYStack yystack) 1062 { 1063 if (yydebug == 0) 1064 return; 1065 1066 int yylno = yyrline_[yyrule]; 1067 int yynrhs = yyr2_[yyrule]; 1068 /* Print the symbols being reduced, and their result. */ 1069 yycdebug ("Reducing stack by rule " + (yyrule - 1) 1070 + " (line " + yylno + "):"); 1071 1072 /* The symbols being reduced. */ 1073 for (int yyi = 0; yyi < yynrhs; yyi++) 1074 yySymbolPrint(" $" + (yyi + 1) + " =", 1075 SymbolKind.get(yystos_[yystack.stateAt (yynrhs - (yyi + 1))]), 1076 ]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([, 1077 b4_rhs_location(yynrhs, yyi + 1)])[); 1078 }]])[ 1079 1080 /* YYTRANSLATE_(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM 1081 as returned by yylex, with out-of-bounds checking. */ 1082 private static final SymbolKind yytranslate_(int t) 1083 ]b4_api_token_raw_if(dnl 1084 [[ { 1085 return SymbolKind.get(t); 1086 } 1087 ]], 1088 [[ { 1089 // Last valid token kind. 1090 int code_max = ]b4_code_max[; 1091 if (t <= 0) 1092 return ]b4_symbol(0, kind)[; 1093 else if (t <= code_max) 1094 return SymbolKind.get(yytranslate_table_[t]); 1095 else 1096 return ]b4_symbol(2, kind)[; 1097 } 1098 ]b4_integral_parser_table_define([translate_table], [b4_translate])[ 1099 ]])[ 1100 1101 private static final int YYLAST_ = ]b4_last[; 1102 private static final int YYEMPTY_ = -2; 1103 private static final int YYFINAL_ = ]b4_final_state_number[; 1104 private static final int YYNTOKENS_ = ]b4_tokens_number[; 1105 1106 ]b4_percent_code_get[ 1107 } 1108 ]b4_percent_code_get([[epilogue]])[]dnl 1109 b4_epilogue[]dnl 1110 b4_output_end 1111