/** * Calculates the closure set for the given set of rules * * @param \Phparser\Rule\RulesCollection $set Set of rules * @return array */ protected function _closure(RulesCollection $set) { $regex = implode('|', $this->variables()); $first = $this->first(); $hasChanged = true; while ($hasChanged) { $hasChanged = false; foreach ($set as $rule) { $rhs = $rule->rhs(); $result = preg_match('/\\.\\b(' . $regex . ')\\b/', $rhs, $matches); if ($result) { $rightSymbols = end(explode($matches[1], $rhs)); $variable = str_replace('.', '', $matches[1]); foreach ($this->_rules as $r) { $lhs = $r->lhs(); if ($lhs == $variable) { $seq = trim($rightSymbols . ' ' . $rule->lookahead()); foreach ($this->_first($first, $seq) as $lookahead) { $newRHS = '.' . $r->rhs(); $newPro = new Rule("{$variable} -> {$newRHS}"); $newPro->lookahead($lookahead); if ($set->push($newPro)) { $hasChanged = true; } } } } } } } return $set; }