Ejemplo n.º 1
0
 /**
  * The bounded-exhaustive algorithm.
  *
  * @param   \Hoa\Compiler\Llk\Rule  $rule    Rule to cover.
  * @param   int                     $next    Next rule.
  * @return  bool
  */
 protected function boundedExhaustive(Compiler\Llk\Rule $rule, $next)
 {
     $content = $rule->getContent();
     if ($rule instanceof Compiler\Llk\Rule\Repetition) {
         if (0 === $next) {
             $this->_trace[] = new Compiler\Llk\Rule\Entry($rule->getName(), $rule->getMin());
             array_pop($this->_todo);
             $this->_todo[] = new Compiler\Llk\Rule\Ekzit($rule->getName(), $rule->getMin(), $this->_todo);
             for ($i = 0, $min = $rule->getMin(); $i < $min; ++$i) {
                 $this->_todo[] = new Compiler\Llk\Rule\Ekzit($content, 0);
                 $this->_todo[] = new Compiler\Llk\Rule\Entry($content, 0);
             }
         } else {
             $nbToken = 0;
             foreach ($this->_trace as $trace) {
                 if ($trace instanceof Compiler\Llk\Rule\Token) {
                     ++$nbToken;
                 }
             }
             $max = $rule->getMax();
             if (-1 != $max && $next > $max) {
                 return false;
             }
             $this->_todo[] = new Compiler\Llk\Rule\Ekzit($rule->getName(), $next, $this->_todo);
             $this->_todo[] = new Compiler\Llk\Rule\Ekzit($content, 0);
             $this->_todo[] = new Compiler\Llk\Rule\Entry($content, 0);
         }
         return true;
     } elseif ($rule instanceof Compiler\Llk\Rule\Choice) {
         if (count($content) <= $next) {
             return false;
         }
         $this->_trace[] = new Compiler\Llk\Rule\Entry($rule->getName(), $next, $this->_todo);
         $nextRule = $content[$next];
         $this->_todo[] = new Compiler\Llk\Rule\Ekzit($nextRule, 0);
         $this->_todo[] = new Compiler\Llk\Rule\Entry($nextRule, 0);
         return true;
     } elseif ($rule instanceof Compiler\Llk\Rule\Concatenation) {
         $this->_trace[] = new Compiler\Llk\Rule\Entry($rule->getName(), $next);
         for ($i = count($content) - 1; $i >= 0; --$i) {
             $nextRule = $content[$i];
             $this->_todo[] = new Compiler\Llk\Rule\Ekzit($nextRule, 0);
             $this->_todo[] = new Compiler\Llk\Rule\Entry($nextRule, 0);
         }
         return true;
     } elseif ($rule instanceof Compiler\Llk\Rule\Token) {
         $nbToken = 0;
         foreach ($this->_trace as $trace) {
             if ($trace instanceof Compiler\Llk\Rule\Token) {
                 ++$nbToken;
             }
         }
         if ($nbToken >= $this->getLength()) {
             return false;
         }
         $this->_trace[] = $rule;
         array_pop($this->_todo);
         return true;
     }
     return false;
 }