예제 #1
0
 /**
  * Skips whitespace in the specified text by advancing an index to
  * the next non-whitespace character.
  * 
  * @param string $text       Text to scan.
  * @param int    &$textIndex Index to begin scanning from.
  * 
  * @return boolean true if the end of the string was reached, false otherwise.
  */
 public static function skipWhiteSpace($text, &$textIndex)
 {
     $textLen = strlen($text);
     while ($textIndex < $textLen && Char::isWhiteSpace($text[$textIndex])) {
         $textIndex++;
     }
     return $textLen == $textIndex;
 }
예제 #2
0
 /** 
  * Reads the next token, skipping whitespace as necessary.
  * 
  * @return void
  */
 public function nextToken()
 {
     while (Char::isWhiteSpace($this->_ch)) {
         $this->_nextChar();
     }
     $t;
     $tokenPos = $this->_textPos;
     switch ($this->_ch) {
         case '(':
             $this->_nextChar();
             $t = ExpressionTokenId::OPENPARAM;
             break;
         case ')':
             $this->_nextChar();
             $t = ExpressionTokenId::CLOSEPARAM;
             break;
         case ',':
             $this->_nextChar();
             $t = ExpressionTokenId::COMMA;
             break;
         case '-':
             $hasNext = $this->_textPos + 1 < $this->_textLen;
             if ($hasNext && Char::isDigit($this->_text[$this->_textPos + 1])) {
                 $this->_nextChar();
                 $t = $this->_parseFromDigit();
                 if (self::isNumeric($t)) {
                     break;
                 }
                 $this->_setTextPos($tokenPos);
             } else {
                 if ($hasNext && $this->_text[$tokenPos + 1] == 'I') {
                     $this->_nextChar();
                     $this->_parseIdentifier();
                     $currentIdentifier = substr($this->_text, $tokenPos + 1, $this->_textPos - $tokenPos - 1);
                     if (self::_isInfinityLiteralDouble($currentIdentifier)) {
                         $t = ExpressionTokenId::DOUBLE_LITERAL;
                         break;
                     } else {
                         if (self::_isInfinityLiteralSingle($currentIdentifier)) {
                             $t = ExpressionTokenId::SINGLE_LITERAL;
                             break;
                         }
                     }
                     // If it looked like '-INF' but wasn't we'll rewind and fall
                     // through to a simple '-' token.
                     $this->_setTextPos($tokenPos);
                 }
             }
             $this->_nextChar();
             $t = ExpressionTokenId::MINUS;
             break;
         case '=':
             $this->_nextChar();
             $t = ExpressionTokenId::EQUAL;
             break;
         case '/':
             $this->_nextChar();
             $t = ExpressionTokenId::SLASH;
             break;
         case '?':
             $this->_nextChar();
             $t = ExpressionTokenId::QUESTION;
             break;
         case '.':
             $this->_nextChar();
             $t = ExpressionTokenId::DOT;
             break;
         case '\'':
             $quote = $this->_ch;
             do {
                 $this->_nextChar();
                 while ($this->_textPos < $this->_textLen && $this->_ch != $quote) {
                     $this->_nextChar();
                 }
                 if ($this->_textPos == $this->_textLen) {
                     throw $this->_parseError(Messages::expressionLexerUnterminatedStringLiteral($this->_textPos, $this->_text));
                 }
                 $this->_nextChar();
             } while ($this->_ch == $quote);
             $t = ExpressionTokenId::STRING_LITERAL;
             break;
         case '*':
             $this->_nextChar();
             $t = ExpressionTokenId::STAR;
             break;
         default:
             if (Char::isLetter($this->_ch) || $this->_ch == '_') {
                 $this->_parseIdentifier();
                 $t = ExpressionTokenId::IDENTIFIER;
                 break;
             }
             if (Char::isDigit($this->_ch)) {
                 $t = $this->_parseFromDigit();
                 break;
             }
             if ($this->_textPos == $this->_textLen) {
                 $t = ExpressionTokenId::END;
                 break;
             }
             throw $this->_parseError(Messages::expressionLexerInvalidCharacter($this->_ch, $this->_textPos));
     }
     $this->_token->Id = $t;
     $this->_token->Text = substr($this->_text, $tokenPos, $this->_textPos - $tokenPos);
     $this->_token->Position = $tokenPos;
     // Handle type-prefixed literals such as binary, datetime or guid.
     $this->_handleTypePrefixedLiterals();
     // Handle keywords.
     if ($this->_token->Id == ExpressionTokenId::IDENTIFIER) {
         if (self::_isInfinityOrNaNDouble($this->_token->Text)) {
             $this->_token->Id = ExpressionTokenId::DOUBLE_LITERAL;
         } else {
             if (self::_isInfinityOrNanSingle($this->_token->Text)) {
                 $this->_token->Id = ExpressionTokenId::SINGLE_LITERAL;
             } else {
                 if ($this->_token->Text == ODataConstants::KEYWORD_TRUE || $this->_token->Text == ODataConstants::KEYWORD_FALSE) {
                     $this->_token->Id = ExpressionTokenId::BOOLEAN_LITERAL;
                 } else {
                     if ($this->_token->Text == ODataConstants::KEYWORD_NULL) {
                         $this->_token->Id = ExpressionTokenId::NULL_LITERAL;
                     }
                 }
             }
         }
     }
 }