/**
  * Parses a query string
  *
  * @param string $strQuery
  * @param string $encoding
  * @throws \ZendSearch\Lucene\Search\Exception\QueryParserException
  * @throws \ZendSearch\Lucene\Exception\RuntimeException
  * @return \ZendSearch\Lucene\Search\Query\AbstractQuery
  */
 public static function parse($strQuery, $encoding = null)
 {
     self::_getInstance();
     // Reset FSM if previous parse operation didn't return it into a correct state
     self::$_instance->reset();
     try {
         self::$_instance->_encoding = $encoding !== null ? $encoding : self::$_instance->_defaultEncoding;
         self::$_instance->_lastToken = null;
         self::$_instance->_context = new QueryParserContext(self::$_instance->_encoding);
         self::$_instance->_contextStack = array();
         self::$_instance->_tokens = self::$_instance->_lexer->tokenize($strQuery, self::$_instance->_encoding);
         // Empty query
         if (count(self::$_instance->_tokens) == 0) {
             return new Query\Insignificant();
         }
         foreach (self::$_instance->_tokens as $token) {
             try {
                 self::$_instance->_currentToken = $token;
                 self::$_instance->process($token->type);
                 self::$_instance->_lastToken = $token;
             } catch (\Exception $e) {
                 if (strpos($e->getMessage(), 'There is no any rule for') !== false) {
                     throw new QueryParserException('Syntax error at char position ' . $token->position . '.', 0, $e);
                 }
                 throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
             }
         }
         if (count(self::$_instance->_contextStack) != 0) {
             throw new QueryParserException('Syntax Error: mismatched parentheses, every opening must have closing.');
         }
         return self::$_instance->_context->getQuery();
     } catch (QueryParserException $e) {
         if (self::$_instance->_suppressQueryParsingExceptions) {
             $queryTokens = Analyzer\Analyzer::getDefault()->tokenize($strQuery, self::$_instance->_encoding);
             $query = new Query\MultiTerm();
             $termsSign = self::$_instance->_defaultOperator == self::B_AND ? true : null;
             foreach ($queryTokens as $token) {
                 $query->addTerm(new Index\Term($token->getTermText()), $termsSign);
             }
             return $query;
         } else {
             throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
         }
     }
 }