[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/pkg/vtiger/extensions/Webservices/third-party/LexerGenerator/ -> Parser.php (source)

   1  <?php
   2  /* Driver template for the PHP_PHP_LexerGenerator_ParserrGenerator parser generator. (PHP port of LEMON)
   3  */
   4  
   5  /**
   6   * This can be used to store both the string representation of
   7   * a token, and any useful meta-data associated with the token.
   8   *
   9   * meta-data should be stored as an array
  10   */
  11  class PHP_LexerGenerator_ParseryyToken implements ArrayAccess
  12  {
  13      public $string = '';
  14      public $metadata = array();
  15  
  16      function __construct($s, $m = array())
  17      {
  18          if ($s instanceof PHP_LexerGenerator_ParseryyToken) {
  19              $this->string = $s->string;
  20              $this->metadata = $s->metadata;
  21          } else {
  22              $this->string = (string) $s;
  23              if ($m instanceof PHP_LexerGenerator_ParseryyToken) {
  24                  $this->metadata = $m->metadata;
  25              } elseif (is_array($m)) {
  26                  $this->metadata = $m;
  27              }
  28          }
  29      }
  30  
  31      function __toString()
  32      {
  33          return $this->_string;
  34      }
  35  
  36      function offsetExists($offset)
  37      {
  38          return isset($this->metadata[$offset]);
  39      }
  40  
  41      function offsetGet($offset)
  42      {
  43          return $this->metadata[$offset];
  44      }
  45  
  46      function offsetSet($offset, $value)
  47      {
  48          if ($offset === null) {
  49              if (isset($value[0])) {
  50                  $x = ($value instanceof PHP_LexerGenerator_ParseryyToken) ?
  51                      $value->metadata : $value;
  52                  $this->metadata = array_merge($this->metadata, $x);
  53                  return;
  54              }
  55              $offset = count($this->metadata);
  56          }
  57          if ($value === null) {
  58              return;
  59          }
  60          if ($value instanceof PHP_LexerGenerator_ParseryyToken) {
  61              if ($value->metadata) {
  62                  $this->metadata[$offset] = $value->metadata;
  63              }
  64          } elseif ($value) {
  65              $this->metadata[$offset] = $value;
  66          }
  67      }
  68  
  69      function offsetUnset($offset)
  70      {
  71          unset($this->metadata[$offset]);
  72      }
  73  }
  74  
  75  /** The following structure represents a single element of the
  76   * parser's stack.  Information stored includes:
  77   *
  78   *   +  The state number for the parser at this level of the stack.
  79   *
  80   *   +  The value of the token stored at this level of the stack.
  81   *      (In other words, the "major" token.)
  82   *
  83   *   +  The semantic value stored at this level of the stack.  This is
  84   *      the information used by the action routines in the grammar.
  85   *      It is sometimes called the "minor" token.
  86   */
  87  class PHP_LexerGenerator_ParseryyStackEntry
  88  {
  89      public $stateno;       /* The state-number */
  90      public $major;         /* The major token value.  This is the code
  91                       ** number for the token at this stack level */
  92      public $minor; /* The user-supplied minor token value.  This
  93                       ** is the value of the token  */
  94  };
  95  
  96  // code external to the class is included here
  97  #line 3 "LexerGenerator\Parser.y"
  98  
  99  /* ?><?php {//*/
 100  /**
 101   * PHP_LexerGenerator, a php 5 lexer generator.
 102   * 
 103   * This lexer generator translates a file in a format similar to
 104   * re2c ({@link http://re2c.org}) and translates it into a PHP 5-based lexer
 105   *
 106   * PHP version 5
 107   *
 108   * LICENSE:
 109   * 
 110   * Copyright (c) 2006, Gregory Beaver <[email protected]>
 111   * All rights reserved.
 112   *
 113   * Redistribution and use in source and binary forms, with or without
 114   * modification, are permitted provided that the following conditions
 115   * are met:
 116   *
 117   *     * Redistributions of source code must retain the above copyright
 118   *       notice, this list of conditions and the following disclaimer.
 119   *     * Redistributions in binary form must reproduce the above copyright
 120   *       notice, this list of conditions and the following disclaimer in
 121   *       the documentation and/or other materials provided with the distribution.
 122   *     * Neither the name of the PHP_LexerGenerator nor the names of its
 123   *       contributors may be used to endorse or promote products derived
 124   *       from this software without specific prior written permission.
 125   *
 126   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 127   * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 128   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 129   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 130   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 131   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 132   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 133   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 134   * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 135   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 136   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 137   *
 138   * @category   php
 139   * @package    PHP_LexerGenerator
 140   * @author     Gregory Beaver <[email protected]>
 141   * @copyright  2006 Gregory Beaver
 142   * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
 143   * @version    CVS: $Id$
 144   * @since      File available since Release 0.1.0
 145   */
 146  /**
 147   * For regular expression validation
 148   */
 149  require_once 'PHP/LexerGenerator/Regex/Lexer.php';
 150  require_once 'PHP/LexerGenerator/Regex/Parser.php';
 151  require_once 'PHP/LexerGenerator/Exception.php';
 152  /**
 153   * Token parser for plex files.
 154   * 
 155   * This parser converts tokens pulled from {@link PHP_LexerGenerator_Lexer}
 156   * into abstract patterns and rules, then creates the output file
 157   * @package    PHP_LexerGenerator
 158   * @author     Gregory Beaver <[email protected]>
 159   * @copyright  2006 Gregory Beaver
 160   * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
 161   * @version    0.2.0
 162   * @since      Class available since Release 0.1.0
 163   */
 164  #line 166 "LexerGenerator\Parser.php"
 165  
 166  // declare_class is output here
 167  #line 2 "LexerGenerator\Parser.y"
 168  class PHP_LexerGenerator_Parser#line 171 "LexerGenerator\Parser.php"
 169  {
 170  /* First off, code is included which follows the "include_class" declaration
 171  ** in the input file. */
 172  #line 82 "LexerGenerator\Parser.y"
 173  
 174      private $patterns;
 175      private $out;
 176      private $lex;
 177      private $input;
 178      private $counter;
 179      private $token;
 180      private $value;
 181      private $line;
 182      private $_regexLexer;
 183      private $_regexParser;
 184  
 185      public $transTable = array(
 186          1 => self::PHPCODE,
 187          2 => self::COMMENTSTART,
 188          3 => self::COMMENTEND,
 189          4 => self::QUOTE,
 190          5 => self::PATTERN,
 191          6 => self::CODE,
 192          7 => self::SUBPATTERN,
 193          8 => self::PI,
 194      );
 195  
 196      function __construct($outfile, $lex)
 197      {
 198          $this->out = fopen($outfile, 'wb');
 199          if (!$this->out) {
 200              throw new Exception('unable to open lexer output file "' . $outfile . '"');
 201          }
 202          $this->lex = $lex;
 203          $this->_regexLexer = new PHP_LexerGenerator_Regex_Lexer('');
 204          $this->_regexParser = new PHP_LexerGenerator_Regex_Parser($this->_regexLexer);
 205      }
 206  
 207      function outputRules($rules, $statename)
 208      {
 209          static $ruleindex = 1;
 210          $patterns = array();
 211          $pattern = '/';
 212          $ruleMap = array();
 213          $tokenindex = array();
 214          $i = 0;
 215          $actualindex = 1;
 216          foreach ($rules as $rule) {
 217              $ruleMap[$i++] = $actualindex;
 218              $tokenindex[$actualindex] = $rule['subpatterns'];
 219              $actualindex += $rule['subpatterns'] + 1;
 220              $patterns[] = '^(' . $rule['pattern'] . ')';
 221          }
 222          $tokenindex = var_export($tokenindex, true);
 223          $tokenindex = explode("\n", $tokenindex);
 224          // indent for prettiness
 225          $tokenindex = implode("\n            ", $tokenindex);
 226          $pattern .= implode('|', $patterns);
 227          $pattern .= '/';
 228          if (!$statename) {
 229              $statename = $ruleindex;
 230          }
 231          fwrite($this->out, '
 232      function yylex' . $ruleindex . '()
 233      {
 234          $tokenMap = ' . $tokenindex . ';
 235          if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
 236              return false; // end of input
 237          }
 238          ');
 239          fwrite($this->out, '$yy_global_pattern = "' .
 240              $pattern . '";' . "\n");
 241          fwrite($this->out, '
 242          do {
 243              if (preg_match($yy_global_pattern, substr(' . $this->input . ', ' .
 244               $this->counter .
 245                      '), $yymatches)) {
 246                  $yysubmatches = $yymatches;
 247                  $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
 248                  if (!count($yymatches)) {
 249                      throw new Exception(\'Error: lexing failed because a rule matched\' .
 250                          \'an empty string.  Input "\' . substr(' . $this->input . ',
 251                          ' . $this->counter . ', 5) . \'... state ' . $statename . '\');
 252                  }
 253                  next($yymatches); // skip global match
 254                  ' . $this->token . ' = key($yymatches); // token number
 255                  if ($tokenMap[' . $this->token . ']) {
 256                      // extract sub-patterns for passing to lex function
 257                      $yysubmatches = array_slice($yysubmatches, ' . $this->token . ' + 1,
 258                          $tokenMap[' . $this->token . ']);
 259                  } else {
 260                      $yysubmatches = array();
 261                  }
 262                  ' . $this->value . ' = current($yymatches); // token value
 263                  $r = $this->{\'yy_r' . $ruleindex . '_\' . ' . $this->token . '}($yysubmatches);
 264                  if ($r === null) {
 265                      ' . $this->counter . ' += strlen($this->value);
 266                      ' . $this->line . ' += substr_count("\n", ' . $this->value . ');
 267                      // accept this token
 268                      return true;
 269                  } elseif ($r === true) {
 270                      // we have changed state
 271                      // process this token in the new state
 272                      return $this->yylex();
 273                  } elseif ($r === false) {
 274                      ' . $this->counter . ' += strlen($this->value);
 275                      ' . $this->line . ' += substr_count("\n", ' . $this->value . ');
 276                      if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
 277                          return false; // end of input
 278                      }
 279                      // skip this token
 280                      continue;
 281                  } else {');
 282          fwrite($this->out, '                    $yy_yymore_patterns = array(' . "\n");
 283          for($i = 0; count($patterns); $i++) {
 284              unset($patterns[$i]);
 285              fwrite($this->out, '        ' . $ruleMap[$i] . ' => "' .
 286                  implode('|', $patterns) . "\",\n");
 287          }
 288          fwrite($this->out, '    );' . "\n");
 289          fwrite($this->out, '
 290                      // yymore is needed
 291                      do {
 292                          if (!strlen($yy_yymore_patterns[' . $this->token . '])) {
 293                              throw new Exception(\'cannot do yymore for the last token\');
 294                          }
 295                          if (preg_match($yy_yymore_patterns[' . $this->token . '],
 296                                substr(' . $this->input . ', ' . $this->counter . '), $yymatches)) {
 297                              $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
 298                              next($yymatches); // skip global match
 299                              ' . $this->token . ' = key($yymatches); // token number
 300                              ' . $this->value . ' = current($yymatches); // token value
 301                              ' . $this->line . ' = substr_count("\n", ' . $this->value . ');
 302                          }
 303                      } while ($this->{\'yy_r' . $ruleindex . '_\' . ' . $this->token . '}() !== null);
 304                      // accept
 305                      ' . $this->counter . ' += strlen($this->value);
 306                      ' . $this->line . ' += substr_count("\n", ' . $this->value . ');
 307                      return true;
 308                  }
 309              } else {
 310                  throw new Exception(\'Unexpected input at line\' . ' . $this->line . ' .
 311                      \': \' . ' . $this->input . '[' . $this->counter . ']);
 312              }
 313              break;
 314          } while (true);
 315      } // end function
 316  
 317  ');
 318          if ($statename) {
 319              fwrite($this->out, '
 320      const ' . $statename . ' = ' . $ruleindex . ';
 321  ');
 322          }
 323          foreach ($rules as $i => $rule) {
 324              fwrite($this->out, '    function yy_r' . $ruleindex . '_' . $ruleMap[$i] . '($yy_subpatterns)
 325      {
 326  ' . $rule['code'] .
 327  '    }
 328  ');
 329          }
 330          $ruleindex++; // for next set of rules
 331      }
 332  
 333      function error($msg)
 334      {
 335          echo 'Error on line ' . $this->lex->line . ': ' , $msg;
 336      }
 337  
 338      function _validatePattern($pattern)
 339      {
 340          $this->_regexLexer->reset($pattern);
 341          try {
 342              while ($this->_regexLexer->yylex()) {
 343                  $this->_regexParser->doParse(
 344                      $this->_regexLexer->token, $this->_regexLexer->value);
 345              }
 346              $this->_regexParser->doParse(0, 0);
 347          } catch (PHP_LexerGenerator_Exception $e) {
 348              $this->error($e->getMessage());
 349              throw new PHP_LexerGenerator_Exception('Invalid pattern "' . $pattern . '"');
 350          }
 351          return $this->_regexParser->result;
 352      }
 353  #line 357 "LexerGenerator\Parser.php"
 354  
 355  /* Next is all token values, as class constants
 356  */
 357  /* 
 358  ** These constants (all generated automatically by the parser generator)
 359  ** specify the various kinds of tokens (terminals) that the parser
 360  ** understands. 
 361  **
 362  ** Each symbol here is a terminal symbol in the grammar.
 363  */
 364      const PHPCODE                        =  1;
 365      const COMMENTSTART                   =  2;
 366      const COMMENTEND                     =  3;
 367      const PI                             =  4;
 368      const SUBPATTERN                     =  5;
 369      const CODE                           =  6;
 370      const PATTERN                        =  7;
 371      const QUOTE                          =  8;
 372      const YY_NO_ACTION = 94;
 373      const YY_ACCEPT_ACTION = 93;
 374      const YY_ERROR_ACTION = 92;
 375  
 376  /* Next are that tables used to determine what action to take based on the
 377  ** current state and lookahead token.  These tables are used to implement
 378  ** functions that take a state number and lookahead value and return an
 379  ** action integer.  
 380  **
 381  ** Suppose the action integer is N.  Then the action is determined as
 382  ** follows
 383  **
 384  **   0 <= N < self::YYNSTATE                              Shift N.  That is,
 385  **                                                        push the lookahead
 386  **                                                        token onto the stack
 387  **                                                        and goto state N.
 388  **
 389  **   self::YYNSTATE <= N < self::YYNSTATE+self::YYNRULE   Reduce by rule N-YYNSTATE.
 390  **
 391  **   N == self::YYNSTATE+self::YYNRULE                    A syntax error has occurred.
 392  **
 393  **   N == self::YYNSTATE+self::YYNRULE+1                  The parser accepts its
 394  **                                                        input. (and concludes parsing)
 395  **
 396  **   N == self::YYNSTATE+self::YYNRULE+2                  No such action.  Denotes unused
 397  **                                                        slots in the yy_action[] table.
 398  **
 399  ** The action table is constructed as a single large static array $yy_action.
 400  ** Given state S and lookahead X, the action is computed as
 401  **
 402  **      self::$yy_action[self::$yy_shift_ofst[S] + X ]
 403  **
 404  ** If the index value self::$yy_shift_ofst[S]+X is out of range or if the value
 405  ** self::$yy_lookahead[self::$yy_shift_ofst[S]+X] is not equal to X or if
 406  ** self::$yy_shift_ofst[S] is equal to self::YY_SHIFT_USE_DFLT, it means that
 407  ** the action is not in the table and that self::$yy_default[S] should be used instead.  
 408  **
 409  ** The formula above is for computing the action when the lookahead is
 410  ** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
 411  ** a reduce action) then the static $yy_reduce_ofst array is used in place of
 412  ** the static $yy_shift_ofst array and self::YY_REDUCE_USE_DFLT is used in place of
 413  ** self::YY_SHIFT_USE_DFLT.
 414  **
 415  ** The following are the tables generated in this section:
 416  **
 417  **  self::$yy_action        A single table containing all actions.
 418  **  self::$yy_lookahead     A table containing the lookahead for each entry in
 419  **                          yy_action.  Used to detect hash collisions.
 420  **  self::$yy_shift_ofst    For each state, the offset into self::$yy_action for
 421  **                          shifting terminals.
 422  **  self::$yy_reduce_ofst   For each state, the offset into self::$yy_action for
 423  **                          shifting non-terminals after a reduce.
 424  **  self::$yy_default       Default action for each state.
 425  */
 426      const YY_SZ_ACTTAB = 87;
 427  static public $yy_action = array(
 428   /*     0 */    33,   31,   58,   58,    3,   50,   50,   57,   44,   39,
 429   /*    10 */    42,   58,   57,   55,   50,   42,   51,   36,   58,   58,
 430   /*    20 */    59,   50,   50,   38,   58,   46,   45,   50,   35,   58,
 431   /*    30 */    17,    2,   50,   93,   52,   16,   18,    6,   24,   19,
 432   /*    40 */     2,   12,   41,   53,   48,   40,   30,   60,    1,    4,
 433   /*    50 */    34,   10,   20,   43,   49,   32,   14,   58,    7,   20,
 434   /*    60 */    50,    8,   20,    9,   20,   37,   47,   11,   20,   56,
 435   /*    70 */    15,    5,   22,   54,   28,   23,   53,   21,   29,   25,
 436   /*    80 */     2,   27,    6,   13,   53,   53,   26,
 437      );
 438      static public $yy_lookahead = array(
 439   /*     0 */     3,    3,    5,    5,    5,    8,    8,    5,    6,    3,
 440   /*    10 */     8,    5,    5,    6,    8,    8,    3,    3,    5,    5,
 441   /*    20 */     3,    8,    8,    4,    5,    5,    6,    8,    4,    5,
 442   /*    30 */     1,    2,    8,   10,   11,   12,    1,    2,    4,    1,
 443   /*    40 */     2,    7,    5,    1,    5,    8,   16,    8,    2,    5,
 444   /*    50 */     4,   18,   19,    5,    6,   14,   15,    5,   18,   19,
 445   /*    60 */     8,   18,   19,   18,   19,    5,    1,   18,   19,    1,
 446   /*    70 */     7,    2,   13,    1,   17,   13,   20,   19,    4,   13,
 447   /*    80 */     2,   17,    2,   12,   20,   20,   13,
 448  );
 449      const YY_SHIFT_USE_DFLT = -4;
 450      const YY_SHIFT_MAX = 39;
 451      static public $yy_shift_ofst = array(
 452   /*     0 */    35,   24,   19,   52,   52,   52,   74,   13,   -2,   -3,
 453   /*    10 */    14,    6,   37,   38,   34,   37,   29,   78,   80,   78,
 454   /*    20 */     7,    2,   46,   46,   48,   46,   46,   39,   39,   20,
 455   /*    30 */    63,   42,   17,   72,   60,   -1,   68,   69,   44,   65,
 456  );
 457      const YY_REDUCE_USE_DFLT = -1;
 458      const YY_REDUCE_MAX = 19;
 459      static public $yy_reduce_ofst = array(
 460   /*     0 */    23,   49,   45,   33,   43,   40,   41,   58,   58,   58,
 461   /*    10 */    58,   58,   64,   59,   30,   57,   62,   73,   71,   66,
 462  );
 463      static public $yyExpectedTokens = array(
 464          /* 0 */ array(1, 2, ),
 465          /* 1 */ array(4, 5, 8, ),
 466          /* 2 */ array(4, 5, 8, ),
 467          /* 3 */ array(5, 8, ),
 468          /* 4 */ array(5, 8, ),
 469          /* 5 */ array(5, 8, ),
 470          /* 6 */ array(4, ),
 471          /* 7 */ array(3, 5, 8, ),
 472          /* 8 */ array(3, 5, 8, ),
 473          /* 9 */ array(3, 5, 8, ),
 474          /* 10 */ array(3, 5, 8, ),
 475          /* 11 */ array(3, 5, 8, ),
 476          /* 12 */ array(5, 8, ),
 477          /* 13 */ array(1, 2, ),
 478          /* 14 */ array(4, 7, ),
 479          /* 15 */ array(5, 8, ),
 480          /* 16 */ array(1, 2, ),
 481          /* 17 */ array(2, ),
 482          /* 18 */ array(2, ),
 483          /* 19 */ array(2, ),
 484          /* 20 */ array(5, 6, 8, ),
 485          /* 21 */ array(5, 6, 8, ),
 486          /* 22 */ array(2, 4, ),
 487          /* 23 */ array(2, 4, ),
 488          /* 24 */ array(5, 6, ),
 489          /* 25 */ array(2, 4, ),
 490          /* 26 */ array(2, 4, ),
 491          /* 27 */ array(5, 8, ),
 492          /* 28 */ array(5, 8, ),
 493          /* 29 */ array(5, 6, ),
 494          /* 30 */ array(7, ),
 495          /* 31 */ array(1, ),
 496          /* 32 */ array(3, ),
 497          /* 33 */ array(1, ),
 498          /* 34 */ array(5, ),
 499          /* 35 */ array(5, ),
 500          /* 36 */ array(1, ),
 501          /* 37 */ array(2, ),
 502          /* 38 */ array(5, ),
 503          /* 39 */ array(1, ),
 504          /* 40 */ array(),
 505          /* 41 */ array(),
 506          /* 42 */ array(),
 507          /* 43 */ array(),
 508          /* 44 */ array(),
 509          /* 45 */ array(),
 510          /* 46 */ array(),
 511          /* 47 */ array(),
 512          /* 48 */ array(),
 513          /* 49 */ array(),
 514          /* 50 */ array(),
 515          /* 51 */ array(),
 516          /* 52 */ array(),
 517          /* 53 */ array(),
 518          /* 54 */ array(),
 519          /* 55 */ array(),
 520          /* 56 */ array(),
 521          /* 57 */ array(),
 522          /* 58 */ array(),
 523          /* 59 */ array(),
 524          /* 60 */ array(),
 525  );
 526      static public $yy_default = array(
 527   /*     0 */    92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
 528   /*    10 */    92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
 529   /*    20 */    92,   92,   64,   62,   92,   65,   63,   72,   73,   92,
 530   /*    30 */    67,   75,   92,   74,   92,   92,   92,   92,   92,   78,
 531   /*    40 */    88,   89,   86,   70,   83,   69,   68,   80,   91,   71,
 532   /*    50 */    84,   79,   61,   77,   76,   82,   81,   87,   85,   66,
 533   /*    60 */    90,
 534  );
 535  /* The next thing included is series of defines which control
 536  ** various aspects of the generated parser.
 537  **    self::YYNOCODE      is a number which corresponds
 538  **                        to no legal terminal or nonterminal number.  This
 539  **                        number is used to fill in empty slots of the hash 
 540  **                        table.
 541  **    self::YYFALLBACK    If defined, this indicates that one or more tokens
 542  **                        have fall-back values which should be used if the
 543  **                        original value of the token will not parse.
 544  **    self::YYSTACKDEPTH  is the maximum depth of the parser's stack.
 545  **    self::YYNSTATE      the combined number of states.
 546  **    self::YYNRULE       the number of rules in the grammar
 547  **    self::YYERRORSYMBOL is the code number of the error symbol.  If not
 548  **                        defined, then do no error processing.
 549  */
 550      const YYNOCODE = 21;
 551      const YYSTACKDEPTH = 100;
 552      const YYNSTATE = 61;
 553      const YYNRULE = 31;
 554      const YYERRORSYMBOL = 9;
 555      const YYERRSYMDT = 'yy0';
 556      const YYFALLBACK = 0;
 557      /** The next table maps tokens into fallback tokens.  If a construct
 558       * like the following:
 559       * 
 560       *      %fallback ID X Y Z.
 561       *
 562       * appears in the grammer, then ID becomes a fallback token for X, Y,
 563       * and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
 564       * but it does not parse, the type of the token is changed to ID and
 565       * the parse is retried before an error is thrown.
 566       */
 567      static public $yyFallback = array(
 568      );
 569      /**
 570       * Turn parser tracing on by giving a stream to which to write the trace
 571       * and a prompt to preface each trace message.  Tracing is turned off
 572       * by making either argument NULL 
 573       *
 574       * Inputs:
 575       * 
 576       * - A stream resource to which trace output should be written.
 577       *   If NULL, then tracing is turned off.
 578       * - A prefix string written at the beginning of every
 579       *   line of trace output.  If NULL, then tracing is
 580       *   turned off.
 581       *
 582       * Outputs:
 583       * 
 584       * - None.
 585       * @param resource
 586       * @param string
 587       */
 588      static function Trace($TraceFILE, $zTracePrompt)
 589      {
 590          if (!$TraceFILE) {
 591              $zTracePrompt = 0;
 592          } elseif (!$zTracePrompt) {
 593              $TraceFILE = 0;
 594          }
 595          self::$yyTraceFILE = $TraceFILE;
 596          self::$yyTracePrompt = $zTracePrompt;
 597      }
 598  
 599      /**
 600       * Output debug information to output (php://output stream)
 601       */
 602      static function PrintTrace()
 603      {
 604          self::$yyTraceFILE = fopen('php://output', 'w');
 605          self::$yyTracePrompt = '';
 606      }
 607  
 608      /**
 609       * @var resource|0
 610       */
 611      static public $yyTraceFILE;
 612      /**
 613       * String to prepend to debug output
 614       * @var string|0
 615       */
 616      static public $yyTracePrompt;
 617      /**
 618       * @var int
 619       */
 620      public $yyidx;                    /* Index of top element in stack */
 621      /**
 622       * @var int
 623       */
 624      public $yyerrcnt;                 /* Shifts left before out of the error */
 625      /**
 626       * @var array
 627       */
 628      public $yystack = array();  /* The parser's stack */
 629  
 630      /**
 631       * For tracing shifts, the names of all terminals and nonterminals
 632       * are required.  The following table supplies these names
 633       * @var array
 634       */
 635      static public $yyTokenName = array( 
 636    '$',             'PHPCODE',       'COMMENTSTART',  'COMMENTEND',  
 637    'PI',            'SUBPATTERN',    'CODE',          'PATTERN',     
 638    'QUOTE',         'error',         'start',         'lexfile',     
 639    'declare',       'rules',         'declarations',  'processing_instructions',
 640    'pattern_declarations',  'subpattern',    'rule',          'rule_subpattern',
 641      );
 642  
 643      /**
 644       * For tracing reduce actions, the names of all rules are required.
 645       * @var array
 646       */
 647      static public $yyRuleName = array(
 648   /*   0 */ "start ::= lexfile",
 649   /*   1 */ "lexfile ::= declare rules",
 650   /*   2 */ "lexfile ::= declare PHPCODE rules",
 651   /*   3 */ "lexfile ::= PHPCODE declare rules",
 652   /*   4 */ "lexfile ::= PHPCODE declare PHPCODE rules",
 653   /*   5 */ "declare ::= COMMENTSTART declarations COMMENTEND",
 654   /*   6 */ "declarations ::= processing_instructions pattern_declarations",
 655   /*   7 */ "processing_instructions ::= PI SUBPATTERN",
 656   /*   8 */ "processing_instructions ::= PI CODE",
 657   /*   9 */ "processing_instructions ::= processing_instructions PI SUBPATTERN",
 658   /*  10 */ "processing_instructions ::= processing_instructions PI CODE",
 659   /*  11 */ "pattern_declarations ::= PATTERN subpattern",
 660   /*  12 */ "pattern_declarations ::= pattern_declarations PATTERN subpattern",
 661   /*  13 */ "rules ::= COMMENTSTART rule COMMENTEND",
 662   /*  14 */ "rules ::= COMMENTSTART PI SUBPATTERN rule COMMENTEND",
 663   /*  15 */ "rules ::= COMMENTSTART rule COMMENTEND PHPCODE",
 664   /*  16 */ "rules ::= COMMENTSTART PI SUBPATTERN rule COMMENTEND PHPCODE",
 665   /*  17 */ "rules ::= rules COMMENTSTART rule COMMENTEND",
 666   /*  18 */ "rules ::= rules PI SUBPATTERN COMMENTSTART rule COMMENTEND",
 667   /*  19 */ "rules ::= rules COMMENTSTART rule COMMENTEND PHPCODE",
 668   /*  20 */ "rules ::= rules COMMENTSTART PI SUBPATTERN rule COMMENTEND PHPCODE",
 669   /*  21 */ "rule ::= rule_subpattern CODE",
 670   /*  22 */ "rule ::= rule rule_subpattern CODE",
 671   /*  23 */ "rule_subpattern ::= QUOTE",
 672   /*  24 */ "rule_subpattern ::= SUBPATTERN",
 673   /*  25 */ "rule_subpattern ::= rule_subpattern QUOTE",
 674   /*  26 */ "rule_subpattern ::= rule_subpattern SUBPATTERN",
 675   /*  27 */ "subpattern ::= QUOTE",
 676   /*  28 */ "subpattern ::= SUBPATTERN",
 677   /*  29 */ "subpattern ::= subpattern QUOTE",
 678   /*  30 */ "subpattern ::= subpattern SUBPATTERN",
 679      );
 680  
 681      /**
 682       * This function returns the symbolic name associated with a token
 683       * value.
 684       * @param int
 685       * @return string
 686       */
 687      function tokenName($tokenType)
 688      {
 689          if ($tokenType === 0) {
 690              return 'End of Input';
 691          }
 692          if ($tokenType > 0 && $tokenType < count(self::$yyTokenName)) {
 693              return self::$yyTokenName[$tokenType];
 694          } else {
 695              return "Unknown";
 696          }
 697      }
 698  
 699      /**
 700       * The following function deletes the value associated with a
 701       * symbol.  The symbol can be either a terminal or nonterminal.
 702       * @param int the symbol code
 703       * @param mixed the symbol's value
 704       */
 705      static function yy_destructor($yymajor, $yypminor)
 706      {
 707          switch ($yymajor) {
 708          /* Here is inserted the actions which take place when a
 709          ** terminal or non-terminal is destroyed.  This can happen
 710          ** when the symbol is popped from the stack during a
 711          ** reduce or during error processing or when a parser is 
 712          ** being destroyed before it is finished parsing.
 713          **
 714          ** Note: during a reduce, the only symbols destroyed are those
 715          ** which appear on the RHS of the rule, but which are not used
 716          ** inside the C code.
 717          */
 718              default:  break;   /* If no destructor action specified: do nothing */
 719          }
 720      }
 721  
 722      /**
 723       * Pop the parser's stack once.
 724       *
 725       * If there is a destructor routine associated with the token which
 726       * is popped from the stack, then call it.
 727       *
 728       * Return the major token number for the symbol popped.
 729       * @param PHP_LexerGenerator_ParseryyParser
 730       * @return int
 731       */
 732      function yy_pop_parser_stack()
 733      {
 734          if (!count($this->yystack)) {
 735              return;
 736          }
 737          $yytos = array_pop($this->yystack);
 738          if (self::$yyTraceFILE && $this->yyidx >= 0) {
 739              fwrite(self::$yyTraceFILE,
 740                  self::$yyTracePrompt . 'Popping ' . self::$yyTokenName[$yytos->major] .
 741                      "\n");
 742          }
 743          $yymajor = $yytos->major;
 744          self::yy_destructor($yymajor, $yytos->minor);
 745          $this->yyidx--;
 746          return $yymajor;
 747      }
 748  
 749      /**
 750       * Deallocate and destroy a parser.  Destructors are all called for
 751       * all stack elements before shutting the parser down.
 752       */
 753      function __destruct()
 754      {
 755          while ($this->yyidx >= 0) {
 756              $this->yy_pop_parser_stack();
 757          }
 758          if (is_resource(self::$yyTraceFILE)) {
 759              fclose(self::$yyTraceFILE);
 760          }
 761      }
 762  
 763      /**
 764       * Based on the current state and parser stack, get a list of all
 765       * possible lookahead tokens
 766       * @param int
 767       * @return array
 768       */
 769      function yy_get_expected_tokens($token)
 770      {
 771          $state = $this->yystack[$this->yyidx]->stateno;
 772          $expected = self::$yyExpectedTokens[$state];
 773          if (in_array($token, self::$yyExpectedTokens[$state], true)) {
 774              return $expected;
 775          }
 776          $stack = $this->yystack;
 777          $yyidx = $this->yyidx;
 778          do {
 779              $yyact = $this->yy_find_shift_action($token);
 780              if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
 781                  // reduce action
 782                  $done = 0;
 783                  do {
 784                      if ($done++ == 100) {
 785                          $this->yyidx = $yyidx;
 786                          $this->yystack = $stack;
 787                          // too much recursion prevents proper detection
 788                          // so give up
 789                          return array_unique($expected);
 790                      }
 791                      $yyruleno = $yyact - self::YYNSTATE;
 792                      $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
 793                      $nextstate = $this->yy_find_reduce_action(
 794                          $this->yystack[$this->yyidx]->stateno,
 795                          self::$yyRuleInfo[$yyruleno]['lhs']);
 796                      if (isset(self::$yyExpectedTokens[$nextstate])) {
 797                          $expected += self::$yyExpectedTokens[$nextstate];
 798                              if (in_array($token,
 799                                    self::$yyExpectedTokens[$nextstate], true)) {
 800                              $this->yyidx = $yyidx;
 801                              $this->yystack = $stack;
 802                              return array_unique($expected);
 803                          }
 804                      }
 805                      if ($nextstate < self::YYNSTATE) {
 806                          // we need to shift a non-terminal
 807                          $this->yyidx++;
 808                          $x = new PHP_LexerGenerator_ParseryyStackEntry;
 809                          $x->stateno = $nextstate;
 810                          $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
 811                          $this->yystack[$this->yyidx] = $x;
 812                          continue 2;
 813                      } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
 814                          $this->yyidx = $yyidx;
 815                          $this->yystack = $stack;
 816                          // the last token was just ignored, we can't accept
 817                          // by ignoring input, this is in essence ignoring a
 818                          // syntax error!
 819                          return array_unique($expected);
 820                      } elseif ($nextstate === self::YY_NO_ACTION) {
 821                          $this->yyidx = $yyidx;
 822                          $this->yystack = $stack;
 823                          // input accepted, but not shifted (I guess)
 824                          return $expected;
 825                      } else {
 826                          $yyact = $nextstate;
 827                      }
 828                  } while (true);
 829              }
 830              break;
 831          } while (true);
 832          return array_unique($expected);
 833      }
 834  
 835      /**
 836       * Based on the parser state and current parser stack, determine whether
 837       * the lookahead token is possible.
 838       * 
 839       * The parser will convert the token value to an error token if not.  This
 840       * catches some unusual edge cases where the parser would fail.
 841       * @param int
 842       * @return bool
 843       */
 844      function yy_is_expected_token($token)
 845      {
 846          if ($token === 0) {
 847              return true; // 0 is not part of this
 848          }
 849          $state = $this->yystack[$this->yyidx]->stateno;
 850          if (in_array($token, self::$yyExpectedTokens[$state], true)) {
 851              return true;
 852          }
 853          $stack = $this->yystack;
 854          $yyidx = $this->yyidx;
 855          do {
 856              $yyact = $this->yy_find_shift_action($token);
 857              if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
 858                  // reduce action
 859                  $done = 0;
 860                  do {
 861                      if ($done++ == 100) {
 862                          $this->yyidx = $yyidx;
 863                          $this->yystack = $stack;
 864                          // too much recursion prevents proper detection
 865                          // so give up
 866                          return true;
 867                      }
 868                      $yyruleno = $yyact - self::YYNSTATE;
 869                      $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
 870                      $nextstate = $this->yy_find_reduce_action(
 871                          $this->yystack[$this->yyidx]->stateno,
 872                          self::$yyRuleInfo[$yyruleno]['lhs']);
 873                      if (isset(self::$yyExpectedTokens[$nextstate]) &&
 874                            in_array($token, self::$yyExpectedTokens[$nextstate], true)) {
 875                          $this->yyidx = $yyidx;
 876                          $this->yystack = $stack;
 877                          return true;
 878                      }
 879                      if ($nextstate < self::YYNSTATE) {
 880                          // we need to shift a non-terminal
 881                          $this->yyidx++;
 882                          $x = new PHP_LexerGenerator_ParseryyStackEntry;
 883                          $x->stateno = $nextstate;
 884                          $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
 885                          $this->yystack[$this->yyidx] = $x;
 886                          continue 2;
 887                      } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
 888                          $this->yyidx = $yyidx;
 889                          $this->yystack = $stack;
 890                          if (!$token) {
 891                              // end of input: this is valid
 892                              return true;
 893                          }
 894                          // the last token was just ignored, we can't accept
 895                          // by ignoring input, this is in essence ignoring a
 896                          // syntax error!
 897                          return false;
 898                      } elseif ($nextstate === self::YY_NO_ACTION) {
 899                          $this->yyidx = $yyidx;
 900                          $this->yystack = $stack;
 901                          // input accepted, but not shifted (I guess)
 902                          return true;
 903                      } else {
 904                          $yyact = $nextstate;
 905                      }
 906                  } while (true);
 907              }
 908              break;
 909          } while (true);
 910          return true;
 911      }
 912  
 913      /**
 914       * Find the appropriate action for a parser given the terminal
 915       * look-ahead token iLookAhead.
 916       *
 917       * If the look-ahead token is YYNOCODE, then check to see if the action is
 918       * independent of the look-ahead.  If it is, return the action, otherwise
 919       * return YY_NO_ACTION.
 920       * @param int The look-ahead token
 921       */
 922      function yy_find_shift_action($iLookAhead)
 923      {
 924          $stateno = $this->yystack[$this->yyidx]->stateno;
 925       
 926          /* if ($this->yyidx < 0) return self::YY_NO_ACTION;  */
 927          if (!isset(self::$yy_shift_ofst[$stateno])) {
 928              // no shift actions
 929              return self::$yy_default[$stateno];
 930          }
 931          $i = self::$yy_shift_ofst[$stateno];
 932          if ($i === self::YY_SHIFT_USE_DFLT) {
 933              return self::$yy_default[$stateno];
 934          }
 935          if ($iLookAhead == self::YYNOCODE) {
 936              return self::YY_NO_ACTION;
 937          }
 938          $i += $iLookAhead;
 939          if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
 940                self::$yy_lookahead[$i] != $iLookAhead) {
 941              if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback)
 942                     && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) {
 943                  if (self::$yyTraceFILE) {
 944                      fwrite(self::$yyTraceFILE, self::$yyTracePrompt . "FALLBACK " .
 945                          self::$yyTokenName[$iLookAhead] . " => " .
 946                          self::$yyTokenName[$iFallback] . "\n");
 947                  }
 948                  return $this->yy_find_shift_action($iFallback);
 949              }
 950              return self::$yy_default[$stateno];
 951          } else {
 952              return self::$yy_action[$i];
 953          }
 954      }
 955  
 956      /**
 957       * Find the appropriate action for a parser given the non-terminal
 958       * look-ahead token $iLookAhead.
 959       *
 960       * If the look-ahead token is self::YYNOCODE, then check to see if the action is
 961       * independent of the look-ahead.  If it is, return the action, otherwise
 962       * return self::YY_NO_ACTION.
 963       * @param int Current state number
 964       * @param int The look-ahead token
 965       */
 966      function yy_find_reduce_action($stateno, $iLookAhead)
 967      {
 968          /* $stateno = $this->yystack[$this->yyidx]->stateno; */
 969  
 970          if (!isset(self::$yy_reduce_ofst[$stateno])) {
 971              return self::$yy_default[$stateno];
 972          }
 973          $i = self::$yy_reduce_ofst[$stateno];
 974          if ($i == self::YY_REDUCE_USE_DFLT) {
 975              return self::$yy_default[$stateno];
 976          }
 977          if ($iLookAhead == self::YYNOCODE) {
 978              return self::YY_NO_ACTION;
 979          }
 980          $i += $iLookAhead;
 981          if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
 982                self::$yy_lookahead[$i] != $iLookAhead) {
 983              return self::$yy_default[$stateno];
 984          } else {
 985              return self::$yy_action[$i];
 986          }
 987      }
 988  
 989      /**
 990       * Perform a shift action.
 991       * @param int The new state to shift in
 992       * @param int The major token to shift in
 993       * @param mixed the minor token to shift in
 994       */
 995      function yy_shift($yyNewState, $yyMajor, $yypMinor)
 996      {
 997          $this->yyidx++;
 998          if ($this->yyidx >= self::YYSTACKDEPTH) {
 999              $this->yyidx--;
1000              if (self::$yyTraceFILE) {
1001                  fprintf(self::$yyTraceFILE, "%sStack Overflow!\n", self::$yyTracePrompt);
1002              }
1003              while ($this->yyidx >= 0) {
1004                  $this->yy_pop_parser_stack();
1005              }
1006              /* Here code is inserted which will execute if the parser
1007              ** stack ever overflows */
1008              return;
1009          }
1010          $yytos = new PHP_LexerGenerator_ParseryyStackEntry;
1011          $yytos->stateno = $yyNewState;
1012          $yytos->major = $yyMajor;
1013          $yytos->minor = $yypMinor;
1014          array_push($this->yystack, $yytos);
1015          if (self::$yyTraceFILE && $this->yyidx > 0) {
1016              fprintf(self::$yyTraceFILE, "%sShift %d\n", self::$yyTracePrompt,
1017                  $yyNewState);
1018              fprintf(self::$yyTraceFILE, "%sStack:", self::$yyTracePrompt);
1019              for($i = 1; $i <= $this->yyidx; $i++) {
1020                  fprintf(self::$yyTraceFILE, " %s",
1021                      self::$yyTokenName[$this->yystack[$i]->major]);
1022              }
1023              fwrite(self::$yyTraceFILE,"\n");
1024          }
1025      }
1026  
1027      /**
1028       * The following table contains information about every rule that
1029       * is used during the reduce.
1030       *
1031       * <pre>
1032       * array(
1033       *  array(
1034       *   int $lhs;         Symbol on the left-hand side of the rule
1035       *   int $nrhs;     Number of right-hand side symbols in the rule
1036       *  ),...
1037       * );
1038       * </pre>
1039       */
1040      static public $yyRuleInfo = array(
1041    array( 'lhs' => 10, 'rhs' => 1 ),
1042    array( 'lhs' => 11, 'rhs' => 2 ),
1043    array( 'lhs' => 11, 'rhs' => 3 ),
1044    array( 'lhs' => 11, 'rhs' => 3 ),
1045    array( 'lhs' => 11, 'rhs' => 4 ),
1046    array( 'lhs' => 12, 'rhs' => 3 ),
1047    array( 'lhs' => 14, 'rhs' => 2 ),
1048    array( 'lhs' => 15, 'rhs' => 2 ),
1049    array( 'lhs' => 15, 'rhs' => 2 ),
1050    array( 'lhs' => 15, 'rhs' => 3 ),
1051    array( 'lhs' => 15, 'rhs' => 3 ),
1052    array( 'lhs' => 16, 'rhs' => 2 ),
1053    array( 'lhs' => 16, 'rhs' => 3 ),
1054    array( 'lhs' => 13, 'rhs' => 3 ),
1055    array( 'lhs' => 13, 'rhs' => 5 ),
1056    array( 'lhs' => 13, 'rhs' => 4 ),
1057    array( 'lhs' => 13, 'rhs' => 6 ),
1058    array( 'lhs' => 13, 'rhs' => 4 ),
1059    array( 'lhs' => 13, 'rhs' => 6 ),
1060    array( 'lhs' => 13, 'rhs' => 5 ),
1061    array( 'lhs' => 13, 'rhs' => 7 ),
1062    array( 'lhs' => 18, 'rhs' => 2 ),
1063    array( 'lhs' => 18, 'rhs' => 3 ),
1064    array( 'lhs' => 19, 'rhs' => 1 ),
1065    array( 'lhs' => 19, 'rhs' => 1 ),
1066    array( 'lhs' => 19, 'rhs' => 2 ),
1067    array( 'lhs' => 19, 'rhs' => 2 ),
1068    array( 'lhs' => 17, 'rhs' => 1 ),
1069    array( 'lhs' => 17, 'rhs' => 1 ),
1070    array( 'lhs' => 17, 'rhs' => 2 ),
1071    array( 'lhs' => 17, 'rhs' => 2 ),
1072      );
1073  
1074      /**
1075       * The following table contains a mapping of reduce action to method name
1076       * that handles the reduction.
1077       * 
1078       * If a rule is not set, it has no handler.
1079       */
1080      static public $yyReduceMap = array(
1081          1 => 1,
1082          2 => 2,
1083          3 => 3,
1084          4 => 4,
1085          5 => 5,
1086          6 => 6,
1087          7 => 7,
1088          8 => 7,
1089          9 => 9,
1090          10 => 9,
1091          11 => 11,
1092          12 => 12,
1093          13 => 13,
1094          14 => 14,
1095          15 => 15,
1096          16 => 16,
1097          17 => 17,
1098          18 => 18,
1099          19 => 19,
1100          20 => 20,
1101          21 => 21,
1102          22 => 22,
1103          23 => 23,
1104          24 => 24,
1105          25 => 25,
1106          26 => 26,
1107          27 => 27,
1108          28 => 28,
1109          29 => 29,
1110          30 => 30,
1111      );
1112      /* Beginning here are the reduction cases.  A typical example
1113      ** follows:
1114      **  #line <lineno> <grammarfile>
1115      **   function yy_r0($yymsp){ ... }           // User supplied code
1116      **  #line <lineno> <thisfile>
1117      */
1118  #line 266 "LexerGenerator\Parser.y"
1119      function yy_r1(){
1120      fwrite($this->out, '
1121      private $_yy_state = 1;
1122      private $_yy_stack = array();
1123  
1124      function yylex()
1125      {
1126          return $this->{\'yylex\' . $this->_yy_state}();
1127      }
1128  
1129      function yypushstate($state)
1130      {
1131          array_push($this->_yy_stack, $this->_yy_state);
1132          $this->_yy_state = $state;
1133      }
1134  
1135      function yypopstate()
1136      {
1137          $this->_yy_state = array_pop($this->_yy_stack);
1138      }
1139  
1140      function yybegin($state)
1141      {
1142          $this->_yy_state = $state;
1143      }
1144  
1145  ');
1146      foreach ($this->yystack[$this->yyidx + 0]->minor as $rule) {
1147          $this->outputRules($rule['rules'], $rule['statename']);
1148          if ($rule['code']) {
1149              fwrite($this->out, $rule['code']);
1150          }
1151      }
1152      }
1153  #line 1159 "LexerGenerator\Parser.php"
1154  #line 300 "LexerGenerator\Parser.y"
1155      function yy_r2(){
1156      fwrite($this->out, '
1157      private $_yy_state = 1;
1158      private $_yy_stack = array();
1159  
1160      function yylex()
1161      {
1162          return $this->{\'yylex\' . $this->_yy_state}();
1163      }
1164  
1165      function yypushstate($state)
1166      {
1167          array_push($this->_yy_stack, $this->_yy_state);
1168          $this->_yy_state = $state;
1169      }
1170  
1171      function yypopstate()
1172      {
1173          $this->_yy_state = array_pop($this->_yy_stack);
1174      }
1175  
1176      function yybegin($state)
1177      {
1178          $this->_yy_state = $state;
1179      }
1180  
1181  ');
1182      if (strlen($this->yystack[$this->yyidx + -1]->minor)) {
1183          fwrite($this->out, $this->yystack[$this->yyidx + -1]->minor);
1184      }
1185      foreach ($this->yystack[$this->yyidx + 0]->minor as $rule) {
1186          $this->outputRules($rule['rules'], $rule['statename']);
1187          if ($rule['code']) {
1188              fwrite($this->out, $rule['code']);
1189          }
1190      }
1191      }
1192  #line 1198 "LexerGenerator\Parser.php"
1193  #line 337 "LexerGenerator\Parser.y"
1194      function yy_r3(){
1195      if (strlen($this->yystack[$this->yyidx + -2]->minor)) {
1196          fwrite($this->out, $this->yystack[$this->yyidx + -2]->minor);
1197      }
1198      fwrite($this->out, '
1199      private $_yy_state = 1;
1200      private $_yy_stack = array();
1201  
1202      function yylex()
1203      {
1204          return $this->{\'yylex\' . $this->_yy_state}();
1205      }
1206  
1207      function yypushstate($state)
1208      {
1209          array_push($this->_yy_stack, $this->_yy_state);
1210          $this->_yy_state = $state;
1211      }
1212  
1213      function yypopstate()
1214      {
1215          $this->_yy_state = array_pop($this->_yy_stack);
1216      }
1217  
1218      function yybegin($state)
1219      {
1220          $this->_yy_state = $state;
1221      }
1222  
1223  ');
1224      foreach ($this->yystack[$this->yyidx + 0]->minor as $rule) {
1225          $this->outputRules($rule['rules'], $rule['statename']);
1226          if ($rule['code']) {
1227              fwrite($this->out, $rule['code']);
1228          }
1229      }
1230      }
1231  #line 1237 "LexerGenerator\Parser.php"
1232  #line 374 "LexerGenerator\Parser.y"
1233      function yy_r4(){
1234      if (strlen($this->yystack[$this->yyidx + -3]->minor)) {
1235          fwrite($this->out, $this->yystack[$this->yyidx + -3]->minor);
1236      }
1237      fwrite($this->out, '
1238      private $_yy_state = 1;
1239      private $_yy_stack = array();
1240  
1241      function yylex()
1242      {
1243          return $this->{\'yylex\' . $this->_yy_state}();
1244      }
1245  
1246      function yypushstate($state)
1247      {
1248          array_push($this->_yy_stack, $this->_yy_state);
1249          $this->_yy_state = $state;
1250      }
1251  
1252      function yypopstate()
1253      {
1254          $this->_yy_state = array_pop($this->_yy_stack);
1255      }
1256  
1257      function yybegin($state)
1258      {
1259          $this->_yy_state = $state;
1260      }
1261  
1262  ');
1263      if (strlen($this->yystack[$this->yyidx + -1]->minor)) {
1264          fwrite($this->out, $this->yystack[$this->yyidx + -1]->minor);
1265      }
1266      foreach ($this->yystack[$this->yyidx + 0]->minor as $rule) {
1267          $this->outputRules($rule['rules'], $rule['statename']);
1268          if ($rule['code']) {
1269              fwrite($this->out, $rule['code']);
1270          }
1271      }
1272      }
1273  #line 1279 "LexerGenerator\Parser.php"
1274  #line 415 "LexerGenerator\Parser.y"
1275      function yy_r5(){
1276      $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
1277      $this->patterns = $this->yystack[$this->yyidx + -1]->minor['patterns'];
1278      }
1279  #line 1285 "LexerGenerator\Parser.php"
1280  #line 420 "LexerGenerator\Parser.y"
1281      function yy_r6(){
1282      $expected = array(
1283          'counter' => true,
1284          'input' => true,
1285          'token' => true,
1286          'value' => true,
1287          'line' => true,
1288      );
1289      foreach ($this->yystack[$this->yyidx + -1]->minor as $pi) {
1290          if (isset($expected[$pi['pi']])) {
1291              unset($expected[$pi['pi']]);
1292              continue;
1293          }
1294          if (count($expected)) {
1295              throw new Exception('Processing Instructions "' .
1296                  implode(', ', array_keys($expected)) . '" must be defined');
1297          }
1298      }
1299      $expected = array(
1300          'counter' => true,
1301          'input' => true,
1302          'token' => true,
1303          'value' => true,
1304          'line' => true,
1305      );
1306      foreach ($this->yystack[$this->yyidx + -1]->minor as $pi) {
1307          if (isset($expected[$pi['pi']])) {
1308              $this->{$pi['pi']} = $pi['definition'];
1309              continue;
1310          }
1311          $this->error('Unknown processing instruction %' . $pi['pi'] .
1312              ', should be one of "' . implode(', ', array_keys($expected)) . '"');
1313      }
1314      $this->_retvalue = array('patterns' => $this->yystack[$this->yyidx + 0]->minor, 'pis' => $this->yystack[$this->yyidx + -1]->minor);
1315      }
1316  #line 1322 "LexerGenerator\Parser.php"
1317  #line 456 "LexerGenerator\Parser.y"
1318      function yy_r7(){
1319      $this->_retvalue = array(array('pi' => $this->yystack[$this->yyidx + -1]->minor, 'definition' => $this->yystack[$this->yyidx + 0]->minor));
1320      }
1321  #line 1327 "LexerGenerator\Parser.php"
1322  #line 462 "LexerGenerator\Parser.y"
1323      function yy_r9(){
1324      $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor;
1325      $this->_retvalue[] = array('pi' => $this->yystack[$this->yyidx + -1]->minor, 'definition' => $this->yystack[$this->yyidx + 0]->minor);
1326      }
1327  #line 1333 "LexerGenerator\Parser.php"
1328  #line 471 "LexerGenerator\Parser.y"
1329      function yy_r11(){
1330      $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor => $this->yystack[$this->yyidx + 0]->minor);
1331      }
1332  #line 1338 "LexerGenerator\Parser.php"
1333  #line 474 "LexerGenerator\Parser.y"
1334      function yy_r12(){
1335      $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor;
1336      if (isset($this->_retvalue[$this->yystack[$this->yyidx + -1]->minor])) {
1337          throw new Exception('Pattern "' . $this->yystack[$this->yyidx + -1]->minor . '" is already defined as "' .
1338              $this->_retvalue[$this->yystack[$this->yyidx + -1]->minor] . '", cannot redefine as "' . $this->yystack[$this->yyidx + 0]->minor->string . '"');
1339      }
1340      $this->_retvalue[$this->yystack[$this->yyidx + -1]->minor] = $this->yystack[$this->yyidx + 0]->minor;
1341      }
1342  #line 1348 "LexerGenerator\Parser.php"
1343  #line 483 "LexerGenerator\Parser.y"
1344      function yy_r13(){
1345      $this->_retvalue = array(array('rules' => $this->yystack[$this->yyidx + -1]->minor, 'code' => '', 'statename' => ''));
1346      }
1347  #line 1353 "LexerGenerator\Parser.php"
1348  #line 486 "LexerGenerator\Parser.y"
1349      function yy_r14(){
1350      if ($this->yystack[$this->yyidx + -3]->minor != 'statename') {
1351          throw new Exception('Error: only %statename processing instruction ' .
1352              'is allowed in rule sections');
1353      }
1354      $this->_retvalue = array(array('rules' => $this->yystack[$this->yyidx + -1]->minor, 'code' => '', 'statename' => $this->yystack[$this->yyidx + -2]->minor));
1355      }
1356  #line 1362 "LexerGenerator\Parser.php"
1357  #line 493 "LexerGenerator\Parser.y"
1358      function yy_r15(){
1359      $this->_retvalue = array(array('rules' => $this->yystack[$this->yyidx + -2]->minor, 'code' => $this->yystack[$this->yyidx + 0]->minor, 'statename' => ''));
1360      }
1361  #line 1367 "LexerGenerator\Parser.php"
1362  #line 496 "LexerGenerator\Parser.y"
1363      function yy_r16(){
1364      if ($this->yystack[$this->yyidx + -4]->minor != 'statename') {
1365          throw new Exception('Error: only %statename processing instruction ' .
1366              'is allowed in rule sections');
1367      }
1368      $this->_retvalue = array(array('rules' => $this->yystack[$this->yyidx + -2]->minor, 'code' => $this->yystack[$this->yyidx + 0]->minor, 'statename' => $this->yystack[$this->yyidx + -3]->minor));
1369      }
1370  #line 1376 "LexerGenerator\Parser.php"
1371  #line 503 "LexerGenerator\Parser.y"
1372      function yy_r17(){
1373      $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor;
1374      $this->_retvalue[] = array('rules' => $this->yystack[$this->yyidx + -1]->minor, 'code' => '', 'statename' => '');
1375      }
1376  #line 1382 "LexerGenerator\Parser.php"
1377  #line 507 "LexerGenerator\Parser.y"
1378      function yy_r18(){
1379      if ($this->yystack[$this->yyidx + -4]->minor != 'statename') {
1380          throw new Exception('Error: only %statename processing instruction ' .
1381              'is allowed in rule sections');
1382      }
1383      $this->_retvalue = $this->yystack[$this->yyidx + -5]->minor;
1384      $this->_retvalue[] = array('rules' => $this->yystack[$this->yyidx + -1]->minor, 'code' => '', 'statename' => $this->yystack[$this->yyidx + -3]->minor);
1385      }
1386  #line 1392 "LexerGenerator\Parser.php"
1387  #line 515 "LexerGenerator\Parser.y"
1388      function yy_r19(){
1389      $this->_retvalue = $this->yystack[$this->yyidx + -4]->minor;
1390      $this->_retvalue[] = array('rules' => $this->yystack[$this->yyidx + -2]->minor, 'code' => $this->yystack[$this->yyidx + 0]->minor, 'statename' => '');
1391      }
1392  #line 1398 "LexerGenerator\Parser.php"
1393  #line 519 "LexerGenerator\Parser.y"
1394      function yy_r20(){
1395      if ($this->yystack[$this->yyidx + -4]->minor != 'statename') {
1396          throw new Exception('Error: only %statename processing instruction ' .
1397              'is allowed in rule sections');
1398      }
1399      $this->_retvalue = $this->yystack[$this->yyidx + -6]->minor;
1400      $this->_retvalue[] = array('rules' => $this->yystack[$this->yyidx + -2]->minor, 'code' => $this->yystack[$this->yyidx + 0]->minor, 'statename' => $this->yystack[$this->yyidx + -3]->minor);
1401      }
1402  #line 1408 "LexerGenerator\Parser.php"
1403  #line 528 "LexerGenerator\Parser.y"
1404      function yy_r21(){
1405      if (@preg_match('/' . $this->yystack[$this->yyidx + -1]->minor[0] . '/', '')) {
1406          $this->error('Rule "' . $this->yystack[$this->yyidx + -1]->minor[2] . '" can match the empty string, this will break lexing');
1407      }
1408      $this->_retvalue = array(array('pattern' => $this->yystack[$this->yyidx + -1]->minor[1], 'code' => $this->yystack[$this->yyidx + 0]->minor, 'subpatterns' => $this->yystack[$this->yyidx + -1]->minor[3]));
1409      }
1410  #line 1416 "LexerGenerator\Parser.php"
1411  #line 534 "LexerGenerator\Parser.y"
1412      function yy_r22(){
1413      $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor;
1414      if (@preg_match('/' . $this->yystack[$this->yyidx + -1]->minor[0] . '/', '')) {
1415          $this->error('Rule "' . $this->yystack[$this->yyidx + -1]->minor[2] . '" can match the empty string, this will break lexing');
1416      }
1417      $this->_retvalue[] = array('pattern' => $this->yystack[$this->yyidx + -1]->minor[1], 'code' => $this->yystack[$this->yyidx + 0]->minor, 'subpatterns' => $this->yystack[$this->yyidx + -1]->minor[3]);
1418      }
1419  #line 1425 "LexerGenerator\Parser.php"
1420  #line 542 "LexerGenerator\Parser.y"
1421      function yy_r23(){
1422      $this->_retvalue = array(
1423          preg_quote($this->yystack[$this->yyidx + 0]->minor, '/'),
1424          str_replace(array('\\', '"'), array('\\\\', '\\"'), preg_quote($this->yystack[$this->yyidx + 0]->minor, '/')),
1425          '"' . str_replace('"', '\"', $this->yystack[$this->yyidx + 0]->minor) . '"', 0);
1426      }
1427  #line 1433 "LexerGenerator\Parser.php"
1428  #line 548 "LexerGenerator\Parser.y"
1429      function yy_r24(){
1430      if (!isset($this->patterns[$this->yystack[$this->yyidx + 0]->minor])) {
1431          $this->error('Undefined pattern "' . $this->yystack[$this->yyidx + 0]->minor . '" used in rules');
1432          throw new Exception('Undefined pattern "' . $this->yystack[$this->yyidx + 0]->minor . '" used in rules');
1433      }
1434      $this->_retvalue = array($this->patterns[$this->yystack[$this->yyidx + 0]->minor]['pattern'], $this->patterns[$this->yystack[$this->yyidx + 0]->minor]->string, $this->yystack[$this->yyidx + 0]->minor, $this->patterns[$this->yystack[$this->yyidx + 0]->minor]['subpatterns']);
1435      }
1436  #line 1442 "LexerGenerator\Parser.php"
1437  #line 555 "LexerGenerator\Parser.y"
1438      function yy_r25(){
1439      $this->_retvalue = array(
1440          $this->yystack[$this->yyidx + -1]->minor[0] . preg_quote($this->yystack[$this->yyidx + 0]->minor, '/'),
1441          $this->yystack[$this->yyidx + -1]->minor[1] . str_replace(array('\\', '"'), array('\\\\', '\\"'), preg_quote($this->yystack[$this->yyidx + 0]->minor, '/')),
1442          $this->yystack[$this->yyidx + -1]->minor[2] . ' "' . str_replace('"', '\"', $this->yystack[$this->yyidx + 0]->minor) . '"', $this->yystack[$this->yyidx + -1]->minor[3]);
1443      }
1444  #line 1450 "LexerGenerator\Parser.php"
1445  #line 561 "LexerGenerator\Parser.y"
1446      function yy_r26(){
1447      if (!isset($this->patterns[$this->yystack[$this->yyidx + 0]->minor])) {
1448          $this->error('Undefined pattern "' . $this->yystack[$this->yyidx + 0]->minor . '" used in rules');
1449          throw new Exception('Undefined pattern "' . $this->yystack[$this->yyidx + 0]->minor . '" used in rules');
1450      }
1451      $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor[0] . $this->patterns[$this->yystack[$this->yyidx + 0]->minor]['pattern'], $this->yystack[$this->yyidx + -1]->minor[1] . $this->patterns[$this->yystack[$this->yyidx + 0]->minor]->string,
1452          $this->yystack[$this->yyidx + -1]->minor[2] . ' ' . $this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor[3] + $this->patterns[$this->yystack[$this->yyidx + 0]->minor]['subpatterns']);
1453      }
1454  #line 1460 "LexerGenerator\Parser.php"
1455  #line 570 "LexerGenerator\Parser.y"
1456      function yy_r27(){
1457      $this->_retvalue = new PHP_LexerGenerator_ParseryyToken(str_replace(array('\\', '"'), array('\\\\', '\\"'), preg_quote($this->yystack[$this->yyidx + 0]->minor, '/')), array(
1458          'pattern' => preg_quote($this->yystack[$this->yyidx + 0]->minor, '/'), 'subpatterns' => 0));
1459      }
1460  #line 1466 "LexerGenerator\Parser.php"
1461  #line 574 "LexerGenerator\Parser.y"
1462      function yy_r28(){
1463      $this->_retvalue = $this->_validatePattern($this->yystack[$this->yyidx + 0]->minor);
1464      }
1465  #line 1471 "LexerGenerator\Parser.php"
1466  #line 577 "LexerGenerator\Parser.y"
1467      function yy_r29(){
1468      $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -1]->minor->string . str_replace(array('\\', '"'), array('\\\\', '\\"'), preg_quote($this->yystack[$this->yyidx + 0]->minor, '/')), array(
1469          'pattern' => $this->yystack[$this->yyidx + -1]->minor['pattern'] . preg_quote($this->yystack[$this->yyidx + 0]->minor, '/'), 'subpatterns' => $this->yystack[$this->yyidx + -1]->minor['subpatterns']));
1470      }
1471  #line 1477 "LexerGenerator\Parser.php"
1472  #line 581 "LexerGenerator\Parser.y"
1473      function yy_r30(){
1474      $x = $this->_validatePattern($this->yystack[$this->yyidx + 0]->minor);
1475      $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -1]->minor->string . $x->string, array(
1476          'pattern' => $this->yystack[$this->yyidx + -1]->minor['pattern'] . $x['pattern'],
1477          'subpatterns' => $x['subpatterns'] + $this->yystack[$this->yyidx + -1]->minor['subpatterns']));
1478      }
1479  #line 1485 "LexerGenerator\Parser.php"
1480  
1481      /**
1482       * placeholder for the left hand side in a reduce operation.
1483       * 
1484       * For a parser with a rule like this:
1485       * <pre>
1486       * rule(A) ::= B. { A = 1; }
1487       * </pre>
1488       * 
1489       * The parser will translate to something like:
1490       * 
1491       * <code>
1492       * function yy_r0(){$this->_retvalue = 1;}
1493       * </code>
1494       */
1495      private $_retvalue;
1496  
1497      /**
1498       * Perform a reduce action and the shift that must immediately
1499       * follow the reduce.
1500       * 
1501       * For a rule such as:
1502       * 
1503       * <pre>
1504       * A ::= B blah C. { dosomething(); }
1505       * </pre>
1506       * 
1507       * This function will first call the action, if any, ("dosomething();" in our
1508       * example), and then it will pop three states from the stack,
1509       * one for each entry on the right-hand side of the expression
1510       * (B, blah, and C in our example rule), and then push the result of the action
1511       * back on to the stack with the resulting state reduced to (as described in the .out
1512       * file)
1513       * @param int Number of the rule by which to reduce
1514       */
1515      function yy_reduce($yyruleno)
1516      {
1517          //int $yygoto;                     /* The next state */
1518          //int $yyact;                      /* The next action */
1519          //mixed $yygotominor;        /* The LHS of the rule reduced */
1520          //PHP_LexerGenerator_ParseryyStackEntry $yymsp;            /* The top of the parser's stack */
1521          //int $yysize;                     /* Amount to pop the stack */
1522          $yymsp = $this->yystack[$this->yyidx];
1523          if (self::$yyTraceFILE && $yyruleno >= 0 
1524                && $yyruleno < count(self::$yyRuleName)) {
1525              fprintf(self::$yyTraceFILE, "%sReduce (%d) [%s].\n",
1526                  self::$yyTracePrompt, $yyruleno,
1527                  self::$yyRuleName[$yyruleno]);
1528          }
1529  
1530          $this->_retvalue = $yy_lefthand_side = null;
1531          if (array_key_exists($yyruleno, self::$yyReduceMap)) {
1532              // call the action
1533              $this->_retvalue = null;
1534              $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}();
1535              $yy_lefthand_side = $this->_retvalue;
1536          }
1537          $yygoto = self::$yyRuleInfo[$yyruleno]['lhs'];
1538          $yysize = self::$yyRuleInfo[$yyruleno]['rhs'];
1539          $this->yyidx -= $yysize;
1540          for($i = $yysize; $i; $i--) {
1541              // pop all of the right-hand side parameters
1542              array_pop($this->yystack);
1543          }
1544          $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto);
1545          if ($yyact < self::YYNSTATE) {
1546              /* If we are not debugging and the reduce action popped at least
1547              ** one element off the stack, then we can push the new element back
1548              ** onto the stack here, and skip the stack overflow test in yy_shift().
1549              ** That gives a significant speed improvement. */
1550              if (!self::$yyTraceFILE && $yysize) {
1551                  $this->yyidx++;
1552                  $x = new PHP_LexerGenerator_ParseryyStackEntry;
1553                  $x->stateno = $yyact;
1554                  $x->major = $yygoto;
1555                  $x->minor = $yy_lefthand_side;
1556                  $this->yystack[$this->yyidx] = $x;
1557              } else {
1558                  $this->yy_shift($yyact, $yygoto, $yy_lefthand_side);
1559              }
1560          } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) {
1561              $this->yy_accept();
1562          }
1563      }
1564  
1565      /**
1566       * The following code executes when the parse fails
1567       * 
1568       * Code from %parse_fail is inserted here
1569       */
1570      function yy_parse_failed()
1571      {
1572          if (self::$yyTraceFILE) {
1573              fprintf(self::$yyTraceFILE, "%sFail!\n", self::$yyTracePrompt);
1574          }
1575          while ($this->yyidx >= 0) {
1576              $this->yy_pop_parser_stack();
1577          }
1578          /* Here code is inserted which will be executed whenever the
1579          ** parser fails */
1580      }
1581  
1582      /**
1583       * The following code executes when a syntax error first occurs.
1584       * 
1585       * %syntax_error code is inserted here
1586       * @param int The major type of the error token
1587       * @param mixed The minor type of the error token
1588       */
1589      function yy_syntax_error($yymajor, $TOKEN)
1590      {
1591  #line 70 "LexerGenerator\Parser.y"
1592  
1593      echo "Syntax Error on line " . $this->lex->line . ": token '" . 
1594          $this->lex->value . "' while parsing rule:";
1595      foreach ($this->yystack as $entry) {
1596          echo $this->tokenName($entry->major) . ' ';
1597      }
1598      foreach ($this->yy_get_expected_tokens($yymajor) as $token) {
1599          $expect[] = self::$yyTokenName[$token];
1600      }
1601      throw new Exception('Unexpected ' . $this->tokenName($yymajor) . '(' . $TOKEN
1602          . '), expected one of: ' . implode(',', $expect));
1603  #line 1610 "LexerGenerator\Parser.php"
1604      }
1605  
1606      /**
1607       * The following is executed when the parser accepts
1608       * 
1609       * %parse_accept code is inserted here
1610       */
1611      function yy_accept()
1612      {
1613          if (self::$yyTraceFILE) {
1614              fprintf(self::$yyTraceFILE, "%sAccept!\n", self::$yyTracePrompt);
1615          }
1616          while ($this->yyidx >= 0) {
1617              $stack = $this->yy_pop_parser_stack();
1618          }
1619          /* Here code is inserted which will be executed whenever the
1620          ** parser accepts */
1621      }
1622  
1623      /**
1624       * The main parser program.
1625       * 
1626       * The first argument is the major token number.  The second is
1627       * the token value string as scanned from the input.
1628       *
1629       * @param int the token number
1630       * @param mixed the token value
1631       * @param mixed any extra arguments that should be passed to handlers
1632       */
1633      function doParse($yymajor, $yytokenvalue)
1634      {
1635  //        $yyact;            /* The parser action. */
1636  //        $yyendofinput;     /* True if we are at the end of input */
1637          $yyerrorhit = 0;   /* True if yymajor has invoked an error */
1638          
1639          /* (re)initialize the parser, if necessary */
1640          if ($this->yyidx === null || $this->yyidx < 0) {
1641              /* if ($yymajor == 0) return; // not sure why this was here... */
1642              $this->yyidx = 0;
1643              $this->yyerrcnt = -1;
1644              $x = new PHP_LexerGenerator_ParseryyStackEntry;
1645              $x->stateno = 0;
1646              $x->major = 0;
1647              $this->yystack = array();
1648              array_push($this->yystack, $x);
1649          }
1650          $yyendofinput = ($yymajor==0);
1651          
1652          if (self::$yyTraceFILE) {
1653              fprintf(self::$yyTraceFILE, "%sInput %s\n",
1654                  self::$yyTracePrompt, self::$yyTokenName[$yymajor]);
1655          }
1656          
1657          do {
1658              $yyact = $this->yy_find_shift_action($yymajor);
1659              if ($yymajor < self::YYERRORSYMBOL &&
1660                    !$this->yy_is_expected_token($yymajor)) {
1661                  // force a syntax error
1662                  $yyact = self::YY_ERROR_ACTION;
1663              }
1664              if ($yyact < self::YYNSTATE) {
1665                  $this->yy_shift($yyact, $yymajor, $yytokenvalue);
1666                  $this->yyerrcnt--;
1667                  if ($yyendofinput && $this->yyidx >= 0) {
1668                      $yymajor = 0;
1669                  } else {
1670                      $yymajor = self::YYNOCODE;
1671                  }
1672              } elseif ($yyact < self::YYNSTATE + self::YYNRULE) {
1673                  $this->yy_reduce($yyact - self::YYNSTATE);
1674              } elseif ($yyact == self::YY_ERROR_ACTION) {
1675                  if (self::$yyTraceFILE) {
1676                      fprintf(self::$yyTraceFILE, "%sSyntax Error!\n",
1677                          self::$yyTracePrompt);
1678                  }
1679                  if (self::YYERRORSYMBOL) {
1680                      /* A syntax error has occurred.
1681                      ** The response to an error depends upon whether or not the
1682                      ** grammar defines an error token "ERROR".  
1683                      **
1684                      ** This is what we do if the grammar does define ERROR:
1685                      **
1686                      **  * Call the %syntax_error function.
1687                      **
1688                      **  * Begin popping the stack until we enter a state where
1689                      **    it is legal to shift the error symbol, then shift
1690                      **    the error symbol.
1691                      **
1692                      **  * Set the error count to three.
1693                      **
1694                      **  * Begin accepting and shifting new tokens.  No new error
1695                      **    processing will occur until three tokens have been
1696                      **    shifted successfully.
1697                      **
1698                      */
1699                      if ($this->yyerrcnt < 0) {
1700                          $this->yy_syntax_error($yymajor, $yytokenvalue);
1701                      }
1702                      $yymx = $this->yystack[$this->yyidx]->major;
1703                      if ($yymx == self::YYERRORSYMBOL || $yyerrorhit ){
1704                          if (self::$yyTraceFILE) {
1705                              fprintf(self::$yyTraceFILE, "%sDiscard input token %s\n",
1706                                  self::$yyTracePrompt, self::$yyTokenName[$yymajor]);
1707                          }
1708                          $this->yy_destructor($yymajor, $yytokenvalue);
1709                          $yymajor = self::YYNOCODE;
1710                      } else {
1711                          while ($this->yyidx >= 0 &&
1712                                   $yymx != self::YYERRORSYMBOL &&
1713          ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE
1714                                ){
1715                              $this->yy_pop_parser_stack();
1716                          }
1717                          if ($this->yyidx < 0 || $yymajor==0) {
1718                              $this->yy_destructor($yymajor, $yytokenvalue);
1719                              $this->yy_parse_failed();
1720                              $yymajor = self::YYNOCODE;
1721                          } elseif ($yymx != self::YYERRORSYMBOL) {
1722                              $u2 = 0;
1723                              $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2);
1724                          }
1725                      }
1726                      $this->yyerrcnt = 3;
1727                      $yyerrorhit = 1;
1728                  } else {
1729                      /* YYERRORSYMBOL is not defined */
1730                      /* This is what we do if the grammar does not define ERROR:
1731                      **
1732                      **  * Report an error message, and throw away the input token.
1733                      **
1734                      **  * If the input token is $, then fail the parse.
1735                      **
1736                      ** As before, subsequent error messages are suppressed until
1737                      ** three input tokens have been successfully shifted.
1738                      */
1739                      if ($this->yyerrcnt <= 0) {
1740                          $this->yy_syntax_error($yymajor, $yytokenvalue);
1741                      }
1742                      $this->yyerrcnt = 3;
1743                      $this->yy_destructor($yymajor, $yytokenvalue);
1744                      if ($yyendofinput) {
1745                          $this->yy_parse_failed();
1746                      }
1747                      $yymajor = self::YYNOCODE;
1748                  }
1749              } else {
1750                  $this->yy_accept();
1751                  $yymajor = self::YYNOCODE;
1752              }            
1753          } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0);
1754      }
1755  }


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1