/** * Creates WHERE/SORT/LIMIT parser. * * @return \Xiag\Rql\Parser\Parser * @author Andreas Glaser * @author Dominic Tubach <*****@*****.**> * @todo : Rename */ public static function createFiltersOnly() { $scalarParser = new Xiag\ValueParser\ScalarParser(); $scalarParser->registerTypeCaster('string', new Xiag\TypeCaster\StringTypeCaster())->registerTypeCaster('integer', new Xiag\TypeCaster\IntegerTypeCaster())->registerTypeCaster('float', new Xiag\TypeCaster\FloatTypeCaster())->registerTypeCaster('boolean', new Xiag\TypeCaster\BooleanTypeCaster()); $arrayParser = new Xiag\ValueParser\ArrayParser($scalarParser); $globParser = new Xiag\ValueParser\GlobParser(); $fieldParser = new Xiag\ValueParser\FieldParser(); $integerParser = new Xiag\ValueParser\IntegerParser(); $queryNodeParser = new Xiag\NodeParser\QueryNodeParser(); $queryNodeParser->addNodeParser(new Xiag\NodeParser\Query\GroupNodeParser($queryNodeParser))->addNodeParser(new XiagLogicalOperator\AndNodeParser($queryNodeParser))->addNodeParser(new XiagLogicalOperator\OrNodeParser($queryNodeParser))->addNodeParser(new XiagLogicalOperator\NotNodeParser($queryNodeParser))->addNodeParser(new XiagComparisonOperator\Rql\InNodeParser($fieldParser, $arrayParser))->addNodeParser(new XiagComparisonOperator\Rql\OutNodeParser($fieldParser, $arrayParser))->addNodeParser(new XiagComparisonOperator\Rql\EqNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Rql\NeNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Rql\LtNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Rql\GtNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Rql\LeNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Rql\GeNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Rql\LikeNodeParser($fieldParser, $globParser))->addNodeParser(new XiagComparisonOperator\Fiql\InNodeParser($fieldParser, $arrayParser))->addNodeParser(new XiagComparisonOperator\Fiql\OutNodeParser($fieldParser, $arrayParser))->addNodeParser(new XiagComparisonOperator\Fiql\EqNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Fiql\NeNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Fiql\LtNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Fiql\GtNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Fiql\LeNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Fiql\GeNodeParser($fieldParser, $scalarParser))->addNodeParser(new XiagComparisonOperator\Fiql\LikeNodeParser($fieldParser, $globParser)); // custom additions $queryNodeParser->addNodeParser(new ExtensionComparisonOperator\Rql\IsNullNodeParser($fieldParser))->addNodeParser(new ExtensionComparisonOperator\Rql\IsNotNullNodeParser($fieldParser)); $parserChain = new Xiag\NodeParserChain(); $parserChain->addNodeParser($queryNodeParser)->addNodeParser(new Xiag\NodeParser\SortNodeParser($fieldParser))->addNodeParser(new Xiag\NodeParser\LimitNodeParser($integerParser)); return new Xiag\Parser($parserChain); }
{ return $tokenStream->test(Token::T_OPERATOR, 'elemMatch'); } public function parse(TokenStream $tokenStream) { $tokenStream->expect(Token::T_OPERATOR, 'elemMatch'); $tokenStream->expect(Token::T_OPEN_PARENTHESIS); $field = $tokenStream->expect(Token::T_STRING)->getValue(); $tokenStream->expect(Token::T_COMMA); $query = $this->queryParser->parse($tokenStream); if (!$query instanceof AbstractQueryNode) { throw new SyntaxErrorException(sprintf('"elemMatch" operator expects parameter "query" to be instance of "%s", "%s" given', AbstractQueryNode::class, get_class($query))); } $tokenStream->expect(Token::T_CLOSE_PARENTHESIS); return new ElemMatchNode($field, $query); } } // create node parser $scalarParser = (new ValueParser\ScalarParser())->registerTypeCaster('string', new TypeCaster\StringTypeCaster())->registerTypeCaster('integer', new TypeCaster\IntegerTypeCaster())->registerTypeCaster('float', new TypeCaster\FloatTypeCaster())->registerTypeCaster('boolean', new TypeCaster\BooleanTypeCaster()); $arrayParser = new ValueParser\ArrayParser($scalarParser); $globParser = new ValueParser\GlobParser(); $fieldParser = new ValueParser\FieldParser(); $integerParser = new ValueParser\IntegerParser(); $queryNodeParser = new NodeParser\QueryNodeParser(); $queryNodeParser->addNodeParser(new NodeParser\Query\GroupNodeParser($queryNodeParser))->addNodeParser(new NodeParser\Query\LogicalOperator\AndNodeParser($queryNodeParser))->addNodeParser(new NodeParser\Query\LogicalOperator\OrNodeParser($queryNodeParser))->addNodeParser(new NodeParser\Query\LogicalOperator\NotNodeParser($queryNodeParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\InNodeParser($fieldParser, $arrayParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\OutNodeParser($fieldParser, $arrayParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\EqNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\NeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\LtNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\GtNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\LeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\GeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\LikeNodeParser($fieldParser, $globParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\InNodeParser($fieldParser, $arrayParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\OutNodeParser($fieldParser, $arrayParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\EqNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\NeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\LtNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\GtNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\LeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\GeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\LikeNodeParser($fieldParser, $globParser))->addNodeParser(new BetweenTokenParser($scalarParser))->addNodeParser(new ElemMatchNodeParser($queryNodeParser)); $nodeParser = (new NodeParserChain())->addNodeParser($queryNodeParser)->addNodeParser(new NodeParser\SelectNodeParser($fieldParser))->addNodeParser(new NodeParser\SortNodeParser($fieldParser))->addNodeParser(new NodeParser\LimitNodeParser($integerParser)); // parse $lexer = new Lexer(); $parser = new Parser($nodeParser); $tokenStream = $lexer->tokenize('between(x,1,2)&elemMatch(array,(between(x,3,4)&a=b&(c!=d|e!=f)¬(le(g,h))))'); var_dump($parser->parse($tokenStream));
<?php namespace Xiag\Rql\ParserExample01; use Xiag\Rql\Parser\Lexer; use Xiag\Rql\Parser\Parser; use Xiag\Rql\Parser\NodeParserChain; use Xiag\Rql\Parser\ValueParser; use Xiag\Rql\Parser\TypeCaster; use Xiag\Rql\Parser\NodeParser; require __DIR__ . '/../vendor/autoload.php'; $scalarParser = (new ValueParser\ScalarParser())->registerTypeCaster('string', new TypeCaster\StringTypeCaster())->registerTypeCaster('integer', new TypeCaster\IntegerTypeCaster())->registerTypeCaster('float', new TypeCaster\FloatTypeCaster())->registerTypeCaster('boolean', new TypeCaster\BooleanTypeCaster()); $arrayParser = new ValueParser\ArrayParser($scalarParser); $globParser = new ValueParser\GlobParser(); $fieldParser = new ValueParser\FieldParser(); $integerParser = new ValueParser\IntegerParser(); $queryNodeParser = new NodeParser\QueryNodeParser(); $queryNodeParser->addNodeParser(new NodeParser\Query\GroupNodeParser($queryNodeParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\InNodeParser($fieldParser, $arrayParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\OutNodeParser($fieldParser, $arrayParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\EqNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\NeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\LtNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\GtNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\LeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\GeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\LikeNodeParser($fieldParser, $globParser)); $nodeParser = (new NodeParserChain())->addNodeParser($queryNodeParser)->addNodeParser(new NodeParser\SelectNodeParser($fieldParser))->addNodeParser(new NodeParser\SortNodeParser($fieldParser))->addNodeParser(new NodeParser\LimitNodeParser($integerParser)); $lexer = new Lexer(); $parser = new Parser($nodeParser); // ok $tokenStream = $lexer->tokenize('((a==true()|b!=str)&c>=10&d=in=(1,value,null()))'); var_dump($parser->parse($tokenStream)); // error $tokenStream = $lexer->tokenize('or(eq(a,true),ne(b,str))>e(c,10)&in(d,(1,value,null()))'); var_dump($parser->parse($tokenStream));
if ($tokenStream->nextIf(Token::T_FALSE)) { return false; } elseif ($tokenStream->nextIf(Token::T_TRUE)) { return true; } elseif ($tokenStream->nextIf(Token::T_NULL)) { return null; } elseif ($tokenStream->nextIf(Token::T_DATE)) { return new \DateTime($token->getValue()); } elseif ($tokenStream->nextIf(Token::T_STRING)) { return $token->getValue(); } elseif ($tokenStream->nextIf(Token::T_INTEGER)) { return (int) $token->getValue(); } elseif ($tokenStream->nextIf(Token::T_FLOAT)) { return (double) $token->getValue(); } throw new SyntaxErrorException(sprintf('Invalid scalar token "%s" (%s)', $token->getValue(), $token->getName())); } } $subLexer = (new SubLexerChain())->addSubLexer(new SubLexer\PunctuationSubLexer())->addSubLexer(new SubLexer\FiqlOperatorSubLexer())->addSubLexer(new SubLexer\RqlOperatorSubLexer())->addSubLexer(new ConstantSubLexer())->addSubLexer(new StringSubLexer())->addSubLexer(new IdentifierSubLexer())->addSubLexer(new SubLexer\DatetimeSubLexer())->addSubLexer(new SubLexer\NumberSubLexer())->addSubLexer(new SubLexer\SortSubLexer()); $identifierParser = new IdentifierParser(); $scalarParser = new ScalarParser(); $arrayParser = new ValueParser\ArrayParser($scalarParser); $integerParser = new ValueParser\IntegerParser(); $queryNodeParser = new NodeParser\QueryNodeParser(); $queryNodeParser->addNodeParser(new NodeParser\Query\GroupNodeParser($queryNodeParser))->addNodeParser(new LogicalOperator\AndNodeParser($queryNodeParser))->addNodeParser(new LogicalOperator\OrNodeParser($queryNodeParser))->addNodeParser(new LogicalOperator\NotNodeParser($queryNodeParser))->addNodeParser(new ComparisonOperator\Rql\InNodeParser($identifierParser, $arrayParser))->addNodeParser(new ComparisonOperator\Rql\OutNodeParser($identifierParser, $arrayParser))->addNodeParser(new ComparisonOperator\Rql\EqNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Rql\NeNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Rql\LtNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Rql\GtNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Rql\LeNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Rql\GeNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Rql\LikeNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Fiql\InNodeParser($identifierParser, $arrayParser))->addNodeParser(new ComparisonOperator\Fiql\OutNodeParser($identifierParser, $arrayParser))->addNodeParser(new ComparisonOperator\Fiql\EqNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Fiql\NeNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Fiql\LtNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Fiql\GtNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Fiql\LeNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Fiql\GeNodeParser($identifierParser, $scalarParser))->addNodeParser(new ComparisonOperator\Fiql\LikeNodeParser($identifierParser, $scalarParser)); $nodeParser = (new NodeParserChain())->addNodeParser($queryNodeParser)->addNodeParser(new NodeParser\SelectNodeParser($identifierParser))->addNodeParser(new NodeParser\SortNodeParser($identifierParser))->addNodeParser(new NodeParser\LimitNodeParser($integerParser)); // parse $lexer = new Lexer($subLexer); $parser = new Parser($nodeParser); $tokenStream = $lexer->tokenize(implode('&', ['select(a.b,c.d)', 'ne(a.b,"quoted string !@#$%^&*()_+[]{} ;:\'\\"\\| ,<.>/? ~ + escaped \\" double quote")', '(not(c.d="d")|e=false)', 'out(f,(1,"2",null,2016-06-29T23:30:33Z,true))', 'sort(-a.b,+c.d)', 'limit(1,2)'])); var_dump($parser->parse($tokenStream));