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));
 }
示例#3
0
 public function parseInputStreamWithBacktracking(InputStreamInterface $input, ExpressionResultInterface $previous_result = null)
 {
     if ($previous_result !== null) {
         return null;
     }
     if ($input->isAtEnd() === false) {
         return null;
     }
     return new ConstantExpressionResult("");
 }
示例#4
0
 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;
 }
示例#5
0
 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;
 }
 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;
 }
 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);
 }