/** * 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 */ } }