/** * Initializes grammar G = (N, T, P, S) * @param PaccSet<PaccNonterminal> * @param PaccSet<PaccTerminal> * @param PaccSet<PaccProduction> * @param PaccNonterminal */ public function __construct(PaccSet $nonterminals, PaccSet $terminals, PaccSet $productions, PaccNonterminal $start) { // check if ($nonterminals->getType() !== 'PaccNonterminal') { throw new InvalidArgumentException('PaccSet<PaccNonterminal> expected, PaccSet<' . $nonterminals->getType() . '> given.'); } if ($terminals->getType() !== 'PaccTerminal') { throw new InvalidArgumentException('PaccSet<PaccTerminal> expected, PaccSet<' . $terminals->getType() . '> given.'); } if ($productions->getType() !== 'PaccProduction') { throw new InvalidArgumentException('PaccSet<PaccProduction> expected, PaccSet<' . $productions->getType() . '> given.'); } // initialize $this->nonterminals = $nonterminals; $this->terminals = $terminals; $this->productions = $productions; $this->start = $start; }
/** * @param PaccSet<PaccLRItem> * @param PaccSymbol * @return PaccSet<PaccLRItem> */ private function jump(PaccSet $items, PaccSymbol $symbol) { if ($items->getType() !== 'PaccLRItem') { throw new InvalidArgumentException('Bad type - expected PaccSet<LRItem>, given PaccSet<' . $items->getType() . '>.'); } $ret = new PaccSet('PaccLRItem'); foreach ($items as $item) { if (!(current($item->afterDot()) !== FALSE && current($item->afterDot())->__eq($symbol))) { continue; } $ret->add(new PaccLRItem($item->production, $item->dot + 1, $item->terminalindex)); } return $this->closure($ret); }