function recursive_closure($callable, $queue) { bug_unless(is_callable($callable)); bug_unless(is_array($queue)); $seen = array(); while (!empty($queue)) { $subject = array_shift($queue); if (isset($seen[$subject])) { continue; } $seen[$subject] = true; foreach (call_user_func($callable, $subject) as $element) { $queue[] = $element; } } return array_keys($seen); }
function add_rhs($rhs) { bug_unless($rhs instanceof lime_rhs); $this->rhs[] = $rhs; }
public function __construct($rule, $dot, $follow) { $this->rule = $rule; $this->dot = $dot; $this->key = $rule->id . '.' . $dot; $this->rightmost = count($rule->rhs) <= $dot; $this->symbol_after_the_dot = $this->rightmost ? null : $rule->rhs[$dot]; $this->_blink = array(); $this->follow = new set($follow); $this->_flink = array(); bug_unless($this->rightmost or count($rule)); }
function next() { $start = $this->stream->pos(); bug_unless(is_array($this->pattern[$this->state]), 'No state called ' . $this->state); # much faster implementation of the lexer, by leveraging PCRE a bit better. if ($match = $this->stream->test($this->megaregexp[$this->state])) { $text = $match[0]; $tmp = array_flip($match); $index = $tmp[$text] - 1; $pattern = $this->pattern[$this->state][$index]; $type = $pattern[1]; //->type; $action = $pattern[3]; //->action; if ($action) { $action($type, $text, $match, $this->state, $this->context); } if ($pattern[2]) { return $this->next(); } $stop = $this->stream->pos(); return new token($type, $text, $start, $stop); } return $this->stream->default_rule(); }