29 #line 1 "queryparser/queryparser.lemony"
78 #define Parse_ENGINEALWAYSONSTACK
86 return ch < 128 && C_isupper(static_cast<unsigned char>(ch));
91 return ch < 128 && C_isdigit(static_cast<unsigned char>(ch));
96 return ch < 128 && C_isalpha(static_cast<unsigned char>(ch));
122 return ch ==
'+' || ch ==
'#';
133 return ch ==
'"' || ch == 0x201c || ch == 0x201d;
139 if (!
U_isupper(ch) && ch !=
':')
return false;
140 string::size_type len = prefix.length();
141 return (len > 1 && prefix[len - 1] !=
':');
173 explicit Term(
const string &name_)
176 :
name(name_), field_info(field_info_),
180 const string &unstemmed_,
183 : state(state_),
name(name_), field_info(field_info_),
184 unstemmed(unstemmed_), stem(stem_), pos(pos_) { }
189 string make_term(
const string & prefix)
const;
192 if (stem == QueryParser::STEM_SOME) stem = QueryParser::STEM_NONE;
201 Query * as_wildcarded_query(
State * state)
const;
211 Query * as_partial_query(
State * state_)
const;
214 Query* as_unbroken_query()
const;
217 void as_positional_unbroken(
Terms* terms)
const;
220 Query as_range_query()
const;
222 Query get_query()
const;
224 Query get_query_with_synonyms()
const;
226 Query get_query_with_auto_synonyms()
const;
235 const char* error = NULL;
240 : qpi(qpi_), flags(flags_), effective_default_op(qpi_->default_op)
242 if ((flags & QueryParser::FLAG_NO_POSITIONS)) {
244 effective_default_op = Query::OP_AND;
258 qpi->
unstem.insert(make_pair(term, unstemmed));
271 if (i.default_grouping) {
276 return new Term(range_query,
str(slot));
280 return new Term(range_query, i.grouping);
282 return new Term(range_query,
string());
289 return effective_default_op;
333 if (stem != QueryParser::STEM_NONE && stem != QueryParser::STEM_ALL)
335 if (!prefix.empty()) {
339 if (stem != QueryParser::STEM_NONE) {
340 term += state->stem_term(
name);
345 if (!unstemmed.empty())
346 state->add_to_unstem(term, unstemmed);
362 : i(i_), pos(pos_), first(first_) { }
373 if (first)
return *first;
378 return i == o.
i && first == o.
first;
382 return !(*
this == o);
396 const auto& prefixes = field_info->prefixes;
397 if (prefixes.empty()) {
398 Assert(field_info->proc.get());
399 return (*field_info->proc)(
name);
402 Query q = get_query();
404 for (
auto&& prefix : prefixes) {
407 if (!prefix.empty()) {
416 if (syn == end && stem != QueryParser::STEM_NONE) {
419 if (!prefix.empty()) {
423 term += state->stem_term(
name);
437 const unsigned MASK_ENABLE_AUTO_SYNONYMS =
438 QueryParser::FLAG_AUTO_SYNONYMS |
439 QueryParser::FLAG_AUTO_MULTIWORD_SYNONYMS;
440 if (state->flags & MASK_ENABLE_AUTO_SYNONYMS)
441 return get_query_with_synonyms();
451 if (op == Query::OP_OR) {
453 }
else if (op == Query::OP_AND) {
456 *q =
Query(op, *q, *term);
468 if (op == Query::OP_OR) {
470 }
else if (op == Query::OP_AND) {
473 *q =
Query(op, *q, term);
483 const auto& prefixes = field_info->prefixes;
484 if (prefixes.empty()) {
485 Assert(field_info->proc.get());
486 return (*field_info->proc)(
name);
488 auto piter = prefixes.begin();
489 Query q(make_term(*piter), 1, pos);
490 while (++piter != prefixes.end()) {
491 q |=
Query(make_term(*piter), 1, pos);
499 const auto& prefixes = field_info->prefixes;
503 subqs.reserve(prefixes.size());
504 for (
string root : prefixes) {
507 subqs.push_back(
Query(Query::OP_WILDCARD, root, max, max_type,
510 Query * q =
new Query(Query::OP_SYNONYM, subqs.begin(), subqs.end());
520 vector<Query> subqs_partial;
521 vector<Query> subqs_full;
523 for (
const string& prefix : field_info->prefixes) {
524 string root = prefix;
527 subqs_partial.push_back(
Query(Query::OP_WILDCARD, root, max, max_type,
529 if (!state->is_stopword(
this)) {
532 subqs_full.push_back(
Query(make_term(prefix), 1, pos));
536 Query(Query::OP_SYNONYM,
537 subqs_partial.begin(), subqs_partial.end()),
538 Query(Query::OP_SYNONYM,
539 subqs_full.begin(), subqs_full.end()));
547 vector<Query> prefix_subqs;
548 vector<Query> ngram_subqs;
549 const auto& prefixes = field_info->prefixes;
550 for (
const string& prefix : prefixes) {
552 ngram_subqs.push_back(
Query(prefix + *tk, 1, pos));
554 prefix_subqs.push_back(
Query(Query::OP_AND,
555 ngram_subqs.begin(), ngram_subqs.end()));
559 prefix_subqs.begin(), prefix_subqs.end());
578 return (ch && ch < 128 && strchr(
".-/:\\@", ch) != NULL);
584 return (ch && ch < 128 && strchr(
"(/\\@<>=*[{\"", ch) != NULL);
590 const unsigned int SHOULD_STEM_MASK =
605 if (ch ==
'\'' || ch ==
'&' || ch == 0xb7 || ch == 0x5f4 || ch == 0x2027) {
617 if (ch == 0x2019 || ch == 0x201b)
619 if (ch <= 0x200d || ch == 0x2060 || ch == 0xfeff)
641 if (ch >= 0x200b && (ch <= 0x200d || ch == 0x2060 || ch == 0xfeff))
652 QueryParser::Internal::add_prefix(
const string &field,
const string &prefix)
654 map<string, FieldInfo>::iterator p = field_map.find(field);
655 if (p == field_map.end()) {
660 throw Xapian::InvalidOperationError(
"Can't use add_prefix() and add_boolean_prefix() on the same field name, or add_boolean_prefix() with different values of the 'exclusive' parameter");
662 if (p->second.proc.get())
664 p->second.prefixes.push_back(prefix);
671 map<string, FieldInfo>::iterator p = field_map.find(field);
672 if (p == field_map.end()) {
677 throw Xapian::InvalidOperationError(
"Can't use add_prefix() and add_boolean_prefix() on the same field name, or add_boolean_prefix() with different values of the 'exclusive' parameter");
679 if (!p->second.prefixes.empty())
686 QueryParser::Internal::add_boolean_prefix(
const string &field,
687 const string &prefix,
696 map<string, FieldInfo>::iterator p = field_map.find(field);
697 if (p == field_map.end()) {
701 if (p->second.type != type) {
702 throw Xapian::InvalidOperationError(
"Can't use add_prefix() and add_boolean_prefix() on the same field name, or add_boolean_prefix() with different values of the 'exclusive' parameter");
704 if (p->second.proc.get())
706 p->second.prefixes.push_back(prefix);
711 QueryParser::Internal::add_boolean_prefix(
const string &field,
721 map<string, FieldInfo>::iterator p = field_map.find(field);
722 if (p == field_map.end()) {
726 if (p->second.type != type) {
727 throw Xapian::InvalidOperationError(
"Can't use add_prefix() and add_boolean_prefix() on the same field name, or add_boolean_prefix() with different values of the 'exclusive' parameter");
729 if (!p->second.prefixes.empty())
737 bool try_word_break,
bool& needs_word_break,
748 }
while (p != end && *p ==
'.' && ++p != end &&
U_isupper(*p));
751 if (t.length() > 1) {
761 was_acronym = !term.empty();
764 const char* start = it.
raw();
766 term.assign(start, it.
raw() - start);
767 needs_word_break =
true;
771 unsigned prevch = *it;
773 while (++it != end) {
783 unsigned nextch = *p;
797 string suff_term = term;
801 if (suff_term.size() - term.size() == 3) {
807 if (!suff_term.empty() && (p == end || !
is_wordchar(*p))) {
812 bool use_suff_term =
false;
814 if (db.term_exists(lc)) {
815 use_suff_term =
true;
818 if (!db.term_exists(lc)) use_suff_term =
true;
830 #line 1421 "queryparser/queryparser.lemony"
859 if (it == filter.end()) {
860 filter.insert(make_pair(
grouping, qnew));
862 Query & q = it->second;
884 auto i = filter.begin();
885 Assert(i != filter.end());
887 while (++i != filter.end()) {
917 for (
auto&& t : terms) {
924 terms.push_back(term);
943 subqs.reserve(terms.size());
944 if (state->
flags & QueryParser::FLAG_AUTO_MULTIWORD_SYNONYMS) {
949 vector<Term*>::size_type begin = 0;
950 vector<Term*>::size_type i = begin;
951 while (terms.size() - i > 0) {
952 size_t longest_match = 0;
955 vector<Term*>::size_type longest_match_end = 0;
956 if (terms.size() - i >= 2) {
958 key = terms[i]->name;
960 key += terms[i + 1]->name;
963 if (synkey != synend) {
964 longest_match = key.size();
965 longest_match_end = i + 2;
966 for (
auto j = i + 2; j < terms.size(); ++j) {
968 key += terms[j]->name;
970 if (synkey == synend)
972 const string& found = *synkey;
975 if (found.size() == key.size()) {
976 longest_match = key.size();
977 longest_match_end = j + 1;
982 if (longest_match == 0) {
984 if (stopper && (*stopper)(terms[i]->
name)) {
987 if (default_op_is_positional)
988 terms[i]->need_positions();
989 subqs.push_back(terms[i]->get_query_with_auto_synonyms());
994 i = longest_match_end;
995 key.resize(longest_match);
997 vector<Query> subqs2;
998 for (
auto j = begin; j != i; ++j) {
999 if (stopper && (*stopper)(terms[j]->
name)) {
1002 if (default_op_is_positional)
1003 terms[i]->need_positions();
1004 subqs2.push_back(terms[j]->get_query());
1007 Query q_original_terms;
1008 if (default_op_is_positional) {
1009 q_original_terms =
Query(default_op,
1010 subqs2.begin(), subqs2.end(),
1013 q_original_terms =
Query(default_op,
1014 subqs2.begin(), subqs2.end());
1020 Query q(Query::OP_SYNONYM,
1028 vector<Term*>::const_iterator i;
1029 for (i = terms.begin(); i != terms.end(); ++i) {
1030 if (stopper && (*stopper)((*i)->name)) {
1033 if (default_op_is_positional)
1034 (*i)->need_positions();
1035 subqs.push_back((*i)->get_query_with_auto_synonyms());
1040 if (!empty_ok && stopper && subqs.empty() &&
1041 stoplist_size < state->stoplist_size()) {
1050 if (!subqs.empty()) {
1051 if (default_op_is_positional) {
1052 q =
new Query(default_op, subqs.begin(), subqs.end(),
1055 q =
new Query(default_op, subqs.begin(), subqs.end());
1090 const vector<Query>& v,
1092 if (op == Query::OP_AND) {
1093 return Query(op, v.begin(), v.end());
1095 return Query(op, v.begin(), v.end(), w);
1100 if (window ==
size_t(-1)) op = Query::OP_AND;
1102 size_t n_terms = terms.size();
1104 if (uniform_prefixes) {
1106 for (
auto&& prefix : *prefixes) {
1107 vector<Query> subqs;
1108 subqs.reserve(n_terms);
1109 for (
Term* t : terms) {
1110 subqs.push_back(
Query(t->make_term(prefix), 1, t->pos));
1112 add_to_query(q, Query::OP_OR, opwindow_subq(op, subqs, w));
1116 vector<Query> subqs;
1117 subqs.reserve(n_terms);
1118 for (
Term* t : terms) {
1119 subqs.push_back(t->get_query());
1121 q =
new Query(opwindow_subq(op, subqs, w));
1129 : window(no_pos ? size_t(-1) : 0),
1130 uniform_prefixes(
true),
1136 return new Terms(state->
flags & QueryParser::FLAG_NO_POSITIONS);
1140 for (
auto&& t : terms) {
1148 if (terms.empty()) {
1149 prefixes = &term_prefixes;
1150 }
else if (uniform_prefixes && prefixes != &term_prefixes) {
1151 if (*prefixes != term_prefixes) {
1153 uniform_prefixes =
false;
1157 terms.push_back(term);
1161 if (alternative_window > window) window = alternative_window;
1166 return as_opwindow_query(Query::OP_PHRASE, 0);
1176 return as_opwindow_query(Query::OP_NEAR, w - 1);
1186 return as_opwindow_query(Query::OP_PHRASE, w - 1);
1197 Term * c =
new Term(state, t, field_info, unstemmed, stem, pos);
1208 #define VET_BOOL_ARGS(A, B, OP_TXT) \
1211 state->error = "Syntax: <expression> " OP_TXT " <expression>";\
1212 yy_parse_failed(yypParser);\
1217 #line 1218 "queryparser/queryparser_internal.cc"
1275 # define INTERFACE 1
1278 #define YYCODETYPE unsigned char
1280 #define YYACTIONTYPE unsigned char
1281 #define ParseTOKENTYPE Term *
1291 #ifndef YYSTACKDEPTH
1292 #define YYSTACKDEPTH 100
1294 #define ParseARG_SDECL State * state;
1295 #define ParseARG_PDECL ,State * state
1296 #define ParseARG_FETCH State * state = yypParser->state
1297 #define ParseARG_STORE yypParser->state = state
1301 #define YY_MAX_SHIFT 34
1302 #define YY_MIN_SHIFTREDUCE 77
1303 #define YY_MAX_SHIFTREDUCE 132
1304 #define YY_ERROR_ACTION 133
1305 #define YY_ACCEPT_ACTION 134
1306 #define YY_NO_ACTION 135
1307 #define YY_MIN_REDUCE 136
1308 #define YY_MAX_REDUCE 191
1320 # define yytestcase(X)
1374 #define YY_ACTTAB_COUNT (326)
1376 134, 34, 34, 20, 8, 34, 18, 13, 16, 27,
1377 31, 23, 30, 28, 3, 21, 112, 10, 9, 2,
1378 25, 15, 111, 114, 104, 105, 97, 87, 14, 4,
1379 137, 113, 126, 115, 12, 11, 1, 7, 10, 9,
1380 124, 25, 15, 98, 88, 104, 105, 97, 87, 14,
1381 4, 29, 113, 138, 138, 138, 8, 138, 18, 13,
1382 16, 119, 31, 23, 30, 28, 141, 141, 141, 8,
1383 141, 18, 13, 16, 125, 31, 23, 30, 28, 140,
1384 140, 140, 8, 140, 18, 13, 16, 123, 31, 23,
1385 30, 28, 26, 26, 20, 8, 26, 18, 13, 16,
1386 136, 31, 23, 30, 28, 24, 24, 24, 8, 24,
1387 18, 13, 16, 135, 31, 23, 30, 28, 22, 22,
1388 22, 8, 22, 18, 13, 16, 135, 31, 23, 30,
1389 28, 139, 139, 139, 8, 139, 18, 13, 16, 121,
1390 31, 23, 30, 28, 10, 9, 135, 25, 15, 122,
1391 135, 104, 105, 97, 87, 14, 4, 135, 113, 135,
1392 189, 189, 135, 25, 19, 135, 135, 104, 105, 189,
1393 189, 14, 4, 162, 113, 162, 162, 162, 162, 33,
1394 32, 33, 32, 116, 135, 135, 120, 118, 120, 118,
1395 106, 25, 17, 117, 162, 104, 105, 95, 135, 14,
1396 4, 135, 113, 25, 17, 135, 135, 104, 105, 99,
1397 135, 14, 4, 135, 113, 25, 17, 135, 135, 104,
1398 105, 96, 135, 14, 4, 135, 113, 25, 17, 135,
1399 135, 104, 105, 100, 135, 14, 4, 135, 113, 25,
1400 19, 135, 135, 104, 105, 135, 135, 14, 4, 135,
1401 113, 135, 149, 149, 135, 31, 23, 30, 28, 152,
1402 135, 135, 152, 135, 31, 23, 30, 28, 135, 150,
1403 135, 135, 150, 135, 31, 23, 30, 28, 153, 135,
1404 135, 153, 135, 31, 23, 30, 28, 151, 135, 135,
1405 151, 135, 31, 23, 30, 28, 135, 148, 148, 135,
1406 31, 23, 30, 28, 191, 135, 191, 191, 191, 191,
1407 6, 5, 1, 7, 5, 1, 7, 135, 135, 135,
1408 135, 135, 135, 135, 135, 191,
1411 25, 26, 27, 28, 29, 30, 31, 32, 33, 7,
1412 35, 36, 37, 38, 5, 34, 12, 8, 9, 10,
1413 11, 12, 21, 12, 15, 16, 17, 18, 19, 20,
1414 0, 22, 12, 22, 8, 9, 4, 5, 8, 9,
1415 12, 11, 12, 17, 18, 15, 16, 17, 18, 19,
1416 20, 6, 22, 26, 27, 28, 29, 30, 31, 32,
1417 33, 14, 35, 36, 37, 38, 26, 27, 28, 29,
1418 30, 31, 32, 33, 12, 35, 36, 37, 38, 26,
1419 27, 28, 29, 30, 31, 32, 33, 12, 35, 36,
1420 37, 38, 26, 27, 28, 29, 30, 31, 32, 33,
1421 0, 35, 36, 37, 38, 26, 27, 28, 29, 30,
1422 31, 32, 33, 39, 35, 36, 37, 38, 26, 27,
1423 28, 29, 30, 31, 32, 33, 39, 35, 36, 37,
1424 38, 26, 27, 28, 29, 30, 31, 32, 33, 13,
1425 35, 36, 37, 38, 8, 9, 39, 11, 12, 23,
1426 39, 15, 16, 17, 18, 19, 20, 39, 22, 39,
1427 8, 9, 39, 11, 12, 39, 39, 15, 16, 17,
1428 18, 19, 20, 0, 22, 2, 3, 4, 5, 6,
1429 7, 6, 7, 12, 39, 39, 13, 14, 13, 14,
1430 19, 11, 12, 22, 21, 15, 16, 17, 39, 19,
1431 20, 39, 22, 11, 12, 39, 39, 15, 16, 17,
1432 39, 19, 20, 39, 22, 11, 12, 39, 39, 15,
1433 16, 17, 39, 19, 20, 39, 22, 11, 12, 39,
1434 39, 15, 16, 17, 39, 19, 20, 39, 22, 11,
1435 12, 39, 39, 15, 16, 39, 39, 19, 20, 39,
1436 22, 39, 32, 33, 39, 35, 36, 37, 38, 30,
1437 39, 39, 33, 39, 35, 36, 37, 38, 39, 30,
1438 39, 39, 33, 39, 35, 36, 37, 38, 30, 39,
1439 39, 33, 39, 35, 36, 37, 38, 30, 39, 39,
1440 33, 39, 35, 36, 37, 38, 39, 32, 33, 39,
1441 35, 36, 37, 38, 0, 39, 2, 3, 4, 5,
1442 2, 3, 4, 5, 3, 4, 5, 39, 39, 39,
1443 39, 39, 39, 39, 39, 21, 39, 39, 39, 39,
1444 39, 39, 39, 39, 39, 39, 39, 39, 39,
1446 #define YY_SHIFT_COUNT (34)
1447 #define YY_SHIFT_MIN (0)
1448 #define YY_SHIFT_MAX (311)
1450 30, 9, 136, 136, 136, 136, 136, 136, 152, 180,
1451 192, 204, 216, 228, 11, 173, 304, 175, 26, 175,
1452 308, 171, 311, 126, 32, 4, 1, 20, 2, 28,
1453 45, 47, 62, 75, 100,
1455 #define YY_REDUCE_COUNT (14)
1456 #define YY_REDUCE_MIN (-25)
1457 #define YY_REDUCE_MAX (265)
1459 -25, 27, 40, 53, 66, 79, 92, 105, 220, 229,
1460 239, 248, 257, 265, -19,
1463 144, 144, 144, 144, 144, 144, 144, 144, 145, 133,
1464 133, 133, 133, 160, 133, 161, 190, 162, 133, 161,
1465 133, 133, 142, 167, 143, 133, 187, 133, 169, 133,
1466 168, 166, 133, 133, 187,
1528 #ifdef YYTRACKMAXSTACKDEPTH
1531 #ifndef YYNOERRORRECOVERY
1548 #if defined(YYCOVERAGE) || defined(XAPIAN_DEBUG_LOG)
1551 static const char *
const yyTokenName[] = {
1595 static const char *
const yyRuleName[] = {
1598 "expr ::= bool_arg AND bool_arg",
1599 "expr ::= bool_arg NOT bool_arg",
1600 "expr ::= bool_arg AND NOT bool_arg",
1601 "expr ::= bool_arg AND HATE_AFTER_AND bool_arg",
1602 "expr ::= bool_arg OR bool_arg",
1603 "expr ::= bool_arg XOR bool_arg",
1605 "prob_expr ::= prob",
1607 "prob ::= stop_prob RANGE",
1608 "prob ::= stop_term stop_term",
1609 "prob ::= prob stop_term",
1610 "prob ::= LOVE term",
1611 "prob ::= stop_prob LOVE term",
1612 "prob ::= HATE term",
1613 "prob ::= stop_prob HATE term",
1614 "prob ::= HATE BOOLEAN_FILTER",
1615 "prob ::= stop_prob HATE BOOLEAN_FILTER",
1616 "prob ::= BOOLEAN_FILTER",
1617 "prob ::= stop_prob BOOLEAN_FILTER",
1618 "prob ::= LOVE BOOLEAN_FILTER",
1619 "prob ::= stop_prob LOVE BOOLEAN_FILTER",
1620 "stop_prob ::= stop_term",
1621 "stop_term ::= TERM",
1623 "compound_term ::= WILD_TERM",
1624 "compound_term ::= PARTIAL_TERM",
1625 "compound_term ::= QUOTE phrase QUOTE",
1626 "compound_term ::= phrased_term",
1627 "compound_term ::= group",
1628 "compound_term ::= near_expr",
1629 "compound_term ::= adj_expr",
1630 "compound_term ::= BRA expr KET",
1631 "compound_term ::= SYNONYM TERM",
1632 "compound_term ::= UNBROKEN_WORDS",
1634 "phrase ::= UNBROKEN_WORDS",
1635 "phrase ::= phrase TERM",
1636 "phrase ::= phrase UNBROKEN_WORDS",
1637 "phrased_term ::= TERM PHR_TERM",
1638 "phrased_term ::= phrased_term PHR_TERM",
1639 "group ::= TERM GROUP_TERM",
1640 "group ::= group GROUP_TERM",
1641 "group ::= group EMPTY_GROUP_OK",
1642 "near_expr ::= TERM NEAR TERM",
1643 "near_expr ::= near_expr NEAR TERM",
1644 "adj_expr ::= TERM ADJ TERM",
1645 "adj_expr ::= adj_expr ADJ TERM",
1646 "expr ::= prob_expr",
1647 "bool_arg ::= expr",
1648 "prob_expr ::= term",
1649 "stop_prob ::= prob",
1650 "stop_term ::= compound_term",
1651 "term ::= compound_term",
1658 static const char *ParseTokenName(
int tokenType){
1659 if( tokenType>=0 && tokenType<(
int)(
sizeof(yyTokenName)/
sizeof(yyTokenName[0])) ){
1660 return yyTokenName[tokenType];
1669 static const char *ParseRuleName(
int ruleNum){
1670 if( ruleNum>=0 && ruleNum<(
int)(
sizeof(yyRuleName)/
sizeof(yyRuleName[0])) ){
1671 return yyRuleName[ruleNum];
1682 #ifndef YYMALLOCARGTYPE
1683 # define YYMALLOCARGTYPE size_t
1690 #ifdef YYTRACKMAXSTACKDEPTH
1695 pParser->yytos = NULL;
1697 pParser->yystksz = 0;
1698 if( yyGrowStack(pParser) ){
1699 pParser->
yystack = &pParser->yystk0;
1700 pParser->yystksz = 1;
1704 #ifndef YYNOERRORRECOVERY
1708 pParser->yytos = pParser->
yystack;
1709 pParser->
yystack[0].stateno = 0;
1710 pParser->
yystack[0].major = 0;
1719 #ifndef Parse_ENGINEALWAYSONSTACK
1786 #line 1810 "queryparser/queryparser.lemony"
1787 delete (yypminor->
yy0);
1788 #line 1789 "queryparser/queryparser_internal.cc"
1798 #line 1885 "queryparser/queryparser.lemony"
1799 delete (yypminor->
yy39);
1800 #line 1801 "queryparser/queryparser_internal.cc"
1806 #line 1994 "queryparser/queryparser.lemony"
1807 delete (yypminor->
yy40);
1808 #line 1809 "queryparser/queryparser_internal.cc"
1816 #line 2185 "queryparser/queryparser.lemony"
1817 delete (yypminor->
yy32);
1818 #line 1819 "queryparser/queryparser_internal.cc"
1823 #line 2226 "queryparser/queryparser.lemony"
1824 delete (yypminor->
yy14);
1825 #line 1826 "queryparser/queryparser_internal.cc"
1844 LOGLINE(QUERYPARSER,
"Popping " << ParseTokenName(yytos->
major));
1857 #ifndef Parse_ENGINEALWAYSONSTACK
1877 #ifdef YYTRACKMAXSTACKDEPTH
1878 int ParseStackPeak(
yyParser *pParser){
1879 return pParser->yyhwm;
1888 #if defined(YYCOVERAGE)
1900 #if defined(YYCOVERAGE)
1901 int ParseCoverage(FILE *out){
1902 int stateno, iLookAhead, i;
1904 for(stateno=0; stateno<
YYNSTATE; stateno++){
1906 for(iLookAhead=0; iLookAhead<
YYNTOKEN; iLookAhead++){
1908 if( yycoverage[stateno][iLookAhead]==0 ) nMissed++;
1910 fprintf(out,
"State %d lookahead %s %s\n", stateno,
1911 yyTokenName[iLookAhead],
1912 yycoverage[stateno][iLookAhead] ?
"ok" :
"missed");
1929 int stateno = pParser->
yystack.back().stateno;
1933 #if defined(YYCOVERAGE)
1934 yycoverage[stateno][iLookAhead] = 1;
1946 if( iLookAhead<
sizeof(yyFallback)/
sizeof(yyFallback[0])
1947 && (iFallback = yyFallback[iLookAhead])!=0 ){
1949 "FALLBACK " << ParseTokenName(iLookAhead) <<
" => " <<
1950 ParseTokenName(iFallback));
1951 Assert( yyFallback[iFallback]==0 );
1952 iLookAhead = iFallback;
1958 int j = i - iLookAhead + YYWILDCARD;
1969 "WILDCARD " << ParseTokenName(iLookAhead) <<
" => " <<
1970 ParseTokenName(YYWILDCARD));
1991 #ifdef YYERRORSYMBOL
2001 #ifdef YYERRORSYMBOL
2018 static void yyStackOverflow(
yyParser *yypParser){
2023 fprintf(yyTraceFILE,
"%sStack Overflow!\n",yyTracePrompt);
2038 #ifdef XAPIAN_DEBUG_LOG
2041 LOGLINE(QUERYPARSER, zTag <<
" '" <<
2042 yyTokenName[yypParser->
yystack.back().major] <<
2043 "', go to state " << yyNewState);
2045 LOGLINE(QUERYPARSER, zTag <<
" '" <<
2046 yyTokenName[yypParser->
yystack.back().major] <<
2051 # define yyTraceShift(X,Y,Z)
2067 #ifdef YYTRACKMAXSTACKDEPTH
2068 if( (
int)(yypParser->
yystack.size()>yypParser->yyhwm ){
2070 Assert( yypParser->yyhwm == (int)(yypParser->yystack.size() );
2079 static const struct {
2155 unsigned int yyruleno,
2165 (void)yyLookaheadToken;
2166 yymsp = &yypParser->
yystack.back();
2168 #ifdef XAPIAN_DEBUG_LOG
2172 LOGLINE(QUERYPARSER,
"Reduce " << yyruleno <<
" [" <<
2173 ParseRuleName(yyruleno) <<
"], go to state " <<
2174 yymsp[yysize].stateno);
2176 LOGLINE(QUERYPARSER,
"Reduce " << yyruleno <<
" [" <<
2177 ParseRuleName(yyruleno) <<
"].");
2190 yymsp = &(yypParser->
yystack.back()) - 1;
2192 #ifdef YYTRACKMAXSTACKDEPTH
2193 if( (
int)(yypParser->yytos - yypParser->
yystack)>yypParser->yyhwm ){
2195 Assert( yypParser->yyhwm == (
int)(yypParser->yytos - yypParser->
yystack));
2199 if( yypParser->yytos>=yypParser->yystackEnd ){
2200 yyStackOverflow(yypParser);
2204 if( yypParser->yytos>=&yypParser->
yystack[yypParser->yystksz-1] ){
2205 if( yyGrowStack(yypParser) ){
2206 yyStackOverflow(yypParser);
2209 yymsp = yypParser->yytos;
2227 #line 1867 "queryparser/queryparser.lemony"
2230 if (yymsp[0].minor.yy39) {
2234 state->query =
Query();
2237 #line 2238 "queryparser/queryparser_internal.cc"
2240 #line 1877 "queryparser/queryparser.lemony"
2243 state->query =
Query();
2245 #line 2246 "queryparser/queryparser_internal.cc"
2248 #line 1889 "queryparser/queryparser.lemony"
2254 #line 2255 "queryparser/queryparser_internal.cc"
2258 #line 1895 "queryparser/queryparser.lemony"
2261 if (!yymsp[-2].minor.yy39 && (state->flags & QueryParser::FLAG_PURE_NOT)) {
2268 #line 2269 "queryparser/queryparser_internal.cc"
2272 #line 1905 "queryparser/queryparser.lemony"
2278 #line 2279 "queryparser/queryparser_internal.cc"
2283 #line 1911 "queryparser/queryparser.lemony"
2289 #line 2290 "queryparser/queryparser_internal.cc"
2294 #line 1917 "queryparser/queryparser.lemony"
2300 #line 2301 "queryparser/queryparser_internal.cc"
2304 #line 1923 "queryparser/queryparser.lemony"
2310 #line 2311 "queryparser/queryparser_internal.cc"
2314 #line 1936 "queryparser/queryparser.lemony"
2321 #line 2322 "queryparser/queryparser_internal.cc"
2324 #line 1948 "queryparser/queryparser.lemony"
2329 if (yymsp[0].minor.yy40->love) {
2330 if (yymsp[0].minor.yy40->love->empty()) {
2332 delete yylhsminor.
yy39;
2334 }
else if (yylhsminor.
yy39) {
2343 if (!yymsp[0].minor.yy40->filter.empty()) {
2344 if (yylhsminor.
yy39) {
2348 yylhsminor.
yy39 =
new Query(Query::OP_SCALE_WEIGHT, yymsp[0].minor.yy40->merge_filters(), 0.0);
2353 if (!yylhsminor.
yy39) {
2362 #line 2363 "queryparser/queryparser_internal.cc"
2366 #line 1996 "queryparser/queryparser.lemony"
2373 #line 2374 "queryparser/queryparser_internal.cc"
2376 #line 2003 "queryparser/queryparser.lemony"
2382 #line 2383 "queryparser/queryparser_internal.cc"
2385 #line 2009 "queryparser/queryparser.lemony"
2388 if (yymsp[0].minor.yy39) {
2402 #line 2403 "queryparser/queryparser_internal.cc"
2405 #line 2026 "queryparser/queryparser.lemony"
2408 if (yymsp[0].minor.yy39)
add_to_query(yymsp[-1].minor.yy40->query, state->default_op(), yymsp[0].
minor.
yy39);
2410 #line 2411 "queryparser/queryparser_internal.cc"
2414 #line 2031 "queryparser/queryparser.lemony"
2417 if (state->default_op() == Query::OP_AND) {
2423 #line 2424 "queryparser/queryparser_internal.cc"
2427 #line 2040 "queryparser/queryparser.lemony"
2429 if (state->default_op() == Query::OP_AND) {
2438 #line 2439 "queryparser/queryparser_internal.cc"
2443 #line 2051 "queryparser/queryparser.lemony"
2448 #line 2449 "queryparser/queryparser_internal.cc"
2452 #line 2056 "queryparser/queryparser.lemony"
2456 #line 2457 "queryparser/queryparser_internal.cc"
2461 #line 2060 "queryparser/queryparser.lemony"
2467 #line 2468 "queryparser/queryparser_internal.cc"
2471 #line 2066 "queryparser/queryparser.lemony"
2476 #line 2477 "queryparser/queryparser_internal.cc"
2480 #line 2071 "queryparser/queryparser.lemony"
2486 #line 2487 "queryparser/queryparser_internal.cc"
2490 #line 2077 "queryparser/queryparser.lemony"
2495 #line 2496 "queryparser/queryparser_internal.cc"
2499 #line 2082 "queryparser/queryparser.lemony"
2506 #line 2507 "queryparser/queryparser_internal.cc"
2510 #line 2089 "queryparser/queryparser.lemony"
2515 q |= yymsp[0].
minor.
yy0->get_query();
2518 #line 2519 "queryparser/queryparser_internal.cc"
2522 #line 2104 "queryparser/queryparser.lemony"
2526 #line 2527 "queryparser/queryparser_internal.cc"
2529 #line 2117 "queryparser/queryparser.lemony"
2531 if (state->is_stopword(yymsp[0].
minor.
yy0)) {
2532 yylhsminor.
yy39 = NULL;
2533 state->add_to_stoplist(yymsp[0].minor.yy0);
2535 yylhsminor.
yy39 =
new Query(yymsp[0].minor.yy0->get_query_with_auto_synonyms());
2539 #line 2540 "queryparser/queryparser_internal.cc"
2543 #line 2134 "queryparser/queryparser.lemony"
2545 yylhsminor.
yy39 =
new Query(yymsp[0].minor.yy0->get_query_with_auto_synonyms());
2548 #line 2549 "queryparser/queryparser_internal.cc"
2552 #line 2149 "queryparser/queryparser.lemony"
2554 #line 2555 "queryparser/queryparser_internal.cc"
2557 #line 2152 "queryparser/queryparser.lemony"
2559 #line 2560 "queryparser/queryparser_internal.cc"
2563 #line 2155 "queryparser/queryparser.lemony"
2565 #line 2566 "queryparser/queryparser_internal.cc"
2570 #line 2158 "queryparser/queryparser.lemony"
2572 #line 2573 "queryparser/queryparser_internal.cc"
2575 #line 2161 "queryparser/queryparser.lemony"
2577 #line 2578 "queryparser/queryparser_internal.cc"
2580 #line 2164 "queryparser/queryparser.lemony"
2582 #line 2583 "queryparser/queryparser_internal.cc"
2585 #line 2167 "queryparser/queryparser.lemony"
2587 #line 2588 "queryparser/queryparser_internal.cc"
2591 #line 2170 "queryparser/queryparser.lemony"
2593 #line 2594 "queryparser/queryparser_internal.cc"
2599 #line 2172 "queryparser/queryparser.lemony"
2601 yymsp[-1].
minor.
yy39 =
new Query(yymsp[0].minor.yy0->get_query_with_synonyms());
2604 #line 2605 "queryparser/queryparser_internal.cc"
2608 #line 2177 "queryparser/queryparser.lemony"
2612 #line 2613 "queryparser/queryparser_internal.cc"
2615 #line 2187 "queryparser/queryparser.lemony"
2620 #line 2621 "queryparser/queryparser_internal.cc"
2624 #line 2192 "queryparser/queryparser.lemony"
2627 yymsp[0].
minor.
yy0->as_positional_unbroken(yylhsminor.
yy32);
2629 #line 2630 "queryparser/queryparser_internal.cc"
2634 #line 2197 "queryparser/queryparser.lemony"
2638 #line 2639 "queryparser/queryparser_internal.cc"
2641 #line 2201 "queryparser/queryparser.lemony"
2643 yymsp[0].
minor.
yy0->as_positional_unbroken(yymsp[-1].minor.yy32);
2645 #line 2646 "queryparser/queryparser_internal.cc"
2648 #line 2212 "queryparser/queryparser.lemony"
2654 #line 2655 "queryparser/queryparser_internal.cc"
2658 #line 2228 "queryparser/queryparser.lemony"
2662 #line 2663 "queryparser/queryparser_internal.cc"
2665 #line 2232 "queryparser/queryparser.lemony"
2669 #line 2670 "queryparser/queryparser_internal.cc"
2672 #line 2236 "queryparser/queryparser.lemony"
2676 #line 2677 "queryparser/queryparser_internal.cc"
2681 #line 2246 "queryparser/queryparser.lemony"
2686 if (yymsp[-1].minor.yy0) {
2691 #line 2692 "queryparser/queryparser_internal.cc"
2696 #line 2256 "queryparser/queryparser.lemony"
2699 if (yymsp[-1].minor.yy0) {
2704 #line 2705 "queryparser/queryparser_internal.cc"
2740 #ifndef YYNOERRORRECOVERY
2745 LOGLINE(QUERYPARSER,
"Fail!");
2750 #line 1814 "queryparser/queryparser.lemony"
2753 if (!state->error) state->error =
"parse error";
2754 #line 2755 "queryparser/queryparser_internal.cc"
2771 #define TOKEN yyminor
2773 #line 1819 "queryparser/queryparser.lemony"
2776 #line 2777 "queryparser/queryparser_internal.cc"
2788 LOGLINE(QUERYPARSER,
"Accept!");
2789 #ifndef YYNOERRORRECOVERY
2828 #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
2831 #ifdef YYERRORSYMBOL
2835 #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
2836 yyendofinput = (yymajor==0);
2840 #ifdef XAPIAN_DEBUG_LOG
2842 int stateno = yypParser->
yystack.back().stateno;
2844 LOGLINE(QUERYPARSER,
"Input '" << ParseTokenName(yymajor) <<
2845 "'," << (yyminor ? yyminor->name :
"<<null>>") <<
2846 "in state " << stateno);
2848 LOGLINE(QUERYPARSER,
"Input '" << ParseTokenName(yymajor) <<
2849 "'," << (yyminor ? yyminor->name :
"<<null>>") <<
2860 yy_shift(yypParser,yyact,yymajor,yyminor);
2861 #ifndef YYNOERRORRECOVERY
2866 yypParser->
yystack.pop_back();
2871 yyminorunion.
yy0 = yyminor;
2872 #ifdef YYERRORSYMBOL
2875 LOGLINE(QUERYPARSER,
"Syntax Error!");
2876 #ifdef YYERRORSYMBOL
2899 yymx = yypParser->
yystack.back().major;
2900 if( yymx==YYERRORSYMBOL || yyerrorhit ){
2901 LOGLINE(QUERYPARSER,
"Discard input token " << ParseTokenName(yymajor));
2905 while( !yypParser->
yystack.empty()
2906 && yymx != YYERRORSYMBOL
2908 yypParser->
yystack.back().stateno,
2913 if( yypParser->
yystack.empty() || yymajor==0 ){
2916 #ifndef YYNOERRORRECOVERY
2920 }
else if( yymx!=YYERRORSYMBOL ){
2921 yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
2926 #elif defined(YYNOERRORRECOVERY)
2955 #ifndef YYNOERRORRECOVERY
2963 #ifdef XAPIAN_DEBUG_LOG
2966 LOGLINE(QUERYPARSER,
"Return. Stack=");
2967 for(i=1; i<=(int)yypParser->
yystack.size(); i++)
2975 #line 804 "queryparser/queryparser.lemony"
2979 QueryParser::Internal::parse_query(
const string &qs,
unsigned flags,
2980 const string &default_prefix)
2985 bool ranges = !rangeprocs.empty() && (qs.find(
"..") != string::npos);
2990 State state(
this, flags);
2994 int correction_offset = 0;
2995 corrected_query.resize(0);
2998 list<const FieldInfo *> prefix_stack;
3004 const FieldInfo * default_field_info = &def_pfx;
3005 if (default_prefix.empty()) {
3006 auto f = field_map.find(
string());
3007 if (f != field_map.end()) default_field_info = &(f->second);
3011 prefix_stack.push_back(default_field_info);
3016 unsigned newprev =
' ';
3019 DEFAULT, IN_QUOTES, IN_PREFIXED_QUOTES, IN_PHRASED_TERM, IN_GROUP,
3020 IN_GROUP2, EXPLICIT_SYNONYM
3022 while (it != end && !state.
error) {
3023 bool last_was_operator =
false;
3024 bool last_was_operator_needing_term =
false;
3025 if (mode == EXPLICIT_SYNONYM) mode = DEFAULT;
3028 if (it == end)
break;
3030 last_was_operator_needing_term =
false;
3031 last_was_operator =
true;
3034 just_had_operator_needing_term:
3035 last_was_operator_needing_term =
true;
3036 last_was_operator =
true;
3038 if (mode == IN_PHRASED_TERM) mode = DEFAULT;
3043 if (it == end)
break;
3047 (mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2)) {
3056 if (ch ==
'.' && *p ==
'.') {
3062 a.resize(a.size() - 1);
3066 if (!a.empty() || (p != end && *p >
' ' && *p !=
')')) {
3070 while (p != end && *p >
' ' && *p !=
')') {
3075 state.
error =
"Unknown range operation";
3076 if (a.find(
':', 1) == string::npos) {
3092 if (ch <=
' ' || ch ==
'(')
break;
3098 unsigned prev = newprev;
3099 unsigned ch = *it++;
3102 if (mode == IN_GROUP || mode == IN_GROUP2)
3109 if (mode == DEFAULT) {
3126 if (flags & QueryParser::FLAG_PHRASE) {
3127 if (ch ==
'"' && it != end && *it ==
'"') {
3134 if (mode == DEFAULT) {
3138 if (mode == IN_PREFIXED_QUOTES)
3139 prefix_stack.pop_back();
3147 if (it == end)
goto done;
3148 if (prev >
' ' && prev !=
'(') {
3159 if (mode == DEFAULT && (flags & FLAG_LOVEHATE)) {
3163 }
else if (last_was_operator) {
3168 Parse(&parser, token, NULL, &state);
3169 goto just_had_operator_needing_term;
3179 if (it == end)
goto done;
3180 if (prev >
' ' && strchr(
"()+-", prev) == NULL) {
3189 if (mode == DEFAULT && (flags & FLAG_BOOLEAN)) {
3190 prefix_stack.push_back(prefix_stack.back());
3196 if (mode == DEFAULT && (flags & FLAG_BOOLEAN)) {
3200 if (prefix_stack.size() > 1) prefix_stack.pop_back();
3207 if (it == end)
goto done;
3208 if (mode == DEFAULT && (flags & FLAG_SYNONYM)) {
3209 if (prev >
' ' && strchr(
"+-(", prev) == NULL) {
3218 mode = EXPLICIT_SYNONYM;
3219 goto just_had_operator_needing_term;
3229 size_t term_start_index = it.raw() - qs.data();
3235 if ((mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2 || mode == EXPLICIT_SYNONYM) &&
3236 !field_map.empty()) {
3239 if (p != end && *p ==
':' && ++p != end && *p >
' ' && *p !=
')') {
3244 map<string, FieldInfo>::const_iterator f;
3245 f = field_map.find(field);
3246 if (f != field_map.end()) {
3250 field_info = &(f->second);
3254 if (mode == IN_GROUP || mode == IN_GROUP2)
3260 bool fancy = (*it !=
'"');
3265 if (++it == end || *it !=
'"')
3282 while (it != end && *it >
' ' && *it !=
')')
3290 Term * token =
new Term(&state,
name, field_info, field);
3297 mode = IN_PREFIXED_QUOTES;
3302 prefix_stack.push_back(field_info);
3306 if (ch ==
'(' && (flags & FLAG_BOOLEAN)) {
3313 prefix_stack.push_back(field_info);
3341 bool needs_word_break =
false;
3342 string term = parse_term(it, end, try_word_break,
3343 needs_word_break, was_acronym);
3345 if ((mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2) &&
3346 (flags & FLAG_BOOLEAN) &&
3350 term.size() >= 2 && term.size() <= 4 &&
U_isalpha(term[0])) {
3353 if (flags & FLAG_BOOLEAN_ANY_CASE) {
3354 for (string::iterator i = op.begin(); i != op.end(); ++i) {
3358 if (op.size() == 3) {
3361 goto just_had_operator;
3365 goto just_had_operator;
3369 goto just_had_operator;
3372 if (it != end && *it ==
'/') {
3376 width = (width * 10) + (*p -
'0');
3381 goto just_had_operator;
3385 goto just_had_operator;
3388 }
else if (op.size() == 2) {
3390 Parse(&parser,
OR, NULL, &state);
3391 goto just_had_operator;
3393 }
else if (op.size() == 4) {
3395 if (it != end && *it ==
'/') {
3399 width = (width * 10) + (*p -
'0');
3404 goto just_had_operator;
3408 goto just_had_operator;
3415 if (!field_info) field_info = prefix_stack.back();
3420 string unstemmed_term(term);
3426 if (stem_term != STEM_NONE) {
3428 stem_term = STEM_NONE;
3429 }
else if (stem_term == STEM_SOME ||
3430 stem_term == STEM_SOME_FULL_POS) {
3434 stem_term = STEM_NONE;
3439 Term * term_obj =
new Term(&state, term, field_info,
3440 unstemmed_term, stem_term, term_pos++);
3442 if (needs_word_break) {
3445 if (mode == IN_GROUP || mode == IN_GROUP2)
3447 if (it == end)
break;
3451 if (mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2) {
3453 if ((flags & FLAG_WILDCARD) && *it ==
'*') {
3458 if (mode == IN_GROUP || mode == IN_GROUP2) {
3461 if (mode == IN_GROUP2)
3472 if (flags & FLAG_PARTIAL) {
3473 if (mode == IN_GROUP || mode == IN_GROUP2) {
3476 if (mode == IN_GROUP2)
3490 if ((flags & FLAG_SPELLING_CORRECTION) && !was_acronym) {
3491 const auto& prefixes = field_info->
prefixes;
3492 for (
const string& prefix : prefixes) {
3493 if (!prefix.empty())
3495 const string & suggest = db.get_spelling_suggestion(term);
3496 if (!suggest.empty()) {
3497 if (corrected_query.empty()) corrected_query = qs;
3498 size_t term_end_index = it.raw() - qs.data();
3499 size_t n = term_end_index - term_start_index;
3500 size_t pos = term_start_index + correction_offset;
3501 corrected_query.replace(pos, n, suggest);
3502 correction_offset += suggest.size();
3503 correction_offset -= n;
3509 if (mode == IN_PHRASED_TERM) {
3514 if ((mode == IN_GROUP || mode == IN_GROUP2) &&
3529 if (mode == IN_GROUP || mode == IN_GROUP2) {
3533 Parse(&parser, token, term_obj, &state);
3534 if (token ==
TERM && mode != DEFAULT)
3539 if (it == end)
break;
3549 mode = IN_PHRASED_TERM;
3550 term_start_index = it.raw() - qs.data();
3553 }
else if (mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2) {
3554 int old_mode = mode;
3556 if (!last_was_operator_needing_term &&
is_whitespace(*it)) {
3565 if (old_mode == IN_GROUP || old_mode == IN_GROUP2) {
3577 if (mode == IN_QUOTES || mode == IN_PREFIXED_QUOTES)
3581 while (prefix_stack.size() > 1) {
3583 prefix_stack.pop_back();
3585 Parse(&parser, 0, NULL, &state);
3588 errmsg = state.
error;
3592 #line 3593 "queryparser/queryparser_internal.cc"
static Xapian::Query query(Xapian::Query::op op, const string &t1=string(), const string &t2=string(), const string &t3=string(), const string &t4=string(), const string &t5=string(), const string &t6=string(), const string &t7=string(), const string &t8=string(), const string &t9=string(), const string &t10=string())
Iterator returning unigrams and bigrams.
Parser State shared between the lexer and the parser.
State(QueryParser::Internal *qpi_, unsigned flags_)
Query::op default_op() const
Xapian::termcount get_max_partial_expansion() const
Term * range(const string &a, const string &b)
Database get_database() const
int get_max_partial_type() const
void add_to_stoplist(const Term *term)
void stoplist_resize(size_t s)
int get_max_wildcard_type() const
const Stopper * get_stopper() const
Query::op effective_default_op
QueryParser::Internal * qpi
Xapian::termcount get_max_wildcard_expansion() const
void add_to_unstem(const string &term, const string &unstemmed)
size_t stoplist_size() const
string stem_term(const string &term)
bool is_stopword(const Term *term) const
bool operator!=(const SynonymIterator &o) const
bool operator==(const SynonymIterator &o) const
const Xapian::Query operator*() const
SynonymIterator(const Xapian::TermIterator &i_, Xapian::termpos pos_=0, const Xapian::Query *first_=NULL)
SynonymIterator & operator++()
const Xapian::Query * first
std::input_iterator_tag iterator_category
Xapian::termcount_diff difference_type
Xapian::Query & reference
A group of terms separated only by whitespace.
Query * as_group(State *state) const
Convert to a Xapian::Query * using default_op.
TermGroup(Term *t1, Term *t2)
static TermGroup * create(Term *t1, Term *t2)
Factory function - ensures heap allocation.
void add_term(Term *term)
Add a Term object to this TermGroup object.
bool empty_ok
Controls how to handle a group where all terms are stopwords.
void set_empty_ok()
Set the empty_ok flag.
Class used to pass information about a token from lexer to parser.
string get_grouping() const
Term(const string &name_, termpos pos_)
QueryParser::stem_strategy stem
const FieldInfo * field_info
Term(const string &name_)
string make_term(const string &prefix) const
Query get_query_with_synonyms() const
void as_positional_unbroken(Terms *terms) const
Handle text without explicit word breaks in a positional context.
Term(const string &name_, const FieldInfo *field_info_)
Term(const Xapian::Query &q, const string &grouping)
Query * as_partial_query(State *state_) const
Build a query for a term at the very end of the query string when FLAG_PARTIAL is in use.
Query * as_wildcarded_query(State *state) const
Query get_query_with_auto_synonyms() const
Query as_range_query() const
Range query.
Query * as_unbroken_query() const
Build a query for a string of words without explicit word breaks.
termpos get_termpos() const
Term(State *state_, const string &name_, const FieldInfo *field_info_, const string &unstemmed_, QueryParser::stem_strategy stem_=QueryParser::STEM_NONE, termpos pos_=0)
Some terms which form a positional sub-query.
Query * as_adj_query() const
Convert to a Xapian::Query * using OP_PHRASE to implement ADJ.
Query * as_opwindow_query(Query::op op, Xapian::termcount w_delta) const
Convert to a query using the given operator and window size.
size_t window
Window size.
static Terms * create(State *state)
Factory function - ensures heap allocation.
bool uniform_prefixes
Keep track of whether the terms added all have the same list of prefixes.
const vector< string > * prefixes
The list of prefixes of the terms added.
Query * as_near_query() const
Convert to a Xapian::Query * using OP_NEAR.
void adjust_window(size_t alternative_window)
Query * as_phrase_query() const
Convert to a Xapian::Query * using adjacent OP_PHRASE.
Query opwindow_subq(Query::op op, const vector< Query > &v, Xapian::termcount w) const
void add_positional_term(Term *term)
Add an unstemmed Term object to this Terms object.
This class is used to access a database, or a group of databases.
Xapian::TermIterator synonyms_end(const std::string &) const
Corresponding end iterator to synonyms_begin(term).
Xapian::TermIterator synonym_keys_begin(const std::string &prefix=std::string()) const
An iterator which returns all terms which have synonyms.
Xapian::TermIterator synonym_keys_end(const std::string &=std::string()) const
Corresponding end iterator to synonym_keys_begin(prefix).
Xapian::TermIterator synonyms_begin(const std::string &term) const
An iterator which returns all the synonyms for a given term.
Indicates an attempt to use a feature which is unavailable.
Base class for field processors.
Xapian::valueno get_slot() const
InvalidOperationError indicates the API was used in an invalid way.
Xapian::Internal::opt_intrusive_ptr< const Stopper > stopper
list< RangeProc > rangeprocs
Xapian::termcount max_wildcard_expansion
multimap< string, string > unstem
Xapian::termcount max_partial_expansion
Build a Xapian::Query object from a user query string.
stem_strategy
Stemming strategies, for use with set_stemming_strategy().
Class representing a query.
bool empty() const
Check if this query is Xapian::Query::MatchNothing.
@ OP_VALUE_RANGE
Match only documents where a value slot is within a given range.
@ OP_NEAR
Match only documents where all subqueries match near each other.
@ OP_PHRASE
Match only documents where all subqueries match near and in order.
@ OP_VALUE_LE
Match only documents where a value slot is <= a given value.
@ OP_SYNONYM
Match like OP_OR but weighting as if a single term.
@ LEAF_TERM
Value returned by get_type() for a term.
@ OP_VALUE_GE
Match only documents where a value slot is >= a given value.
@ OP_INVALID
Construct an invalid query.
Xapian::Internal::intrusive_ptr< Internal > internal
op get_type() const
Get the type of the top level of the query.
bool is_none() const
Return true if this is a no-op stemmer.
Abstract base class for stop-word decision functor.
Class for iterating over a list of terms.
void skip_to(const std::string &term)
Advance the iterator to term term.
UnimplementedError indicates an attempt to use an unimplemented feature.
An iterator which returns Unicode character values from a UTF-8 encoded string.
const char * raw() const
Return the raw const char* pointer for the current position.
Hierarchy of classes which Xapian can throw as exceptions.
string str(int value)
Convert int to std::string.
category get_category(int info)
void append_utf8(std::string &s, unsigned ch)
Append the UTF-8 representation of a single Unicode character to a std::string.
unsigned tolower(unsigned ch)
Convert a Unicode character to lowercase.
@ LOWERCASE_LETTER
Letter, lowercase (Ll)
@ MODIFIER_LETTER
Letter, modifier (Lm)
@ OTHER_LETTER
Letter, other (Lo)
@ DECIMAL_DIGIT_NUMBER
Number, decimal digit (Nd)
@ TITLECASE_LETTER
Letter, titlecase (Lt)
bool is_wordchar(unsigned ch)
Test if a given Unicode character is "word character".
bool is_currency(unsigned ch)
Test if a given Unicode character is a currency symbol.
bool is_whitespace(unsigned ch)
Test if a given Unicode character is a whitespace character.
The Xapian namespace contains public interfaces for the Xapian library.
XAPIAN_TERMCOUNT_BASE_TYPE termcount_diff
A signed difference between two counts of terms.
unsigned XAPIAN_TERMCOUNT_BASE_TYPE termcount
A counts of terms.
unsigned valueno
The number for a value slot in a document.
unsigned XAPIAN_TERMPOS_BASE_TYPE termpos
A term position within a document or query.
Various assertion macros.
static void yy_pop_parser_stack(yyParser *pParser)
bool is_not_whitespace(unsigned ch)
const unsigned UNICODE_IGNORE
Value representing "ignore this" when returned by check_infix() or check_infix_digit().
bool should_stem(const string &term)
#define VET_BOOL_ARGS(A, B, OP_TXT)
static const YYCODETYPE yy_lookahead[]
static unsigned int yy_find_shift_action(yyParser *pParser, YYCODETYPE iLookAhead)
static const YYACTIONTYPE yy_action[]
static void yy_syntax_error(yyParser *yypParser, int yymajor, ParseTOKENTYPE yyminor)
static const YYACTIONTYPE yy_default[]
static void add_to_query(Query *&q, Query::op op, Query *term)
bool U_isupper(unsigned ch)
#define YY_MIN_SHIFTREDUCE
static const unsigned short int yy_shift_ofst[]
bool is_not_wordchar(unsigned ch)
bool is_digit(unsigned ch)
static void yy_shift(yyParser *yypParser, int yyNewState, int yyMajor, ParseTOKENTYPE yyMinor)
unsigned check_infix_digit(unsigned ch)
bool is_suffix(unsigned ch)
static const short yy_reduce_ofst[]
static void yy_accept(yyParser *)
static int yy_find_reduce_action(int stateno, YYCODETYPE iLookAhead)
bool U_isdigit(unsigned ch)
bool is_stem_preventer(unsigned ch)
bool is_positional(Xapian::Query::op op)
static void ParseFinalize(yyParser *pParser)
bool is_phrase_generator(unsigned ch)
unsigned check_infix(unsigned ch)
#define YY_MAX_SHIFTREDUCE
#define yyTraceShift(X, Y, Z)
static const struct @13 yyRuleInfo[]
bool U_isalpha(unsigned ch)
bool prefix_needs_colon(const string &prefix, unsigned ch)
static void yy_parse_failed(yyParser *)
bool is_double_quote(unsigned ch)
static void ParseInit(yyParser *pParser)
static void Parse(yyParser *yypParser, int yymajor, ParseTOKENTYPE yyminor ParseARG_PDECL)
static void yy_reduce(yyParser *yypParser, unsigned int yyruleno, int yyLookahead, ParseTOKENTYPE yyLookaheadToken)
static void yy_destructor(yyParser *yypParser, YYCODETYPE yymajor, YYMINORTYPE *yypminor)
The non-lemon-generated parts of the QueryParser class.
static Xapian::Stem stemmer
Convert types to std::string.
Various handy helpers which std::string really should provide.
bool startswith(const std::string &s, char pfx)
Information about how to handle a field prefix in the query string.
filter_type type
The type of this field.
vector< string > prefixes
Field prefix strings.
void append_filter(const string &grouping, const Query &qnew)
Query merge_filters() const
void add_filter_range(const string &grouping, const Query &range)
void append_filter_range(const string &grouping, const Query &range)
map< string, Query > filter
void add_filter(const string &grouping, const Query &q)
ParseARG_SDECL vector< yyStackEntry > yystack
yyStackEntry(YYACTIONTYPE stateno_, YYCODETYPE major_, ParseTOKENTYPE minor_)
Unicode and UTF-8 related classes and functions.
bool is_unbroken_script(unsigned p)
void get_unbroken(Xapian::Utf8Iterator &it)
bool is_ngram_enabled()
Should we use the n-gram code?
Handle text without explicit word breaks.