Пример #1
0
 /**
  * Compute all LR(0) states for the grammar.  Links
  * are added to between some states so that the LR(1) follow sets
  * can be computed later.
  */
 function FindStates()
 {
     PHP_ParserGenerator_Config::Configlist_init();
     /* Find the start symbol */
     if ($this->start) {
         $sp = PHP_ParserGenerator_Symbol::Symbol_find($this->start);
         if ($sp == 0) {
             PHP_ParserGenerator::ErrorMsg($this->filename, 0, "The specified start symbol \"%s\" is not " . "in a nonterminal of the grammar.  \"%s\" will be used as the start " . "symbol instead.", $this->start, $this->rule->lhs->name);
             $this->errorcnt++;
             $sp = $this->rule->lhs;
         }
     } else {
         $sp = $this->rule->lhs;
     }
     /* Make sure the start symbol doesn't occur on the right-hand side of
      ** any rule.  Report an error if it does.  (YACC would generate a new
      ** start symbol in this case.) */
     for ($rp = $this->rule; $rp; $rp = $rp->next) {
         for ($i = 0; $i < $rp->nrhs; $i++) {
             if ($rp->rhs[$i]->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
                 foreach ($rp->rhs[$i]->subsym as $subsp) {
                     if ($subsp === $sp) {
                         PHP_ParserGenerator::ErrorMsg($this->filename, 0, "The start symbol \"%s\" occurs on the " . "right-hand side of a rule. This will result in a parser which " . "does not work properly.", $sp->name);
                         $this->errorcnt++;
                     }
                 }
             } elseif ($rp->rhs[$i] === $sp) {
                 PHP_ParserGenerator::ErrorMsg($this->filename, 0, "The start symbol \"%s\" occurs on the " . "right-hand side of a rule. This will result in a parser which " . "does not work properly.", $sp->name);
                 $this->errorcnt++;
             }
         }
     }
     /* The basis configuration set for the first state
      ** is all rules which have the start symbol as their
      ** left-hand side */
     for ($rp = $sp->rule; $rp; $rp = $rp->nextlhs) {
         $newcfp = PHP_ParserGenerator_Config::Configlist_addbasis($rp, 0);
         $newcfp->fws[0] = 1;
     }
     /* Compute the first state.  All other states will be
      ** computed automatically during the computation of the first one.
      ** The returned pointer to the first state is not used. */
     $newstp = array();
     $newstp = $this->getstate();
     if (is_array($newstp)) {
         $this->buildshifts($newstp[0]);
         /* Recursively compute successor states */
     }
 }