/**
  * @param array $tokens
  * @return array
  */
 public function compile(array $tokens)
 {
     $stack = new StackLevel(new LogicalOperator('$and'));
     foreach ($tokens as $token) {
         switch ($token[0]) {
             case Parser::TOK_WHITESPACE:
                 break;
             case Parser::TOK_EXPRESSION_SPLIT:
                 $stack->endExpression();
                 break;
             case Parser::TOK_INT_LITERAL:
                 $stack->add(new Literal((int) $this->retrieveCapture($token)));
                 break;
             case Parser::TOK_FLOAT_LITERAL:
                 $stack->add(new Literal((double) $this->retrieveCapture($token)));
                 break;
             case Parser::TOK_LITERAL:
             case Parser::TOK_STRING_LITERAL:
                 $stack->add(new Literal($this->retrieveCapture($token)));
                 break;
             case Parser::TOK_RBRACKET:
                 if (!($stack = $stack->endExpression()->getParent())) {
                     throw new UnexpectedClosingParenthesisException();
                 }
                 break;
             default:
                 if ($token[0] instanceof Operator) {
                     $stack->add($token[0]);
                 } elseif ($token[0] instanceof LogicalOperator) {
                     $stack = $stack->endExpression()->newLevel($token[0]);
                 } else {
                     throw new QueryParserException("Unexpected token of type: " . gettype($token[0]));
                 }
         }
     }
     $stack->endExpression();
     if (!$stack->isTopLevel()) {
         throw new UnbalancedParenthesisException($stack->getLevel());
     }
     $item = $this->groupOperators($stack);
     return $item;
 }