⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 queryparser.cpp

📁 clucene是c++版的全文检索引擎,完全移植于lucene,采用 stl 编写.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			CND_CONDITION(DelToken != NULL,"DelToken is NULL");
			_CLDELETE(DelToken);

			sfield = discardEscapeChar(term->Value);
			delField= true;
			_CLDELETE(term);
		}else{
			tokens->push(term);
		}

		// match for
		// TERM | (<LPAREN> QUERY <RPAREN>)
		if(tokens->peek()->Type == CL_NS(queryParser)::LPAREN){
			DelToken = MatchQueryToken(CL_NS(queryParser)::LPAREN);

			CND_CONDITION(DelToken != NULL,"DelToken is NULL");
			_CLDELETE(DelToken);

			q = MatchQuery(sfield);
			//DSR:2004.11.01:
			//If exception is thrown while trying to match trailing parenthesis,
			//need to prevent q from leaking.

			try{
			   DelToken = MatchQueryToken(CL_NS(queryParser)::RPAREN);

			   CND_CONDITION(DelToken != NULL,"DelToken is NULL");
			   _CLDELETE(DelToken);

			}catch(...) {
				_CLDELETE(q);
				throw;
			}
		}else{
			q = MatchTerm(sfield);
		}

		if (delField){
			_CLDELETE_CARRAY(sfield);
		}

	  return q;
	}


	Query* QueryParser::MatchTerm(const TCHAR* field){
	//Func - matches for TERM
	//       TERM ::= TERM | PREFIXTERM | WILDTERM | NUMBER
	//                [ <FUZZY> ] [ <CARAT> <NUMBER> [<FUZZY>]]
	//			      | (<RANGEIN> | <RANGEEX>) [<CARAT> <NUMBER>]
	//			      | <QUOTED> [SLOP] [<CARAT> <NUMBER>]
	//Pre  - field != NULL
	//Post -
		CND_PRECONDITION(field != NULL,"field is NULL");

		QueryToken* term = NULL;
		QueryToken* slop = NULL;
		QueryToken* boost = NULL;

		bool prefix = false;
		bool wildcard = false;
		bool fuzzy = false;
		bool rangein = false;
		Query* q = NULL;

		term = tokens->extract();
		QueryToken* DelToken = NULL; //Token that is about to be deleted

		switch(term->Type){
			case CL_NS(queryParser)::TERM:

			case CL_NS(queryParser)::NUMBER:

#ifndef NO_PREFIX_QUERY
			case CL_NS(queryParser)::PREFIXTERM:
#endif
#ifndef NO_WILDCARD_QUERY
			case CL_NS(queryParser)::WILDTERM:
#endif
			{ //start case
#ifndef NO_PREFIX_QUERY
				//Check if type of QueryToken term is a prefix term
				if(term->Type == CL_NS(queryParser)::PREFIXTERM){
					prefix = true;
				}
#endif
#ifndef NO_WILDCARD_QUERY
				//Check if type of QueryToken term is a wildcard term
				if(term->Type == CL_NS(queryParser)::WILDTERM){
					wildcard = true;
				}
#endif

#ifndef NO_FUZZY_QUERY
				//Peek to see if the type of the next token is fuzzy term
				if(tokens->peek()->Type == CL_NS(queryParser)::FUZZY){
					DelToken = MatchQueryToken(CL_NS(queryParser)::FUZZY);

					CND_CONDITION(DelToken !=NULL, "DelToken is NULL");
					_CLDELETE(DelToken);

					fuzzy = true;
				}
#endif
				if(tokens->peek()->Type == CL_NS(queryParser)::CARAT){
					DelToken = MatchQueryToken(CL_NS(queryParser)::CARAT);

					CND_CONDITION(DelToken !=NULL, "DelToken is NULL");
					_CLDELETE(DelToken);

					boost = MatchQueryToken(CL_NS(queryParser)::NUMBER);
#ifndef NO_FUZZY_QUERY
				   if(tokens->peek()->Type == CL_NS(queryParser)::FUZZY){
					   DelToken = MatchQueryToken(CL_NS(queryParser)::FUZZY);

					   CND_CONDITION(DelToken !=NULL, "DelToken is NULL");
					   _CLDELETE(DelToken);

					   fuzzy = true;
				   }
#endif
				} //end if type==CARAT

				if (false){
				}
#ifndef NO_WILDCARD_QUERY
				else if(wildcard){
					Term* t = NULL;
					TCHAR* tmp = discardEscapeChar(term->Value);
					if ( lowercaseWildcardTerms ){
						_tcslwr(tmp);
						t = _CLNEW Term(field, tmp);
					}else{
						t = _CLNEW Term(field, tmp);
					}
					q = _CLNEW WildcardQuery(t);
					_CLDECDELETE(t);
					_CLDELETE_CARRAY(tmp);
					break;
				}
#endif
#ifndef NO_PREFIX_QUERY
				else if(prefix){
					//Create a PrefixQuery
					q = GetPrefixQuery(field,term->Value,lowercaseExpandedTerms);
					break;
				}
#endif
#ifndef NO_FUZZY_QUERY
				else if(fuzzy){
					//Create a FuzzyQuery
					q = GetFuzzyQuery(field,term->Value,lowercaseExpandedTerms);
					break;
				}
#endif
				else{
					q = GetFieldQuery(field, analyzer, term->Value);
					break;
				}
			}//case CL_NS(queryParser)::TERM:
			 //case CL_NS(queryParser)::NUMBER:
			 //case CL_NS(queryParser)::PREFIXTERM:
			 //case CL_NS(queryParser)::WILDTERM:

#ifndef NO_RANGE_QUERY
			case CL_NS(queryParser)::RANGEIN:
			case CL_NS(queryParser)::RANGEEX:{

				if(term->Type == CL_NS(queryParser)::RANGEIN){
					rangein = true;
				}

				if(tokens->peek()->Type == CL_NS(queryParser)::CARAT){
					DelToken = MatchQueryToken(CL_NS(queryParser)::CARAT);

					CND_CONDITION(DelToken !=NULL, "DelToken is NULL");
					_CLDELETE(DelToken);

					boost = MatchQueryToken(CL_NS(queryParser)::NUMBER);
				}

				TCHAR* tmp = stringDuplicate ( term->Value +1);
				tmp[_tcslen(tmp)-1] = 0;
				q = GetRangeQuery(field, analyzer,	tmp, rangein);
				_CLDELETE_ARRAY(tmp);
				break;
			} //case CL_NS(queryParser)::RANGEIN:
			//case CL_NS(queryParser)::RANGEEX:
#endif
			case CL_NS(queryParser)::QUOTED:{
				if(tokens->peek()->Type == CL_NS(queryParser)::SLOP){
					slop = MatchQueryToken(CL_NS(queryParser)::SLOP);
				}

				if(tokens->peek()->Type == CL_NS(queryParser)::CARAT){
					DelToken = MatchQueryToken(CL_NS(queryParser)::CARAT);

					CND_CONDITION(DelToken !=NULL, "DelToken is NULL");
					_CLDELETE(DelToken);

					boost = MatchQueryToken(CL_NS(queryParser)::NUMBER);
				}

				//todo: check term->Value+1
				TCHAR* quotedValue = STRDUP_TtoT(term->Value+1);
				quotedValue[_tcslen(quotedValue)-1] = '\0';
				q = GetFieldQuery(field, analyzer, quotedValue);
				_CLDELETE_CARRAY(quotedValue);
				if(slop != NULL && q != NULL && q->instanceOf(PhraseQuery::getClassName()) ){
				   try {
                       TCHAR* end;
					   int32_t s = (int32_t)_tcstoi64(slop->Value+1, &end, 10);
					   ((PhraseQuery*)q)->setSlop( s );
				   }catch(...){ //todo: only catch IO Err???
					   //ignored
				   }
				}
   				_CLDELETE(slop);//bvk: moved delting of slop to after
   				              //the PhraseQuery check. Otherwise use of slop
   				              //with non-phrasequeries will leak memory
			} //case CL_NS(queryParser)::QUOTED:
		} // end of switch

		_CLDELETE(term);


		if( q!=NULL && boost != NULL ){
			float_t f = 1.0F;
			try {
				//TODO: check this
				TCHAR* tmp;
				f = _tcstod(boost->Value, &tmp);
				//f = Single.Parse(boost->Value, NumberFormatInfo.InvariantInfo);
			}catch(...){ //todo: only catch IO Err???
				//ignored
			}
			_CLDELETE(boost);

			q->setBoost( f);
		}

		return q;
	}

	QueryToken* QueryParser::MatchQueryToken(QueryTokenTypes expectedType){
	//Func - matches for QueryToken of the specified type and returns it
	//       otherwise Exception throws
	//Pre  - tokens != NULL
	//Post -

		CND_PRECONDITION(tokens != NULL,"tokens is NULL");

		if(tokens->count() == 0){
			QueryParserBase::throwParserException(_T("Error: Unexpected end of program"),' ',0,0);
		}

	  //Extract a token form the TokenList tokens
	  QueryToken* t = tokens->extract();
	  //Check if the type of the token t matches the expectedType
	  if (expectedType != t->Type){
		  TCHAR buf[200];
		  _sntprintf(buf,200,_T("Error: Unexpected QueryToken: %d, expected: %d"),t->Type,expectedType);
		  _CLDELETE(t);
		  QueryParserBase::throwParserException(buf,' ',0,0);
		}

	  //Return the matched token
	  return t;
	}

	void QueryParser::ExtractAndDeleteToken(void){
	//Func - Extracts the first token from the Tokenlist tokenlist
	//       and destroys it
	//Pre  - true
	//Post - The first token has been extracted and destroyed

		CND_PRECONDITION(tokens != NULL, "tokens is NULL");

		//Extract the token from the TokenList tokens
		QueryToken* t = tokens->extract();
		//Condition Check Token may not be NULL
		CND_CONDITION(t != NULL, "Token is NULL");
		//Delete Token
		_CLDELETE(t);
	}

CL_NS_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -