diff --git a/src/Ast/Disjunction.php b/src/Ast/Disjunction.php index 97c1ede..7df649a 100644 --- a/src/Ast/Disjunction.php +++ b/src/Ast/Disjunction.php @@ -13,11 +13,11 @@ class Disjunction extends Filter { - /** @var Term[] */ + /** @var Filter[] */ private $terms = []; /** - * @param Term[] $terms + * @param Filter[] $terms */ public function __construct(array $terms = []) { @@ -27,15 +27,15 @@ public function __construct(array $terms = []) } /** - * @param Term $term + * @param Filter $term */ - public function add(Term $term) + public function add(Filter $term) { $this->terms[] = $term; } /** - * @return Term[] + * @return Filter[] */ public function getTerms() { diff --git a/src/Ast/Path.php b/src/Ast/Path.php index d897c00..a7471fa 100644 --- a/src/Ast/Path.php +++ b/src/Ast/Path.php @@ -64,4 +64,20 @@ public function dump() return array_merge($this->valuePath->dump(), $this->attributePath->dump()); } } + + /** + * @return AttributePath + */ + public function getAttributePath() + { + return $this->attributePath; + } + + /** + * @return ValuePath + */ + public function getValuePath() + { + return $this->valuePath; + } } diff --git a/src/Parser.php b/src/Parser.php index 992f8ba..d34cb13 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -127,13 +127,16 @@ private function disjunction() $terms = []; $terms[] = $this->conjunction(); - if ($this->lexer->isNextToken(Tokens::T_SP)) { + $isNextTokenOr = true; + while($this->lexer->isNextToken(Tokens::T_SP) && $isNextTokenOr) { $nextToken = $this->lexer->glimpse(); if ($this->isName('or', $nextToken)) { $this->match(Tokens::T_SP); $this->match(Tokens::T_NAME); $this->match(Tokens::T_SP); $terms[] = $this->conjunction(); + } else { + $isNextTokenOr = false; } } @@ -152,13 +155,16 @@ private function conjunction() $factors = []; $factors[] = $this->factor(); - if ($this->lexer->isNextToken(Tokens::T_SP)) { + $isNextTokenAnd = true; + while($this->lexer->isNextToken(Tokens::T_SP) && $isNextTokenAnd) { $nextToken = $this->lexer->glimpse(); if ($this->isName('and', $nextToken)) { $this->match(Tokens::T_SP); $this->match(Tokens::T_NAME); $this->match(Tokens::T_SP); $factors[] = $this->factor(); + } else { + $isNextTokenAnd = false; } } diff --git a/tests/ParserFilterModeTest.php b/tests/ParserFilterModeTest.php index c7bb873..ccdc31a 100644 --- a/tests/ParserFilterModeTest.php +++ b/tests/ParserFilterModeTest.php @@ -218,7 +218,25 @@ public function parser_provider_v2() ] ] ], - + [ + '((name eq "mike" or id eq "123") or name eq "alina") and username eq "john"', + [ + 'Conjunction' => [ + [ + 'Disjunction' => [ + [ + 'Disjunction' => [ + ['ComparisonExpression' => 'name eq mike'], + ['ComparisonExpression' => 'id eq 123'], + ] + ], + ['ComparisonExpression' => 'name eq alina'] + ] + ], + ['ComparisonExpression' => 'username eq john'] + ] + ] + ], [ 'username eq "john" and not (name sw "mike" or id ew "123")', [ @@ -235,6 +253,60 @@ public function parser_provider_v2() ] ] ], + [ + 'emails co "example.com" and emails.value co "example.org" and emails.value co "example.info"', + [ + 'Conjunction' => [ + ['ComparisonExpression' => 'emails co example.com'], + ['ComparisonExpression' => 'emails.value co example.org'], + ['ComparisonExpression' => 'emails.value co example.info'], + ] + ] + ], + [ + 'emails co "example.com" or emails.value co "example.org" or emails.value co "example.info"', + [ + 'Disjunction' => [ + ['ComparisonExpression' => 'emails co example.com'], + ['ComparisonExpression' => 'emails.value co example.org'], + ['ComparisonExpression' => 'emails.value co example.info'], + ] + ] + ], + [ + 'emails co "example.com" or emails.value co "example.org" or emails.value co "example.info" or (emails co "example.com" and emails.value co "example.org" and emails.value co "example.info")', + [ + 'Disjunction' => [ + ['ComparisonExpression' => 'emails co example.com'], + ['ComparisonExpression' => 'emails.value co example.org'], + ['ComparisonExpression' => 'emails.value co example.info'], + [ + 'Conjunction' => [ + ['ComparisonExpression' => 'emails co example.com'], + ['ComparisonExpression' => 'emails.value co example.org'], + ['ComparisonExpression' => 'emails.value co example.info'], + ] + ] + ] + ] + ], + [ + 'emails co "example.com" or emails.value co "example.org" or emails.value co "example.info" or emails co "example.com" and emails.value co "example.org" and emails.value co "example.info"', + [ + 'Disjunction' => [ + ['ComparisonExpression' => 'emails co example.com'], + ['ComparisonExpression' => 'emails.value co example.org'], + ['ComparisonExpression' => 'emails.value co example.info'], + [ + 'Conjunction' => [ + ['ComparisonExpression' => 'emails co example.com'], + ['ComparisonExpression' => 'emails.value co example.org'], + ['ComparisonExpression' => 'emails.value co example.info'], + ] + ] + ] + ] + ], ]; } @@ -245,6 +317,7 @@ public function test_parser_v2($filterString, array $expectedDump) { $parser = $this->getParser(); $node = $parser->parse($filterString); + $this->assertEquals($expectedDump, $node->dump(), sprintf("\n\n%s\n%s\n\n", $filterString, json_encode($node->dump(), JSON_PRETTY_PRINT))); }