/** * SimpleConditionalExpression ::= * ComparisonExpression | BetweenExpression | LikeExpression | * InExpression | NullComparisonExpression | ExistsExpression | * EmptyCollectionComparisonExpression | CollectionMemberExpression */ public function SimpleConditionalExpression() { if ($this->_lexer->isNextToken(Lexer::T_NOT)) { $token = $this->_lexer->glimpse(); } else { $token = $this->_lexer->lookahead; } if ($token['type'] === Lexer::T_EXISTS) { return $this->ExistsExpression(); } $pathExprOrInputParam = false; if ($token['type'] === Lexer::T_IDENTIFIER || $token['type'] === Lexer::T_INPUT_PARAMETER) { // Peek beyond the PathExpression $pathExprOrInputParam = true; $peek = $this->_lexer->peek(); while ($peek['value'] === '.') { $this->_lexer->peek(); $peek = $this->_lexer->peek(); } // Also peek beyond a NOT if there is one if ($peek['type'] === Lexer::T_NOT) { $peek = $this->_lexer->peek(); } $token = $peek; // We need to go even further in case of IS (differenciate between NULL and EMPTY) $lookahead = $this->_lexer->peek(); // Also peek beyond a NOT if there is one if ($lookahead['type'] === Lexer::T_NOT) { $lookahead = $this->_lexer->peek(); } $this->_lexer->resetPeek(); } if ($pathExprOrInputParam) { switch ($token['type']) { case Lexer::T_EQUALS: case Lexer::T_LOWER_THAN: case Lexer::T_GREATER_THAN: case Lexer::T_NEGATE: case Lexer::T_OPEN_PARENTHESIS: return $this->ComparisonExpression(); case Lexer::T_BETWEEN: return $this->BetweenExpression(); case Lexer::T_LIKE: return $this->LikeExpression(); case Lexer::T_IN: return $this->InExpression(); case Lexer::T_IS: if ($lookahead['type'] == Lexer::T_NULL) { return $this->NullComparisonExpression(); } return $this->EmptyCollectionComparisonExpression(); case Lexer::T_MEMBER: return $this->CollectionMemberExpression(); default: $this->syntaxError(); } } return $this->ComparisonExpression(); }
/** * SimpleConditionalExpression ::= * ComparisonExpression | BetweenExpression | LikeExpression | * InExpression | NullComparisonExpression | ExistsExpression | * EmptyCollectionComparisonExpression | CollectionMemberExpression | * InstanceOfExpression */ public function SimpleConditionalExpression() { if ($this->_lexer->isNextToken(Lexer::T_NOT)) { $token = $this->_lexer->glimpse(); } else { $token = $this->_lexer->lookahead; } if ($token['type'] === Lexer::T_EXISTS) { return $this->ExistsExpression(); } $peek = $this->_lexer->glimpse(); if ($token['type'] === Lexer::T_IDENTIFIER || $token['type'] === Lexer::T_INPUT_PARAMETER) { if ($peek['value'] == '(') { // Peek beyond the matching closing paranthesis ')' $this->_lexer->peek(); $token = $this->_peekBeyondClosingParenthesis(); } else { // Peek beyond the PathExpression (or InputParameter) $peek = $this->_lexer->peek(); while ($peek['value'] === '.') { $this->_lexer->peek(); $peek = $this->_lexer->peek(); } // Also peek beyond a NOT if there is one if ($peek['type'] === Lexer::T_NOT) { $peek = $this->_lexer->peek(); } $token = $peek; // We need to go even further in case of IS (differenciate between NULL and EMPTY) $lookahead = $this->_lexer->peek(); // Also peek beyond a NOT if there is one if ($lookahead['type'] === Lexer::T_NOT) { $lookahead = $this->_lexer->peek(); } $this->_lexer->resetPeek(); } } switch ($token['type']) { case Lexer::T_BETWEEN: return $this->BetweenExpression(); case Lexer::T_LIKE: return $this->LikeExpression(); case Lexer::T_IN: return $this->InExpression(); case Lexer::T_INSTANCE: return $this->InstanceOfExpression(); case Lexer::T_IS: if ($lookahead['type'] == Lexer::T_NULL) { return $this->NullComparisonExpression(); } return $this->EmptyCollectionComparisonExpression(); case Lexer::T_MEMBER: return $this->CollectionMemberExpression(); default: return $this->ComparisonExpression(); } }
/** * Peeks beyond the specified token and returns the first token after that one. */ private function _peekBeyond($token) { $peek = $this->_lexer->peek(); while ($peek['value'] != $token) { $peek = $this->_lexer->peek(); } $peek = $this->_lexer->peek(); $this->_lexer->resetPeek(); return $peek; }
private function _peekBeyondClosingParenthesis() { $numUnmatched = 1; $token = $this->_lexer->peek(); while ($numUnmatched > 0 && $token !== null) { if ($token['value'] == ')') { --$numUnmatched; } else { if ($token['value'] == '(') { ++$numUnmatched; } } $token = $this->_lexer->peek(); } $this->_lexer->resetPeek(); return $token; }