Esempio n. 1
0
 /**
  * @return PaccSet<PaccLRItem>
  */
 private function closure(PaccSet $items)
 {
     if ($items->getType() !== 'PaccLRItem') {
         throw new InvalidArgumentException('Bad type - expected PaccSet<LRItem>, given PaccSet<' . $items->getType() . '>.');
     }
     do {
         $done = TRUE;
         $itemscopy = clone $items;
         foreach ($items as $item) {
             if (!(count($item->afterDot()) >= 1 && current($item->afterDot()) instanceof PaccNonterminal)) {
                 continue;
             }
             $newitems = new PaccSet('PaccLRItem');
             $beta_first = new PaccSet('integer');
             if (count($item->afterDot()) > 1) {
                 $beta_first->add(next($item->afterDot())->first);
                 $beta_first->delete($this->grammar->epsilon->index);
             }
             if ($beta_first->isEmpty()) {
                 $beta_first->add($item->terminalindex);
             }
             $B = current($item->afterDot());
             foreach ($this->grammar->productions as $production) {
                 if ($B->__eq($production->left)) {
                     foreach ($beta_first as $terminalindex) {
                         $newitems->add(new PaccLRItem($production, 0, $terminalindex));
                     }
                 }
             }
             if (!$newitems->isEmpty() && !$itemscopy->contains($newitems)) {
                 $itemscopy->add($newitems);
                 $done = FALSE;
             }
         }
         $items = $itemscopy;
     } while (!$done);
     return $items;
 }