public function parseInputStreamWithBacktracking(InputStreamInterface $input, ExpressionResultInterface $previous_result = null) { if ($previous_result !== null) { return null; } $string = $input->getRemainingString(); $result = $this->string_parser->parse($string); if ($result === null) { $input->move(-strlen($string)); return null; } $input->move($result->getLength() - strlen($string)); return $result; }
private function parseWithPreviousResult(InputStreamInterface $input, RepeaterExpressionResult $previous_result) { $part_results = $previous_result->getResults(); $length = count($part_results); if ($length > 0) { //we can backtrack the previous result $index = $length - 1; $position = $previous_result->getLength() - $part_results[$index]->getLength(); $input->move($position); $last_part = $this->inner->parseInputStreamWithBacktracking($input, $part_results[$index]); if ($last_part !== null) { //succesfully backtracked, replace the entry $part_results[$index] = $last_part; return new RepeaterExpressionResult($part_results); } //failed to backtrack, fallthrough and find the next entry $input->move($part_results[$index]->getLength()); } if ($length >= $this->maximum) { return null; } $next_result = $this->inner->parseInputStreamWithBacktracking($input); if ($next_result === null) { $input->move(-$previous_result->getLength()); return null; } $part_results[] = $next_result; return new RepeaterExpressionResult($part_results); }
private function parseWithPreviousResult(InputStreamInterface $input, RepeaterExpressionResult $previous_result) { $part_results = iterator_to_array($previous_result->getResults()); $length = count($part_results); if ($length === 0) { return null; } $index = $length - 1; //we need to backtrack the last result. //find the position where the last entry starts $position = $previous_result->getLength() - $part_results[$index]->getLength(); $input->move($position); //backtrack that entry $last_part = $this->inner->parseInputStreamWithBacktracking($input, $part_results[$index]); if ($last_part === null) { //it failed, our new result excludes this item. Still atleast the minimum? if ($index < $this->minimum) { $input->move(-$position); return null; } return new RepeaterExpressionResult(new \ArrayIterator(array_slice($part_results, 0, $index))); } //replace the entry $part_results[$index] = $last_part; return new RepeaterExpressionResult(new \ArrayIterator($part_results)); }
public function parseInputStreamWithBacktracking(InputStreamInterface $input, ExpressionResultInterface $previous_result = null) { if ($previous_result !== null) { return null; } if ($input->matchesChar($this->string) === false) { return null; } $input->move(1); return $this->result; }
public function parseInputStreamWithBacktracking(InputStreamInterface $input, ExpressionResultInterface $previous_result = null) { if ($previous_result !== null && $previous_result instanceof ConcatenatedExpressionResult === false) { throw new \Exception("Expected " . ConcatenatedExpressionResult::class); } /** @var ConcatenatedExpressionResult|null $previous_result */ $position = 0; if ($previous_result !== null) { $part_results = array_values($previous_result->getParts()); $index = count($this->parts) - 1; for ($i = 0; $i < count($this->parts); $i += 1) { $position += $part_results[$i]->getLength(); } $input->move($position); } else { $part_results = array_fill(0, count($this->parts), null); $index = 0; } for (; $index < count($this->parts);) { $part = $this->parts[$index]; if ($part_results[$index] !== null) { $input->move(-$part_results[$index]->getLength()); $position -= $part_results[$index]->getLength(); } $part_result = $part->parseInputStreamWithBacktracking($input, $part_results[$index]); if ($part_result === null) { if ($index === 0) { $input->move(-$position); return null; } $part_results[$index] = $part_result; $index -= 1; } else { $position += $part_result->getLength(); $part_results[$index] = $part_result; $index += 1; } } $corrected_part_results = array_combine($this->key_to_index, $part_results); return new ConcatenatedExpressionResult($corrected_part_results); }
public function parseInputStreamWithBacktracking(InputStreamInterface $input, ExpressionResultInterface $previous_result = null) { if ($previous_result !== null) { return null; } $constant = $this->string; if ($input->matchesString($constant) === false) { return null; } $input->move(strlen($constant)); return $this->result; }