1 /* queryparser.cc: The non-lemon-generated parts of the QueryParser
4 * Copyright (C) 2005,2006,2007,2008,2010,2011,2012,2013,2015,2016 Olly Betts
5 * Copyright (C) 2010 Adam Sjøgren
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
25 #include "xapian/error.h"
26 #include <xapian/queryparser.h>
27 #include <xapian/termiterator.h>
29 #include "api/vectortermlist.h"
31 #include "queryparser_internal.h"
35 using namespace Xapian
;
39 // Default implementation in case the user hasn't implemented it.
41 Stopper::get_description() const
43 return "Xapian::Stopper subclass";
47 SimpleStopper::get_description() const
49 string
desc("Xapian::SimpleStopper(");
50 unordered_set
<string
>::const_iterator i
;
51 for (i
= stop_words
.begin(); i
!= stop_words
.end(); ++i
) {
52 if (i
!= stop_words
.begin()) desc
+= ' ';
59 RangeProcessor::~RangeProcessor() { }
61 ValueRangeProcessor::~ValueRangeProcessor() { }
63 FieldProcessor::~FieldProcessor() { }
65 QueryParser::QueryParser(const QueryParser
& o
) : internal(o
.internal
) { }
68 QueryParser::operator=(const QueryParser
& o
)
70 internal
= o
.internal
;
74 QueryParser::QueryParser() : internal(new QueryParser::Internal
) { }
76 QueryParser::~QueryParser() { }
79 QueryParser::set_stemmer(const Xapian::Stem
& stemmer
)
81 internal
->stemmer
= stemmer
;
85 QueryParser::set_stemming_strategy(stem_strategy strategy
)
87 internal
->stem_action
= strategy
;
91 QueryParser::set_stopper(const Stopper
* stopper
)
93 internal
->stopper
= stopper
;
97 QueryParser::set_default_op(Query::op default_op
)
103 case Query::OP_PHRASE
:
104 case Query::OP_ELITE_SET
:
105 case Query::OP_SYNONYM
:
110 throw Xapian::InvalidArgumentError(
111 "QueryParser::set_default_op() only accepts "
126 internal
->default_op
= default_op
;
130 QueryParser::get_default_op() const
132 return internal
->default_op
;
136 QueryParser::set_database(const Database
&db
) {
141 QueryParser::set_max_expansion(Xapian::termcount max_expansion
,
145 if (flags
& FLAG_WILDCARD
) {
146 internal
->max_wildcard_expansion
= max_expansion
;
147 internal
->max_wildcard_type
= max_type
;
149 if (flags
& FLAG_PARTIAL
) {
150 internal
->max_partial_expansion
= max_expansion
;
151 internal
->max_partial_type
= max_type
;
156 QueryParser::parse_query(const string
&query_string
, unsigned flags
,
157 const string
&default_prefix
)
159 internal
->stoplist
.clear();
160 internal
->unstem
.clear();
161 internal
->errmsg
= NULL
;
163 if (query_string
.empty()) return Query();
165 Query result
= internal
->parse_query(query_string
, flags
, default_prefix
);
166 if (internal
->errmsg
&& strcmp(internal
->errmsg
, "parse error") == 0) {
167 flags
&= FLAG_CJK_NGRAM
;
168 result
= internal
->parse_query(query_string
, flags
, default_prefix
);
171 if (internal
->errmsg
) throw Xapian::QueryParserError(internal
->errmsg
);
176 QueryParser::add_prefix(const string
&field
, const string
&prefix
)
178 Assert(internal
.get());
179 internal
->add_prefix(field
, prefix
);
183 QueryParser::add_prefix(const string
&field
, Xapian::FieldProcessor
* proc
)
185 Assert(internal
.get());
186 internal
->add_prefix(field
, proc
);
190 QueryParser::add_boolean_prefix(const string
&field
, const string
&prefix
,
191 const string
* grouping
)
193 Assert(internal
.get());
194 internal
->add_boolean_prefix(field
, prefix
, grouping
);
198 QueryParser::add_boolean_prefix(const string
&field
,
199 Xapian::FieldProcessor
* proc
,
200 const string
* grouping
)
202 Assert(internal
.get());
203 internal
->add_boolean_prefix(field
, proc
, grouping
);
207 QueryParser::stoplist_begin() const
209 const list
<string
> & sl
= internal
->stoplist
;
210 return TermIterator(new VectorTermList(sl
.begin(), sl
.end()));
214 QueryParser::unstem_begin(const string
&term
) const
216 pair
<multimap
<string
, string
>::iterator
,
217 multimap
<string
, string
>::iterator
> range
;
218 range
= internal
->unstem
.equal_range(term
);
220 multimap
<string
, string
>::iterator
& i
= range
.first
;
221 while (i
!= range
.second
) {
222 l
.push_back(i
->second
);
225 return TermIterator(new VectorTermList(l
.begin(), l
.end()));
229 QueryParser::add_rangeprocessor(Xapian::RangeProcessor
* range_proc
,
230 const std::string
* grouping
)
232 Assert(internal
.get());
233 internal
->rangeprocs
.push_back(RangeProc(range_proc
, grouping
));
237 QueryParser::get_corrected_query_string() const
239 return internal
->corrected_query
;
243 QueryParser::get_description() const
245 // FIXME : describe better!
246 return "Xapian::QueryParser()";