This is the parser for a CSS-like selector language for Objects and Content Repository Nodes. You can think of it as "Sizzle for PHP" (hence the name).
Inheritance: extends Neos\Eel\AbstractParser
 /**
  * {@inheritdoc}
  *
  * @param FlowQuery $flowQuery the FlowQuery object
  * @param array $arguments the arguments for this operation
  * @return void
  */
 public function evaluate(FlowQuery $flowQuery, array $arguments)
 {
     $output = array();
     $outputNodePaths = array();
     if (isset($arguments[0]) && !empty($arguments[0])) {
         $parsedFilter = FizzleParser::parseFilterGroup($arguments[0]);
         if ($this->earlyOptimizationOfFilters($flowQuery, $parsedFilter)) {
             return;
         }
     }
     /** @var NodeInterface $contextNode */
     foreach ($flowQuery->getContext() as $contextNode) {
         /** @var NodeInterface $childNode */
         foreach ($contextNode->getChildNodes() as $childNode) {
             if (!isset($outputNodePaths[$childNode->getPath()])) {
                 $output[] = $childNode;
                 $outputNodePaths[$childNode->getPath()] = true;
             }
         }
     }
     $flowQuery->setContext($output);
     if (isset($arguments[0]) && !empty($arguments[0])) {
         $flowQuery->pushOperation('filter', $arguments);
     }
 }
 /**
  * {@inheritdoc}
  *
  * @param FlowQuery $flowQuery the FlowQuery object
  * @param array $arguments the filter expression to use (in index 0)
  * @return void
  * @throws FizzleException
  */
 public function evaluate(FlowQuery $flowQuery, array $arguments)
 {
     if (count($flowQuery->getContext()) === 0) {
         return;
     }
     if (!isset($arguments[0]) || empty($arguments[0])) {
         if ($flowQuery->peekOperationName() === 'filter') {
             $filterOperation = $flowQuery->popOperation();
             if (count($filterOperation['arguments']) === 0 || empty($filterOperation['arguments'][0])) {
                 throw new FizzleException('Filter() needs arguments if it follows an empty children(): children().filter()', 1332489382);
             }
             $selectorAndFilter = $filterOperation['arguments'][0];
         } else {
             throw new FizzleException('children() needs at least a Property Name filter specified, or must be followed by filter().', 1332489399);
         }
     } else {
         $selectorAndFilter = $arguments[0];
     }
     $parsedFilter = FizzleParser::parseFilterGroup($selectorAndFilter);
     if (count($parsedFilter['Filters']) === 0) {
         throw new FizzleException('filter needs to be specified in children()', 1332489416);
     } elseif (count($parsedFilter['Filters']) === 1) {
         $filter = $parsedFilter['Filters'][0];
         if (isset($filter['PropertyNameFilter'])) {
             $this->evaluatePropertyNameFilter($flowQuery, $filter['PropertyNameFilter']);
             if (isset($filter['AttributeFilters'])) {
                 foreach ($filter['AttributeFilters'] as $attributeFilter) {
                     $flowQuery->pushOperation('filter', [$attributeFilter['text']]);
                 }
             }
         } elseif (isset($filter['AttributeFilters'])) {
             throw new FizzleException('children() must have a property name filter and cannot only have an attribute filter.', 1332489432);
         }
     } else {
         throw new FizzleException('children() only supports a single filter group right now, i.e. nothing of the form "filter1, filter2"', 1332489489);
     }
 }
 /**
  * {@inheritdoc}
  *
  * @param FlowQuery $flowQuery the FlowQuery object
  * @param array $arguments the filter expression to use (in index 0)
  * @return void
  * @throws FizzleException
  */
 public function evaluate(FlowQuery $flowQuery, array $arguments)
 {
     if (!isset($arguments[0]) || empty($arguments[0])) {
         return;
     }
     if (!is_string($arguments[0])) {
         throw new FizzleException('filter operation expects string argument', 1332489625);
     }
     $filter = $arguments[0];
     $parsedFilter = FizzleParser::parseFilterGroup($filter);
     $filteredContext = [];
     $context = $flowQuery->getContext();
     foreach ($context as $element) {
         if ($this->matchesFilterGroup($element, $parsedFilter)) {
             $filteredContext[] = $element;
         }
     }
     $flowQuery->setContext($filteredContext);
 }
 /**
  * {@inheritdoc}
  *
  * @param FlowQuery $flowQuery the FlowQuery object
  * @param array $arguments the arguments for this operation
  * @return void
  */
 public function evaluate(FlowQuery $flowQuery, array $arguments)
 {
     $context = $flowQuery->getContext();
     if (!isset($context[0]) || empty($arguments[0])) {
         return;
     }
     $result = array();
     $selectorAndFilter = $arguments[0];
     $parsedFilter = null;
     $parsedFilter = FizzleParser::parseFilterGroup($selectorAndFilter);
     if (isset($parsedFilter['Filters']) && $this->hasOnlyInstanceOfFilters($parsedFilter['Filters'])) {
         $nodeTypes = array();
         foreach ($parsedFilter['Filters'] as $filter) {
             $nodeTypes[] = $filter['AttributeFilters'][0]['Operand'];
         }
         /** @var NodeInterface $contextNode */
         foreach ($context as $contextNode) {
             $result = array_merge($result, $this->nodeDataRepository->findByParentAndNodeTypeInContext($contextNode->getPath(), implode(',', $nodeTypes), $contextNode->getContext(), true));
         }
     } else {
         foreach ($parsedFilter['Filters'] as $filter) {
             $filterResults = array();
             $generatedNodes = false;
             if (isset($filter['IdentifierFilter'])) {
                 if (!preg_match(UuidValidator::PATTERN_MATCH_UUID, $filter['IdentifierFilter'])) {
                     throw new FlowQueryException('find() requires a valid identifier', 1332492263);
                 }
                 /** @var NodeInterface $contextNode */
                 foreach ($context as $contextNode) {
                     $filterResults = array($contextNode->getContext()->getNodeByIdentifier($filter['IdentifierFilter']));
                 }
                 $generatedNodes = true;
             } elseif (isset($filter['PropertyNameFilter']) || isset($filter['PathFilter'])) {
                 $nodePath = isset($filter['PropertyNameFilter']) ? $filter['PropertyNameFilter'] : $filter['PathFilter'];
                 foreach ($context as $contextNode) {
                     $node = $contextNode->getNode($nodePath);
                     if ($node !== null) {
                         array_push($filterResults, $node);
                     }
                 }
                 $generatedNodes = true;
             }
             if (isset($filter['AttributeFilters']) && $filter['AttributeFilters'][0]['Operator'] === 'instanceof') {
                 foreach ($context as $contextNode) {
                     $filterResults = array_merge($filterResults, $this->nodeDataRepository->findByParentAndNodeTypeInContext($contextNode->getPath(), $filter['AttributeFilters'][0]['Operand'], $contextNode->getContext(), true));
                 }
                 unset($filter['AttributeFilters'][0]);
                 $generatedNodes = true;
             }
             if (isset($filter['AttributeFilters']) && count($filter['AttributeFilters']) > 0) {
                 if (!$generatedNodes) {
                     throw new FlowQueryException('find() needs an identifier, path or instanceof filter for the first filter part', 1436884196);
                 }
                 $filterQuery = new FlowQuery($filterResults);
                 foreach ($filter['AttributeFilters'] as $attributeFilter) {
                     $filterQuery->pushOperation('filter', array($attributeFilter['text']));
                 }
                 $filterResults = $filterQuery->get();
             }
             $result = array_merge($result, $filterResults);
         }
     }
     $flowQuery->setContext(array_unique($result));
 }