1<?php 2/* Driver template for the LEMON parser generator. 3** The author disclaims copyright to this source code. 4*/ 5/** The following structure represents a single element of the 6 * parser's stack. Information stored includes: 7 * 8 * + The state number for the parser at this level of the stack. 9 * 10 * + The value of the token stored at this level of the stack. 11 * (In other words, the "major" token.) 12 * 13 * + The semantic value stored at this level of the stack. This is 14 * the information used by the action routines in the grammar. 15 * It is sometimes called the "minor" token. 16 */ 17class ParseyyStackEntry 18{ 19 public $stateno; /* The state-number */ 20 public $major; /* The major token value. This is the code 21 ** number for the token at this stack level */ 22 public $minor; /* The user-supplied minor token value. This 23 ** is the value of the token */ 24}; 25 26/** 27 * The state of the parser is completely contained in an instance of 28 * the following structure 29 */ 30class ParseyyParser 31{ 32/* First off, code is include which follows the "include" declaration 33** in the input file. */ 34 35/* Next is all token values, in a form suitable for use by makeheaders. 36** This section will be null unless lemon is run with the -m switch. 37*/ 38/* 39** These constants (all generated automatically by the parser generator) 40** specify the various kinds of tokens (terminals) that the parser 41** understands. 42** 43** Each symbol here is a terminal symbol in the grammar. 44*/ 45 const T_LNUMBER = 1; 46 const T_DNUMBER = 2; 47 const T_CONSTANT_ENCAPSED_STRING = 3; 48 const T_LINE = 4; 49 const T_FILE = 5; 50 const T_CLASS_C = 6; 51 const T_METHOD_C = 7; 52 const T_FUNC_C = 8; 53 const YY_NO_ACTION = 5; 54 const YY_ACCEPT_ACTION = 4; 55 const YY_ERROR_ACTION = 3; 56 57/* Next are that tables used to determine what action to take based on the 58** current state and lookahead token. These tables are used to implement 59** functions that take a state number and lookahead value and return an 60** action integer. 61** 62** Suppose the action integer is N. Then the action is determined as 63** follows 64** 65** 0 <= N < YYNSTATE Shift N. That is, push the lookahead 66** token onto the stack and goto state N. 67** 68** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. 69** 70** N == YYNSTATE+YYNRULE A syntax error has occurred. 71** 72** N == YYNSTATE+YYNRULE+1 The parser accepts its input. 73** 74** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused 75** slots in the yy_action[] table. 76** 77** The action table is constructed as a single large table named yy_action[]. 78** Given state S and lookahead X, the action is computed as 79** 80** yy_action[ yy_shift_ofst[S] + X ] 81** 82** If the index value yy_shift_ofst[S]+X is out of range or if the value 83** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] 84** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table 85** and that yy_default[S] should be used instead. 86** 87** The formula above is for computing the action when the lookahead is 88** a terminal symbol. If the lookahead is a non-terminal (as occurs after 89** a reduce action) then the yy_reduce_ofst[] array is used in place of 90** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of 91** YY_SHIFT_USE_DFLT. 92** 93** The following are the tables generated in this section: 94** 95** yy_action[] A single table containing all actions. 96** yy_lookahead[] A table containing the lookahead for each entry in 97** yy_action. Used to detect hash collisions. 98** yy_shift_ofst[] For each state, the offset into yy_action for 99** shifting terminals. 100** yy_reduce_ofst[] For each state, the offset into yy_action for 101** shifting non-terminals after a reduce. 102** yy_default[] Default action for each state. 103*/ 104 const YY_SZ_ACTTAB = 9; 105static public $yy_action = array( 106 /* 0 */ 1, 1, 1, 1, 1, 1, 1, 1, 4, 107 ); 108 static public $yy_lookahead = array( 109 /* 0 */ 1, 2, 3, 4, 5, 6, 7, 8, 10, 110); 111 const YY_SHIFT_USE_DFLT = -2; 112 const YY_SHIFT_MAX = 0; 113 static public $yy_shift_ofst = array( 114 /* 0 */ -1, 115); 116 const YY_REDUCE_USE_DFLT = -3; 117 const YY_REDUCE_MAX = 0; 118 static public $yy_reduce_ofst = array( 119 /* 0 */ -2, 120); 121 static public $yy_default = array( 122 /* 0 */ 3, 2, 123); 124/* The next thing included is series of defines which control 125** various aspects of the generated parser. 126** YYCODETYPE is the data type used for storing terminal 127** and nonterminal numbers. "unsigned char" is 128** used if there are fewer than 250 terminals 129** and nonterminals. "int" is used otherwise. 130** YYNOCODE is a number of type YYCODETYPE which corresponds 131** to no legal terminal or nonterminal number. This 132** number is used to fill in empty slots of the hash 133** table. 134** YYFALLBACK If defined, this indicates that one or more tokens 135** have fall-back values which should be used if the 136** original value of the token will not parse. 137** YYACTIONTYPE is the data type used for storing terminal 138** and nonterminal numbers. "unsigned char" is 139** used if there are fewer than 250 rules and 140** states combined. "int" is used otherwise. 141** ParseTOKENTYPE is the data type used for minor tokens given 142** directly to the parser from the tokenizer. 143** YYMINORTYPE is the data type used for all minor tokens. 144** This is typically a union of many types, one of 145** which is ParseTOKENTYPE. The entry in the union 146** for base tokens is called "yy0". 147** YYSTACKDEPTH is the maximum depth of the parser's stack. 148** ParseARG_DECL A global declaration for the %extra_argument 149** YYNSTATE the combined number of states. 150** YYNRULE the number of rules in the grammar 151** YYERRORSYMBOL is the code number of the error symbol. If not 152** defined, then do no error processing. 153*/ 154 const YYNOCODE = 12; 155 const YYSTACKDEPTH = 100; 156 const ParseARG_DECL = '0'; 157 const YYNSTATE = 2; 158 const YYNRULE = 1; 159 const YYERRORSYMBOL = 9; 160 const YYERRSYMDT = 'yy0'; 161 /** The next table maps tokens into fallback tokens. If a construct 162 * like the following: 163 * 164 * %fallback ID X Y Z. 165 * 166 * appears in the grammer, then ID becomes a fallback token for X, Y, 167 * and Z. Whenever one of the tokens X, Y, or Z is input to the parser 168 * but it does not parse, the type of the token is changed to ID and 169 * the parse is retried before an error is thrown. 170 */ 171 static public $yyFallback = array( 172 ); 173 /** 174 * Turn parser tracing on by giving a stream to which to write the trace 175 * and a prompt to preface each trace message. Tracing is turned off 176 * by making either argument NULL 177 * 178 * Inputs: 179 * 180 * - A stream resource to which trace output should be written. 181 * If NULL, then tracing is turned off. 182 * - A prefix string written at the beginning of every 183 * line of trace output. If NULL, then tracing is 184 * turned off. 185 * 186 * Outputs: 187 * 188 * - None. 189 * @param resource 190 * @param string 191 */ 192 static function Trace($TraceFILE, $zTracePrompt) 193 { 194 if (!$TraceFILE) { 195 $zTracePrompt = 0; 196 } elseif (!$zTracePrompt) { 197 $TraceFILE = 0; 198 } 199 self::$yyTraceFILE = $TraceFILE; 200 self::$yyTracePrompt = $zTracePrompt; 201 } 202 203 static public $yyTraceFILE; 204 static public $yyTracePrompt; 205 /** 206 * @var int 207 */ 208 public $yyidx; /* Index of top element in stack */ 209 /** 210 * @var int 211 */ 212 public $yyerrcnt; /* Shifts left before out of the error */ 213 //public $???????; /* A place to hold %extra_argument - dynamically added */ 214 /** 215 * @var array 216 */ 217 public $yystack = array(); /* The parser's stack */ 218 219 /** 220 * For tracing shifts, the names of all terminals and nonterminals 221 * are required. The following table supplies these names 222 * @var array 223 */ 224 static public $yyTokenName = array( 225 '$', 'T_LNUMBER', 'T_DNUMBER', 'T_CONSTANT_ENCAPSED_STRING', 226 'T_LINE', 'T_FILE', 'T_CLASS_C', 'T_METHOD_C', 227 'T_FUNC_C', 'error', 'common_scalar', 228 ); 229 230 /** 231 * For tracing reduce actions, the names of all rules are required. 232 * @var array 233 */ 234 static public $yyRuleName = array( 235 /* 0 */ "common_scalar ::= T_LNUMBER|T_DNUMBER|T_CONSTANT_ENCAPSED_STRING|T_LINE|T_FILE|T_CLASS_C|T_METHOD_C|T_FUNC_C", 236 ); 237 238 /** 239 * This function returns the symbolic name associated with a token 240 * value. 241 * @param int 242 * @return string 243 */ 244 function ParseTokenName($tokenType) 245 { 246 if ($tokenType > 0 && $tokenType < count(self::$yyTokenName)) { 247 return self::$yyTokenName[$tokenType]; 248 } else { 249 return "Unknown"; 250 } 251 } 252 253 /* The following function deletes the value associated with a 254 ** symbol. The symbol can be either a terminal or nonterminal. 255 ** "yymajor" is the symbol code, and "yypminor" is a pointer to 256 ** the value. 257 */ 258 static function yy_destructor($yymajor, $yypminor) 259 { 260 switch ($yymajor) { 261 /* Here is inserted the actions which take place when a 262 ** terminal or non-terminal is destroyed. This can happen 263 ** when the symbol is popped from the stack during a 264 ** reduce or during error processing or when a parser is 265 ** being destroyed before it is finished parsing. 266 ** 267 ** Note: during a reduce, the only symbols destroyed are those 268 ** which appear on the RHS of the rule, but which are not used 269 ** inside the C code. 270 */ 271 default: break; /* If no destructor action specified: do nothing */ 272 } 273 } 274 275 /** 276 * Pop the parser's stack once. 277 * 278 * If there is a destructor routine associated with the token which 279 * is popped from the stack, then call it. 280 * 281 * Return the major token number for the symbol popped. 282 * @param ParseyyParser 283 * @return int 284 */ 285 function yy_pop_parser_stack() 286 { 287 if (!count($this->yystack)) { 288 return; 289 } 290 // ParseyystackEntry class 291 $yytos = $this->yystack[$this->yyidx]; 292 293 if ($this->yyidx < 0) { 294 return 0; 295 } 296 if (self::$yyTraceFILE && $this->yyidx >= 0) { 297 fwrite(self::$yyTraceFILE, 298 self::$yyTracePrompt . 'Popping ' . self::$yyTokenName[$yytos->major] . 299 "\n"); 300 } 301 $yymajor = $yytos->major; 302 self::yy_destructor($yymajor, $yytos->minor); 303 $this->yyidx--; 304 return $yymajor; 305 } 306 307 /** 308 * Deallocate and destroy a parser. Destructors are all called for 309 * all stack elements before shutting the parser down. 310 */ 311 function __destruct() 312 { 313 while ($this->yyidx >= 0) { 314 $this->yy_pop_parser_stack(); 315 } 316 } 317 318 /** 319 * Find the appropriate action for a parser given the terminal 320 * look-ahead token iLookAhead. 321 * 322 * If the look-ahead token is YYNOCODE, then check to see if the action is 323 * independent of the look-ahead. If it is, return the action, otherwise 324 * return YY_NO_ACTION. 325 * @param int The look-ahead token 326 */ 327 function yy_find_shift_action($iLookAhead) 328 { 329 $stateno = $this->yystack[$this->yyidx]->stateno; 330 331 /* if ($this->yyidx < 0) return self::YY_NO_ACTION; */ 332 if (!isset(self::$yy_shift_ofst[$stateno])) { 333 // no shift actions 334 return self::$yy_default[$stateno]; 335 } 336 $i = self::$yy_shift_ofst[$stateno]; 337 if ($i === self::YY_SHIFT_USE_DFLT) { 338 return self::$yy_default[$stateno]; 339 } 340 if ($iLookAhead == self::YYNOCODE) { 341 return self::YY_NO_ACTION; 342 } 343 $i += $iLookAhead; 344 if ($i < 0 || $i >= self::YY_SZ_ACTTAB || 345 self::$yy_lookahead[$i] != $iLookAhead) { 346 if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback) 347 && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) { 348 if (self::$yyTraceFILE) { 349 fwrite(self::$yyTraceFILE, self::$yyTracePrompt . "FALLBACK " . 350 self::$yyTokenName[$iLookAhead] . " => " . 351 self::$yyTokenName[$iFallback] . "\n"); 352 } 353 return $this->yy_find_shift_action($iFallback); 354 } 355 return self::$yy_default[$stateno]; 356 } else { 357 return self::$yy_action[$i]; 358 } 359 } 360 361 /** 362 * Find the appropriate action for a parser given the non-terminal 363 * look-ahead token iLookAhead. 364 * 365 * If the look-ahead token is YYNOCODE, then check to see if the action is 366 * independent of the look-ahead. If it is, return the action, otherwise 367 * return YY_NO_ACTION. 368 * @param int Current state number 369 * @param int The look-ahead token 370 */ 371 function yy_find_reduce_action($stateno, $iLookAhead) 372 { 373 /* $stateno = $this->yystack[$this->yyidx]->stateno; */ 374 375 if (!isset(self::$yy_reduce_ofst[$stateno])) { 376 return self::$yy_default[$stateno]; 377 } 378 $i = self::$yy_reduce_ofst[$stateno]; 379 if ($i == self::YY_REDUCE_USE_DFLT) { 380 return self::$yy_default[$stateno]; 381 } 382 if ($iLookAhead == self::YYNOCODE) { 383 return self::YY_NO_ACTION; 384 } 385 $i += $iLookAhead; 386 if ($i < 0 || $i >= self::YY_SZ_ACTTAB || 387 self::$yy_lookahead[$i] != $iLookAhead) { 388 return self::$yy_default[$stateno]; 389 } else { 390 return self::$yy_action[$i]; 391 } 392 } 393 394 /** 395 * Perform a shift action. 396 * @param int The new state to shift in 397 * @param int The major token to shift in 398 * @param mixed the minor token to shift in 399 */ 400 function yy_shift($yyNewState, $yyMajor, $yypMinor, $extraargument = null) 401 { 402 $this->yyidx++; 403 if ($this->yyidx >= self::YYSTACKDEPTH) { 404 if (self::ParseARG_DECL && $extraargument !== null) { 405 $this->${self::ParseARG_PDECL} = $extraargument; 406 } 407 $this->yyidx--; 408 if (self::$yyTraceFILE) { 409 fprintf(self::$yyTraceFILE, "%sStack Overflow!\n", self::$yyTracePrompt); 410 } 411 while ($this->yyidx >= 0) { 412 $this->yy_pop_parser_stack(); 413 } 414 /* Here code is inserted which will execute if the parser 415 ** stack ever overflows */ 416 return; 417 } 418 $yytos = new ParseyyStackEntry; 419 $yytos->stateno = $yyNewState; 420 $yytos->major = $yyMajor; 421 $yytos->minor = $yypMinor; 422 array_push($this->yystack, $yytos); 423 if (self::$yyTraceFILE && $this->yyidx > 0) { 424 fprintf(self::$yyTraceFILE, "%sShift %d\n", self::$yyTracePrompt, 425 $yyNewState); 426 fprintf(self::$yyTraceFILE, "%sStack:", self::$yyTracePrompt); 427 for($i = 1; $i <= $this->yyidx; $i++) { 428 fprintf(self::$yyTraceFILE, " %s", 429 self::$yyTokenName[$this->yystack[$i]->major]); 430 } 431 fwrite(self::$yyTraceFILE,"\n"); 432 } 433 } 434 435 /** 436 * The following table contains information about every rule that 437 * is used during the reduce. 438 * 439 * static const struct { 440 * YYCODETYPE lhs; Symbol on the left-hand side of the rule 441 * unsigned char nrhs; Number of right-hand side symbols in the rule 442 * } 443 */ 444 static public $yyRuleInfo = array( 445 array( 'lhs' => 10, 'rhs' => 1 ), 446 ); 447 448 /** 449 * The following table contains a mapping of reduce action to method name 450 * that handles the reduction. 451 * 452 * If a rule is not set, it has no handler. 453 */ 454 static public $yyReduceMap = array( 455 0 => 0, 456 ); 457 /* Beginning here are the reduction cases. A typical example 458 ** follows: 459 ** function yy_r0($yymsp) 460 ** #line <lineno> <grammarfile> 461 ** { ... } // User supplied code 462 ** #line <lineno> <thisfile> 463 */ 464#line 9 "/development/lemon/oops.y" 465 function yy_r0(){$this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; yy_destructor(,&yymsp[0].minor); 466 } 467#line 470 "0" 468 469 /** 470 * placeholder for the left hand side in a reduce operation. 471 * 472 * For a parser with a rule like this: 473 * <pre> 474 * rule(A) ::= B. { A = 1; } 475 * </pre> 476 * 477 * The parser will translate to something like: 478 * 479 * <code> 480 * function yy_r0(){$this->_retvalue = 1;} 481 * </code> 482 */ 483 private $_retvalue; 484 485 /** 486 * Perform a reduce action and the shift that must immediately 487 * follow the reduce. 488 * 489 * For a rule such as: 490 * 491 * <pre> 492 * A ::= B blah C. { dosomething(); } 493 * </pre> 494 * 495 * This function will first call the action, if any, ("dosomething();" in our 496 * example), and then it will pop three states from the stack, 497 * one for each entry on the right-hand side of the expression 498 * (B, blah, and C in our example rule), and then push the result of the action 499 * back on to the stack with the resulting state reduced to (as described in the .out 500 * file) 501 * @param int Number of the rule by which to reduce 502 */ 503 function yy_reduce($yyruleno, $extraargument = null) 504 { 505 //int $yygoto; /* The next state */ 506 //int $yyact; /* The next action */ 507 //mixed $yygotominor; /* The LHS of the rule reduced */ 508 //ParseyyStackEntry $yymsp; /* The top of the parser's stack */ 509 //int $yysize; /* Amount to pop the stack */ 510 if (self::ParseARG_DECL && $extraargument !== null) { 511 $this->${self::ParseARG_PDECL} = $extraargument; 512 } 513 $yymsp = $this->yystack[$this->yyidx]; 514 if (self::$yyTraceFILE && $yyruleno >= 0 515 && $yyruleno < count(self::$yyRuleName)) { 516 fprintf(self::$yyTraceFILE, "%sReduce [%s].\n", self::$yyTracePrompt, 517 self::$yyRuleName[$yyruleno]); 518 } 519 520 $yy_lefthand_side = null; 521 if (array_key_exists($yyruleno, self::$yyReduceMap)) { 522 // call the action 523 $this->_retvalue = null; 524 $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}(); 525 $yy_lefthand_side = $this->_retvalue; 526 } 527 $yygoto = self::$yyRuleInfo[$yyruleno]['lhs']; 528 $yysize = self::$yyRuleInfo[$yyruleno]['rhs']; 529 $this->yyidx -= $yysize; 530 for($i = $yysize; $i; $i--) { 531 // pop all of the right-hand side parameters 532 array_pop($this->yystack); 533 } 534 $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto); 535 if ($yyact < self::YYNSTATE) { 536 /* If we are not debugging and the reduce action popped at least 537 ** one element off the stack, then we can push the new element back 538 ** onto the stack here, and skip the stack overflow test in yy_shift(). 539 ** That gives a significant speed improvement. */ 540 if (!self::$yyTraceFILE && $yysize) { 541 $this->yyidx++; 542 $x = new ParseyyStackEntry; 543 $x->stateno = $yyact; 544 $x->major = $yygoto; 545 $x->minor = $yy_lefthand_side; 546 $this->yystack[$this->yyidx] = $x; 547 } else { 548 $this->yy_shift($yyact, $yygoto, $yy_lefthand_side); 549 } 550 } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) { 551 $this->yy_accept(); 552 } 553 } 554 555 /** 556 * The following code executes when the parse fails 557 */ 558 function yy_parse_failed($extraargument = null) 559 { 560 if (self::ParseARG_DECL && $extraargument !== null) { 561 $this->${self::ParseARG_PDECL} = $extraargument; 562 } 563 if (self::$yyTraceFILE) { 564 fprintf(self::$yyTraceFILE, "%sFail!\n", self::$yyTracePrompt); 565 } 566 while ($this->yyidx >= 0) { 567 $this->yy_pop_parser_stack(); 568 } 569 /* Here code is inserted which will be executed whenever the 570 ** parser fails */ 571 } 572 573 /** 574 * The following code executes when a syntax error first occurs. 575 * @param int The major type of the error token 576 * @param mixed The minor type of the error token 577 */ 578 function yy_syntax_error($yymajor, $yyminor, $extraargument = null) 579 { 580 if (self::ParseARG_DECL && $extraargument !== null) { 581 $this->${self::ParseARG_PDECL} = $extraargument; 582 } 583 $TOKEN = 'yyminor.yy0'; 584 } 585 586 /* 587 ** The following is executed when the parser accepts 588 */ 589 function yy_accept($extraargument = null) 590 { 591 if (self::ParseARG_DECL && $extraargument !== null) { 592 $this->${self::ParseARG_PDECL} = $extraargument; 593 } 594 if (self::$yyTraceFILE) { 595 fprintf(self::$yyTraceFILE, "%sAccept!\n", self::$yyTracePrompt); 596 } 597 while ($this->yyidx >= 0) { 598 $stack = $this->yy_pop_parser_stack(); 599 } 600 /* Here code is inserted which will be executed whenever the 601 ** parser accepts */ 602 } 603 604 /** 605 * The main parser program. 606 * The first argument is a pointer to a structure obtained from 607 * "ParseAlloc" which describes the current state of the parser. 608 * The second argument is the major token number. The third is 609 * the minor token. The fourth optional argument is whatever the 610 * user wants (and specified in the grammar) and is available for 611 * use by the action routines. 612 * 613 * Inputs: 614 * 615 * - A pointer to the parser (an opaque structure.) 616 * - The major token number. 617 * - The minor token number (token value). 618 * - An option argument of a grammar-specified type. 619 * 620 * Outputs: 621 * None. 622 * @param int the token number 623 * @param mixed the token value 624 * @param mixed any extra arguments that should be passed to handlers 625 */ 626 function doParse($yymajor, $yytokenvalue, $extraargument = null) 627 { 628 if (self::ParseARG_DECL && $extraargument !== null) { 629 $this->${self::ParseARG_PDECL} = $extraargument; 630 } 631// YYMINORTYPE yyminorunion; 632// int yyact; /* The parser action. */ 633// int yyendofinput; /* True if we are at the end of input */ 634 $yyerrorhit = 0; /* True if yymajor has invoked an error */ 635 636 /* (re)initialize the parser, if necessary */ 637 if ($this->yyidx === null || $this->yyidx < 0) { 638 /* if ($yymajor == 0) return; // not sure why this was here... */ 639 $this->yyidx = 0; 640 $this->yyerrcnt = -1; 641 $x = new ParseyyStackEntry; 642 $x->stateno = 0; 643 $x->major = 0; 644 $this->yystack = array(); 645 array_push($this->yystack, $x); 646 } 647 $yyendofinput = ($yymajor==0); 648 649 if (self::$yyTraceFILE) { 650 fprintf(self::$yyTraceFILE, "%sInput %s\n", 651 self::$yyTracePrompt, self::$yyTokenName[$yymajor]); 652 } 653 654 do { 655 $yyact = $this->yy_find_shift_action($yymajor); 656 if ($yyact < self::YYNSTATE) { 657 $this->yy_shift($yyact, $yymajor, $yytokenvalue); 658 $this->yyerrcnt--; 659 if ($yyendofinput && $this->yyidx >= 0) { 660 $yymajor = 0; 661 } else { 662 $yymajor = self::YYNOCODE; 663 } 664 } elseif ($yyact < self::YYNSTATE + self::YYNRULE) { 665 $this->yy_reduce($yyact - self::YYNSTATE); 666 } elseif ($yyact == self::YY_ERROR_ACTION) { 667 if (self::$yyTraceFILE) { 668 fprintf(self::$yyTraceFILE, "%sSyntax Error!\n", 669 self::$yyTracePrompt); 670 } 671 if (self::YYERRORSYMBOL) { 672 /* A syntax error has occurred. 673 ** The response to an error depends upon whether or not the 674 ** grammar defines an error token "ERROR". 675 ** 676 ** This is what we do if the grammar does define ERROR: 677 ** 678 ** * Call the %syntax_error function. 679 ** 680 ** * Begin popping the stack until we enter a state where 681 ** it is legal to shift the error symbol, then shift 682 ** the error symbol. 683 ** 684 ** * Set the error count to three. 685 ** 686 ** * Begin accepting and shifting new tokens. No new error 687 ** processing will occur until three tokens have been 688 ** shifted successfully. 689 ** 690 */ 691 if ($this->yyerrcnt < 0) { 692 $this->yy_syntax_error($yymajor, $yytokenvalue); 693 } 694 $yymx = $this->yystack[$this->yyidx]->major; 695 if ($yymx == self::YYERRORSYMBOL || $yyerrorhit ){ 696 if (self::$yyTraceFILE) { 697 fprintf(self::$yyTraceFILE, "%sDiscard input token %s\n", 698 self::$yyTracePrompt, self::$yyTokenName[$yymajor]); 699 } 700 $this->yy_destructor($yymajor, $yytokenvalue); 701 $yymajor = self::YYNOCODE; 702 } else { 703 while ($this->yyidx >= 0 && 704 $yymx != self::YYERRORSYMBOL && 705 ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE 706 ){ 707 $this->yy_pop_parser_stack(); 708 } 709 if ($this->yyidx < 0 || $yymajor==0) { 710 $this->yy_destructor($yymajor, $yytokenvalue); 711 $this->yy_parse_failed(); 712 $yymajor = self::YYNOCODE; 713 } elseif ($yymx != self::YYERRORSYMBOL) { 714 $u2 = 0; 715 $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2); 716 } 717 } 718 $this->yyerrcnt = 3; 719 $yyerrorhit = 1; 720 } else { 721 /* YYERRORSYMBOL is not defined */ 722 /* This is what we do if the grammar does not define ERROR: 723 ** 724 ** * Report an error message, and throw away the input token. 725 ** 726 ** * If the input token is $, then fail the parse. 727 ** 728 ** As before, subsequent error messages are suppressed until 729 ** three input tokens have been successfully shifted. 730 */ 731 if ($this->yyerrcnt <= 0) { 732 $this->yy_syntax_error($yymajor, $yytokenvalue); 733 } 734 $this->yyerrcnt = 3; 735 $this->yy_destructor($yymajor, $yytokenvalue); 736 if ($yyendofinput) { 737 $this->yy_parse_failed(); 738 } 739 $yymajor = self::YYNOCODE; 740 } 741 } else { 742 $this->yy_accept(); 743 $yymajor = self::YYNOCODE; 744 } 745 } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0); 746 } 747} 748