2 * @brief The non-lemon-generated parts of the QueryParser class.
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 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(QueryParser
&&) = default;
77 QueryParser::operator=(QueryParser
&&) = default;
79 QueryParser::QueryParser() : internal(new QueryParser::Internal
) { }
81 QueryParser::~QueryParser() { }
84 QueryParser::set_stemmer(const Xapian::Stem
& stemmer
)
86 internal
->stemmer
= stemmer
;
90 QueryParser::set_stemming_strategy(stem_strategy strategy
)
92 internal
->stem_action
= strategy
;
96 QueryParser::set_stopper(const Stopper
* stopper
)
98 internal
->stopper
= stopper
;
102 QueryParser::set_default_op(Query::op default_op
)
104 switch (default_op
) {
108 case Query::OP_PHRASE
:
109 case Query::OP_ELITE_SET
:
110 case Query::OP_SYNONYM
:
115 throw Xapian::InvalidArgumentError(
116 "QueryParser::set_default_op() only accepts "
131 internal
->default_op
= default_op
;
135 QueryParser::get_default_op() const
137 return internal
->default_op
;
141 QueryParser::set_database(const Database
&db
) {
146 QueryParser::set_max_expansion(Xapian::termcount max_expansion
,
150 if (flags
& FLAG_WILDCARD
) {
151 internal
->max_wildcard_expansion
= max_expansion
;
152 internal
->max_wildcard_type
= max_type
;
154 if (flags
& FLAG_PARTIAL
) {
155 internal
->max_partial_expansion
= max_expansion
;
156 internal
->max_partial_type
= max_type
;
161 QueryParser::parse_query(const string
&query_string
, unsigned flags
,
162 const string
&default_prefix
)
164 if (!(flags
& FLAG_ACCUMULATE
)) {
165 internal
->stoplist
.clear();
166 internal
->unstem
.clear();
168 internal
->errmsg
= NULL
;
170 if (query_string
.empty()) return Query();
172 Query result
= internal
->parse_query(query_string
, flags
, default_prefix
);
173 if (internal
->errmsg
&& strcmp(internal
->errmsg
, "parse error") == 0) {
174 flags
&= FLAG_CJK_NGRAM
| FLAG_NO_POSITIONS
;
175 result
= internal
->parse_query(query_string
, flags
, default_prefix
);
178 if (internal
->errmsg
) throw Xapian::QueryParserError(internal
->errmsg
);
183 QueryParser::add_prefix(const string
&field
, const string
&prefix
)
185 Assert(internal
.get());
186 internal
->add_prefix(field
, prefix
);
190 QueryParser::add_prefix(const string
&field
, Xapian::FieldProcessor
* proc
)
192 Assert(internal
.get());
193 internal
->add_prefix(field
, proc
);
197 QueryParser::add_boolean_prefix(const string
&field
, const string
&prefix
,
198 const string
* grouping
)
200 Assert(internal
.get());
201 internal
->add_boolean_prefix(field
, prefix
, grouping
);
205 QueryParser::add_boolean_prefix(const string
&field
,
206 Xapian::FieldProcessor
* proc
,
207 const string
* grouping
)
209 Assert(internal
.get());
210 internal
->add_boolean_prefix(field
, proc
, grouping
);
214 QueryParser::stoplist_begin() const
216 const list
<string
> & sl
= internal
->stoplist
;
217 return TermIterator(new VectorTermList(sl
.begin(), sl
.end()));
221 QueryParser::unstem_begin(const string
&term
) const
223 struct range_adaptor
: public multimap
<string
, string
>::iterator
{
224 range_adaptor(multimap
<string
, string
>::iterator i
) :
225 multimap
<string
, string
>::iterator(i
) {}
226 const string
& operator*() const { return (*this)->second
; }
228 auto range
= internal
->unstem
.equal_range(term
);
229 return TermIterator(new VectorTermList(range_adaptor(range
.first
),
230 range_adaptor(range
.second
)));
234 QueryParser::add_rangeprocessor(Xapian::RangeProcessor
* range_proc
,
235 const std::string
* grouping
)
237 Assert(internal
.get());
238 internal
->rangeprocs
.push_back(RangeProc(range_proc
, grouping
));
242 QueryParser::get_corrected_query_string() const
244 return internal
->corrected_query
;
248 QueryParser::get_description() const
250 // FIXME : describe better!
251 return "Xapian::QueryParser()";