public function testWhiteSpace() { $expression = " IntIdentifier eq 123 "; $lexer = new ExpressionLexer($expression); $token = $lexer->getCurrentToken(); $this->AssertEquals($token->Id, ExpressionTokenId::IDENTIFIER); $this->AssertEquals($token->Text, 'IntIdentifier'); $this->AssertEquals($token->Position, 5); $lexer->nextToken(); $token = $lexer->getCurrentToken(); $this->AssertEquals($token->Id, ExpressionTokenId::IDENTIFIER); $this->AssertEquals($token->Text, 'eq'); $this->AssertEquals($token->Position, 23); $lexer->nextToken(); $token = $lexer->getCurrentToken(); $this->AssertEquals($token->Id, ExpressionTokenId::INTEGER_LITERAL); $this->AssertEquals($token->Text, '123'); $this->AssertEquals($token->Position, 30); $lexer->nextToken(); $token = $lexer->getCurrentToken(); $this->AssertEquals($token->Id, ExpressionTokenId::END); $this->AssertEquals($token->Position, 37); }
/** * Parse null literal. * * @return ConstantExpression */ private function _parseNullLiteral() { $this->_lexer->nextToken(); return new ConstantExpression(null, new Null1()); }
/** * Read orderby clause. * * @param string $value orderby clause to read. * * @return array(array) An array of 'OrderByPathSegment's, each of which * is array of 'OrderBySubPathSegment's * * @throws ODataException If any syntax error found while reading the clause */ private function _readOrderBy($value) { $orderByPathSegments = array(); $lexer = new ExpressionLexer($value); $i = 0; while ($lexer->getCurrentToken()->Id != ExpressionTokenId::END) { $orderBySubPathSegment = $lexer->readDottedIdentifier(); if (!array_key_exists($i, $orderByPathSegments)) { $orderByPathSegments[$i] = array(); } $orderByPathSegments[$i][] = $orderBySubPathSegment; $tokenId = $lexer->getCurrentToken()->Id; if ($tokenId != ExpressionTokenId::END) { if ($tokenId != ExpressionTokenId::SLASH) { if ($tokenId != ExpressionTokenId::COMMA) { $lexer->validateToken(ExpressionTokenId::IDENTIFIER); $identifier = $lexer->getCurrentToken()->Text; if ($identifier !== 'asc' && $identifier !== 'desc') { // force lexer to throw syntax error as we found // unexpected identifier $lexer->validateToken(ExpressionTokenId::DOT); } $orderByPathSegments[$i][] = '*' . $identifier; $lexer->nextToken(); $tokenId = $lexer->getCurrentToken()->Id; if ($tokenId != ExpressionTokenId::END) { $lexer->validateToken(ExpressionTokenId::COMMA); $i++; } } else { $i++; } } $lexer->nextToken(); } } return $orderByPathSegments; }
/** * Read expand or select clause. * * @param string $value expand or select clause to read. * @param boolean $isSelect true means $value is value of select clause * else value of expand clause. * * @return array(array) An array of 'PathSegment's, each of which is array * of 'SubPathSegment's */ private function _readExpandOrSelect($value, $isSelect) { $pathSegments = array(); $lexer = new ExpressionLexer($value); $i = 0; while ($lexer->getCurrentToken()->Id != ExpressionTokenId::END) { $lastSegment = false; if ($isSelect && $lexer->getCurrentToken()->Id == ExpressionTokenId::STAR) { $lastSegment = true; $subPathSegment = $lexer->getCurrentToken()->Text; $lexer->nextToken(); } else { $subPathSegment = $lexer->readDottedIdentifier(); } if (!array_key_exists($i, $pathSegments)) { $pathSegments[$i] = array(); } $pathSegments[$i][] = $subPathSegment; $tokenId = $lexer->getCurrentToken()->Id; if ($tokenId != ExpressionTokenId::END) { if ($lastSegment || $tokenId != ExpressionTokenId::SLASH) { $lexer->validateToken(ExpressionTokenId::COMMA); $i++; } $lexer->nextToken(); } } return $pathSegments; }
/** * Attempts to parse value(s) of resource key(s) from the key predicate and * creates instance of KeyDescription representing the same, Once parsing is * done one should call validate function to validate the created * KeyDescription * * @param string $keyPredicate The key predicate to parse * @param boolean $allowNamedValues Set to true if paser should accept * named values(Property = KeyValue), * if false then parser will fail on * such constructs * @param boolean $allowNull Set to true if parser should accept * null values for positional key * values, if false then parser will * fail on seeing null values * @param KeyDescriptor &$keyDescriptor On return, Description of key after * parsing * * @return boolean True if the given values were parsed; false if there was a * syntactic error */ private static function _tryParseKeysFromKeyPredicate($keyPredicate, $allowNamedValues, $allowNull, &$keyDescriptor) { $expressionLexer = new ExpressionLexer($keyPredicate); $currentToken = $expressionLexer->getCurrentToken(); //Check for empty predicate e.g. Customers( ) if ($currentToken->Id == ExpressionTokenId::END) { $keyDescriptor = new KeyDescriptor(array(), array()); return true; } $namedValues = array(); $positionalValues = array(); do { if ($currentToken->Id == ExpressionTokenId::IDENTIFIER && $allowNamedValues) { //named and positional values are mutually exclusive if (!empty($positionalValues)) { return false; } //expecting keyName=keyValue, verify it $identifier = $currentToken->getIdentifier(); $expressionLexer->nextToken(); $currentToken = $expressionLexer->getCurrentToken(); if ($currentToken->Id != ExpressionTokenId::EQUAL) { return false; } $expressionLexer->nextToken(); $currentToken = $expressionLexer->getCurrentToken(); $value = null; if (!$currentToken->isKeyValueToken()) { return false; } if (array_key_exists($identifier, $namedValues)) { //Duplication of KeyName not allowed return false; } //Get type of keyValue and validate keyValue $ouValue = $outType = null; if (!self::_getTypeAndValidateKeyValue($currentToken->Text, $currentToken->Id, $outValue, $outType)) { return false; } $namedValues[$identifier] = array($outValue, $outType); } else { if ($currentToken->isKeyValueToken() || $currentToken->Id == ExpressionTokenId::NULL_LITERAL && $allowNull) { //named and positional values are mutually exclusive if (!empty($namedValues)) { return false; } //Get type of keyValue and validate keyValue $ouValue = $outType = null; if (!self::_getTypeAndValidateKeyValue($currentToken->Text, $currentToken->Id, $outValue, $outType)) { return false; } $positionalValues[] = array($outValue, $outType); } else { return false; } } $expressionLexer->nextToken(); $currentToken = $expressionLexer->getCurrentToken(); if ($currentToken->Id == ExpressionTokenId::COMMA) { $expressionLexer->nextToken(); $currentToken = $expressionLexer->getCurrentToken(); //end of text and comma, Trailing comma not allowed if ($currentToken->Id == ExpressionTokenId::END) { return false; } } } while ($currentToken->Id != ExpressionTokenId::END); $keyDescriptor = new KeyDescriptor($namedValues, $positionalValues); return true; }