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

Documentation generated on Mon, 11 Mar 2019 15:41:02 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.