phpDocumentor PHP_LexerGenerator
[ class tree: PHP_LexerGenerator ] [ index: PHP_LexerGenerator ] [ all elements ]

Source for file Parser.php

Documentation is available at Parser.php

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