public function push(CollectionInterface $set)
 {
     if ($set->count() > 0 && !$this->exists($set)) {
         $this->_items[] = $set;
         return true;
     }
     return false;
 }
 /**
  * Calculates the closure set for the given set of rules
  *
  * @param \Phparser\Rule\RulesCollection $set Set of rules
  * @return array
  */
 protected function _closure(CollectionInterface $set)
 {
     $regex = implode('|', $this->variables());
     $hasChanged = true;
     while ($hasChanged) {
         $hasChanged = false;
         foreach ($set as $rule) {
             $result = preg_match('/\\.\\b(' . $regex . ')\\b/', $rule->rhs(), $matches);
             if ($result) {
                 $variable = str_replace('.', '', $matches[1]);
                 foreach ($this->_rules as $r) {
                     $lhs = $r->lhs();
                     if ($lhs == $variable) {
                         $newRHS = '.' . $r->rhs();
                         $newPro = new Rule("{$variable} -> {$newRHS}");
                         if ($set->push($newPro)) {
                             $hasChanged = true;
                         }
                     }
                 }
             }
         }
     }
     return $set;
 }
 /**
  * Constructor.
  * 
  * @param \Phparser\Rule\CollectionInterface $rules Rules of the grammar, used to
  *  extract all valid symbols (variables and terminals) which are the columns
  *  of this table.
  */
 public function __construct(CollectionInterface $rules)
 {
     $this->_columns = array_merge($rules->terminals(), ['$'], $rules->variables());
 }