Beispiel #1
0
 /**
  * Handles a repetition token
  * 
  * @param Token $token Token
  * 
  * @return void
  */
 protected function _handleRepetition(Token $token)
 {
     //If there is no current item, throw exception
     if ($this->_currentItem === null) {
         throw new Exception\InvalidRepetition("Nothing to repeat");
     }
     //Repetitions are allowed only after certain tokens, so check the last
     //emitted token
     $lastToken = $this->_tokensStack->top();
     switch ($lastToken->getType()) {
         //Handle lazy repetition
         case Token::TYPE_REPETITION:
             $prevLastToken = $this->_tokensStack->offsetGet(1);
             //if this token is "?" and follows a repetition token that
             //does not come after another repetition token set the lazy flag
             if ($token->getIdentifier() === "?" && $prevLastToken->getType() !== Token::TYPE_REPETITION) {
                 //Check if last repetition supports the lazy flag
                 $lastRepetition = $this->_currentItem->getRepetition();
                 if ($lastRepetition->supportsLazy()) {
                     $lastRepetition->setLazy(true);
                 }
                 return;
             } else {
                 throw new Exception\InvalidRepetition("Nothing to repeat");
             }
             break;
             //Tokens that can handle the repetition
         //Tokens that can handle the repetition
         case Token::TYPE_NON_PRINTING_CHAR:
         case Token::TYPE_GENERIC_CHAR_TYPE:
         case Token::TYPE_CONTROL_CHAR:
         case Token::TYPE_EXT_UNICODE_SEQUENCE:
         case Token::TYPE_UNICODE_CHAR_CLASS:
         case Token::TYPE_HEX_CHAR:
         case Token::TYPE_DOT:
         case Token::TYPE_BYTE:
         case Token::TYPE_SUBPATTERN_END:
         case Token::TYPE_COMMENT:
         case Token::TYPE_OCTAL_CHAR:
         case Token::TYPE_BACK_REFERENCE:
         case Token::TYPE_CHAR_CLASS_END:
         case Token::TYPE_RECURSIVE_PATTERN:
             break;
             //When simple characters are grouped, repetition is valid only
             //for the last one, so it needs to be splitted so that the last
             //character belongs to a different object
         //When simple characters are grouped, repetition is valid only
         //for the last one, so it needs to be splitted so that the last
         //character belongs to a different object
         case Token::TYPE_CHAR:
             $chars = $this->_currentItem->getChar();
             if (strlen($chars) > 1) {
                 $this->_currentItem->setChar(substr($chars, 0, -1));
                 $this->_currentItem = new Pattern\Char($chars[strlen($chars) - 1]);
                 $this->_containersStack->top()->addChild($this->_currentItem);
             }
             break;
         default:
             throw new Exception\InvalidRepetition("Repetition cannot be inserted at this point");
             break;
     }
     //Get the right repetition class
     switch ($token->getIdentifier()) {
         case "*":
             $repetition = new Pattern\Repetition\ZeroOrMore();
             break;
         case "+":
             $repetition = new Pattern\Repetition\OneOrMore();
             break;
         case "?":
             $repetition = new Pattern\Repetition\Optional();
             break;
         case "{":
             //Check if {}
             if (strpos($token->getSubject(), ",") === false) {
                 $repetition = new Pattern\Repetition\Number($token->getSubject());
             } else {
                 $limits = explode(",", $token->getSubject());
                 $repetition = new Pattern\Repetition\Range($limits[0], $limits[1] === "" ? null : $limits[1]);
             }
             break;
     }
     //Set the repetition on the current item
     $this->_currentItem->setRepetition($repetition);
 }