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] !=
':');
172 : name(name_), stem(
QueryParser::STEM_NONE), pos(pos_) { }
173 explicit Term(
const string &name_)
174 : name(name_), stem(
QueryParser::STEM_NONE), pos(0) { }
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_) { }
187 : name(grouping), query(q) { }
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,
530 subqs_full.push_back(
Query(make_term(prefix), 1, pos));
533 Query(Query::OP_SYNONYM,
534 subqs_partial.begin(), subqs_partial.end()),
535 Query(Query::OP_SYNONYM,
536 subqs_full.begin(), subqs_full.end()));
544 vector<Query> prefix_subqs;
545 vector<Query> ngram_subqs;
546 const auto& prefixes = field_info->prefixes;
547 for (
const string& prefix : prefixes) {
549 ngram_subqs.push_back(
Query(prefix + *tk, 1, pos));
551 prefix_subqs.push_back(
Query(Query::OP_AND,
552 ngram_subqs.begin(), ngram_subqs.end()));
556 prefix_subqs.begin(), prefix_subqs.end());
575 return (ch && ch < 128 && strchr(
".-/:\\@", ch) != NULL);
581 return (ch && ch < 128 && strchr(
"(/\\@<>=*[{\"", ch) != NULL);
587 const unsigned int SHOULD_STEM_MASK =
602 if (ch ==
'\'' || ch ==
'&' || ch == 0xb7 || ch == 0x5f4 || ch == 0x2027) {
612 if (ch == 0x2019 || ch == 0x201b)
614 if (ch <= 0x200d || ch == 0x2060 || ch == 0xfeff)
636 if (ch >= 0x200b && (ch <= 0x200d || ch == 0x2060 || ch == 0xfeff))
647 QueryParser::Internal::add_prefix(
const string &field,
const string &prefix)
649 map<string, FieldInfo>::iterator p = field_map.find(field);
650 if (p == field_map.end()) {
655 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");
657 if (p->second.proc.get())
659 p->second.prefixes.push_back(prefix);
666 map<string, FieldInfo>::iterator p = field_map.find(field);
667 if (p == field_map.end()) {
672 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");
674 if (!p->second.prefixes.empty())
681 QueryParser::Internal::add_boolean_prefix(
const string &field,
682 const string &prefix,
689 if (!grouping) grouping = &field;
691 map<string, FieldInfo>::iterator p = field_map.find(field);
692 if (p == field_map.end()) {
693 field_map.insert(make_pair(field,
FieldInfo(type, prefix, *grouping)));
696 if (p->second.type != type) {
697 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");
699 if (p->second.proc.get())
701 p->second.prefixes.push_back(prefix);
706 QueryParser::Internal::add_boolean_prefix(
const string &field,
714 if (!grouping) grouping = &field;
716 map<string, FieldInfo>::iterator p = field_map.find(field);
717 if (p == field_map.end()) {
718 field_map.insert(make_pair(field,
FieldInfo(type, proc, *grouping)));
721 if (p->second.type != type) {
722 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");
724 if (!p->second.prefixes.empty())
732 bool try_word_break,
bool& needs_word_break,
743 }
while (p != end && *p ==
'.' && ++p != end &&
U_isupper(*p));
746 if (t.length() > 1) {
756 was_acronym = !term.empty();
759 const char* start = it.
raw();
761 term.assign(start, it.
raw() - start);
762 needs_word_break =
true;
766 unsigned prevch = *it;
768 while (++it != end) {
778 unsigned nextch = *p;
792 string suff_term = term;
796 if (suff_term.size() - term.size() == 3) {
802 if (!suff_term.empty() && (p == end || !
is_wordchar(*p))) {
807 bool use_suff_term =
false;
809 if (db.term_exists(lc)) {
810 use_suff_term =
true;
813 if (!db.term_exists(lc)) use_suff_term =
true;
825 #line 1416 "queryparser/queryparser.lemony" 849 filter[grouping] = q;
853 auto it = filter.find(grouping);
854 if (it == filter.end()) {
855 filter.insert(make_pair(grouping, qnew));
857 Query & q = it->second;
860 bool exclusive = !grouping.
empty();
870 filter[grouping] = range;
874 Query & q = filter[grouping];
879 auto i = filter.begin();
880 Assert(i != filter.end());
882 while (++i != filter.end()) {
912 for (
auto&& t : terms) {
919 terms.push_back(term);
938 subqs.reserve(terms.size());
939 if (state->
flags & QueryParser::FLAG_AUTO_MULTIWORD_SYNONYMS) {
944 vector<Term*>::size_type begin = 0;
945 vector<Term*>::size_type i = begin;
946 while (terms.size() - i > 0) {
947 size_t longest_match = 0;
950 vector<Term*>::size_type longest_match_end = 0;
951 if (terms.size() - i >= 2) {
953 key = terms[i]->name;
955 key += terms[i + 1]->name;
958 if (synkey != synend) {
959 longest_match = key.size();
960 longest_match_end = i + 2;
961 for (
auto j = i + 2; j < terms.size(); ++j) {
963 key += terms[j]->name;
965 if (synkey == synend)
967 const string& found = *synkey;
970 if (found.size() == key.size()) {
971 longest_match = key.size();
972 longest_match_end = j + 1;
977 if (longest_match == 0) {
979 if (stopper && (*stopper)(terms[i]->
name)) {
982 if (default_op_is_positional)
983 terms[i]->need_positions();
984 subqs.push_back(terms[i]->get_query_with_auto_synonyms());
989 i = longest_match_end;
990 key.resize(longest_match);
992 vector<Query> subqs2;
993 for (
auto j = begin; j != i; ++j) {
994 if (stopper && (*stopper)(terms[j]->
name)) {
997 if (default_op_is_positional)
998 terms[i]->need_positions();
999 subqs2.push_back(terms[j]->get_query());
1002 Query q_original_terms;
1003 if (default_op_is_positional) {
1004 q_original_terms =
Query(default_op,
1005 subqs2.begin(), subqs2.end(),
1008 q_original_terms =
Query(default_op,
1009 subqs2.begin(), subqs2.end());
1015 Query q(Query::OP_SYNONYM,
1023 vector<Term*>::const_iterator i;
1024 for (i = terms.begin(); i != terms.end(); ++i) {
1025 if (stopper && (*stopper)((*i)->name)) {
1028 if (default_op_is_positional)
1029 (*i)->need_positions();
1030 subqs.push_back((*i)->get_query_with_auto_synonyms());
1035 if (!empty_ok && stopper && subqs.empty() &&
1045 if (!subqs.empty()) {
1046 if (default_op_is_positional) {
1047 q =
new Query(default_op, subqs.begin(), subqs.end(),
1050 q =
new Query(default_op, subqs.begin(), subqs.end());
1085 const vector<Query>& v,
1087 if (op == Query::OP_AND) {
1088 return Query(op, v.begin(), v.end());
1090 return Query(op, v.begin(), v.end(), w);
1095 if (window ==
size_t(-1)) op = Query::OP_AND;
1097 size_t n_terms = terms.size();
1099 if (uniform_prefixes) {
1101 for (
auto&& prefix : *prefixes) {
1102 vector<Query> subqs;
1103 subqs.reserve(n_terms);
1104 for (
Term* t : terms) {
1105 subqs.push_back(
Query(t->make_term(prefix), 1, t->pos));
1107 add_to_query(q, Query::OP_OR, opwindow_subq(op, subqs, w));
1111 vector<Query> subqs;
1112 subqs.reserve(n_terms);
1113 for (
Term* t : terms) {
1114 subqs.push_back(t->get_query());
1116 q =
new Query(opwindow_subq(op, subqs, w));
1124 : window(no_pos ? size_t(-1) : 0),
1125 uniform_prefixes(
true),
1131 return new Terms(state->
flags & QueryParser::FLAG_NO_POSITIONS);
1135 for (
auto&& t : terms) {
1143 if (terms.empty()) {
1144 prefixes = &term_prefixes;
1145 }
else if (uniform_prefixes && prefixes != &term_prefixes) {
1146 if (*prefixes != term_prefixes) {
1148 uniform_prefixes =
false;
1152 terms.push_back(term);
1156 if (alternative_window > window) window = alternative_window;
1161 return as_opwindow_query(Query::OP_PHRASE, 0);
1171 return as_opwindow_query(Query::OP_NEAR, w - 1);
1181 return as_opwindow_query(Query::OP_PHRASE, w - 1);
1192 Term * c =
new Term(state, t, field_info, unstemmed, stem, pos);
1203 #define VET_BOOL_ARGS(A, B, OP_TXT) \ 1206 state->error = "Syntax: <expression> " OP_TXT " <expression>";\ 1207 yy_parse_failed(yypParser);\ 1212 #line 1213 "queryparser/queryparser_internal.cc" 1270 # define INTERFACE 1 1273 #define YYCODETYPE unsigned char 1275 #define YYACTIONTYPE unsigned char 1276 #define ParseTOKENTYPE Term * 1286 #ifndef YYSTACKDEPTH 1287 #define YYSTACKDEPTH 100 1289 #define ParseARG_SDECL State * state; 1290 #define ParseARG_PDECL ,State * state 1291 #define ParseARG_FETCH State * state = yypParser->state 1292 #define ParseARG_STORE yypParser->state = state 1296 #define YY_MAX_SHIFT 34 1297 #define YY_MIN_SHIFTREDUCE 77 1298 #define YY_MAX_SHIFTREDUCE 132 1299 #define YY_ERROR_ACTION 133 1300 #define YY_ACCEPT_ACTION 134 1301 #define YY_NO_ACTION 135 1302 #define YY_MIN_REDUCE 136 1303 #define YY_MAX_REDUCE 191 1315 # define yytestcase(X) 1369 #define YY_ACTTAB_COUNT (326) 1371 134, 34, 34, 20, 8, 34, 18, 13, 16, 27,
1372 31, 23, 30, 28, 3, 21, 112, 10, 9, 2,
1373 25, 15, 111, 114, 104, 105, 97, 87, 14, 4,
1374 137, 113, 126, 115, 12, 11, 1, 7, 10, 9,
1375 124, 25, 15, 98, 88, 104, 105, 97, 87, 14,
1376 4, 29, 113, 138, 138, 138, 8, 138, 18, 13,
1377 16, 119, 31, 23, 30, 28, 141, 141, 141, 8,
1378 141, 18, 13, 16, 125, 31, 23, 30, 28, 140,
1379 140, 140, 8, 140, 18, 13, 16, 123, 31, 23,
1380 30, 28, 26, 26, 20, 8, 26, 18, 13, 16,
1381 136, 31, 23, 30, 28, 24, 24, 24, 8, 24,
1382 18, 13, 16, 135, 31, 23, 30, 28, 22, 22,
1383 22, 8, 22, 18, 13, 16, 135, 31, 23, 30,
1384 28, 139, 139, 139, 8, 139, 18, 13, 16, 121,
1385 31, 23, 30, 28, 10, 9, 135, 25, 15, 122,
1386 135, 104, 105, 97, 87, 14, 4, 135, 113, 135,
1387 189, 189, 135, 25, 19, 135, 135, 104, 105, 189,
1388 189, 14, 4, 162, 113, 162, 162, 162, 162, 33,
1389 32, 33, 32, 116, 135, 135, 120, 118, 120, 118,
1390 106, 25, 17, 117, 162, 104, 105, 95, 135, 14,
1391 4, 135, 113, 25, 17, 135, 135, 104, 105, 99,
1392 135, 14, 4, 135, 113, 25, 17, 135, 135, 104,
1393 105, 96, 135, 14, 4, 135, 113, 25, 17, 135,
1394 135, 104, 105, 100, 135, 14, 4, 135, 113, 25,
1395 19, 135, 135, 104, 105, 135, 135, 14, 4, 135,
1396 113, 135, 149, 149, 135, 31, 23, 30, 28, 152,
1397 135, 135, 152, 135, 31, 23, 30, 28, 135, 150,
1398 135, 135, 150, 135, 31, 23, 30, 28, 153, 135,
1399 135, 153, 135, 31, 23, 30, 28, 151, 135, 135,
1400 151, 135, 31, 23, 30, 28, 135, 148, 148, 135,
1401 31, 23, 30, 28, 191, 135, 191, 191, 191, 191,
1402 6, 5, 1, 7, 5, 1, 7, 135, 135, 135,
1403 135, 135, 135, 135, 135, 191,
1406 25, 26, 27, 28, 29, 30, 31, 32, 33, 7,
1407 35, 36, 37, 38, 5, 34, 12, 8, 9, 10,
1408 11, 12, 21, 12, 15, 16, 17, 18, 19, 20,
1409 0, 22, 12, 22, 8, 9, 4, 5, 8, 9,
1410 12, 11, 12, 17, 18, 15, 16, 17, 18, 19,
1411 20, 6, 22, 26, 27, 28, 29, 30, 31, 32,
1412 33, 14, 35, 36, 37, 38, 26, 27, 28, 29,
1413 30, 31, 32, 33, 12, 35, 36, 37, 38, 26,
1414 27, 28, 29, 30, 31, 32, 33, 12, 35, 36,
1415 37, 38, 26, 27, 28, 29, 30, 31, 32, 33,
1416 0, 35, 36, 37, 38, 26, 27, 28, 29, 30,
1417 31, 32, 33, 39, 35, 36, 37, 38, 26, 27,
1418 28, 29, 30, 31, 32, 33, 39, 35, 36, 37,
1419 38, 26, 27, 28, 29, 30, 31, 32, 33, 13,
1420 35, 36, 37, 38, 8, 9, 39, 11, 12, 23,
1421 39, 15, 16, 17, 18, 19, 20, 39, 22, 39,
1422 8, 9, 39, 11, 12, 39, 39, 15, 16, 17,
1423 18, 19, 20, 0, 22, 2, 3, 4, 5, 6,
1424 7, 6, 7, 12, 39, 39, 13, 14, 13, 14,
1425 19, 11, 12, 22, 21, 15, 16, 17, 39, 19,
1426 20, 39, 22, 11, 12, 39, 39, 15, 16, 17,
1427 39, 19, 20, 39, 22, 11, 12, 39, 39, 15,
1428 16, 17, 39, 19, 20, 39, 22, 11, 12, 39,
1429 39, 15, 16, 17, 39, 19, 20, 39, 22, 11,
1430 12, 39, 39, 15, 16, 39, 39, 19, 20, 39,
1431 22, 39, 32, 33, 39, 35, 36, 37, 38, 30,
1432 39, 39, 33, 39, 35, 36, 37, 38, 39, 30,
1433 39, 39, 33, 39, 35, 36, 37, 38, 30, 39,
1434 39, 33, 39, 35, 36, 37, 38, 30, 39, 39,
1435 33, 39, 35, 36, 37, 38, 39, 32, 33, 39,
1436 35, 36, 37, 38, 0, 39, 2, 3, 4, 5,
1437 2, 3, 4, 5, 3, 4, 5, 39, 39, 39,
1438 39, 39, 39, 39, 39, 21, 39, 39, 39, 39,
1439 39, 39, 39, 39, 39, 39, 39, 39, 39,
1441 #define YY_SHIFT_COUNT (34) 1442 #define YY_SHIFT_MIN (0) 1443 #define YY_SHIFT_MAX (311) 1445 30, 9, 136, 136, 136, 136, 136, 136, 152, 180,
1446 192, 204, 216, 228, 11, 173, 304, 175, 26, 175,
1447 308, 171, 311, 126, 32, 4, 1, 20, 2, 28,
1448 45, 47, 62, 75, 100,
1450 #define YY_REDUCE_COUNT (14) 1451 #define YY_REDUCE_MIN (-25) 1452 #define YY_REDUCE_MAX (265) 1454 -25, 27, 40, 53, 66, 79, 92, 105, 220, 229,
1455 239, 248, 257, 265, -19,
1458 144, 144, 144, 144, 144, 144, 144, 144, 145, 133,
1459 133, 133, 133, 160, 133, 161, 190, 162, 133, 161,
1460 133, 133, 142, 167, 143, 133, 187, 133, 169, 133,
1461 168, 166, 133, 133, 187,
1523 #ifdef YYTRACKMAXSTACKDEPTH 1526 #ifndef YYNOERRORRECOVERY 1543 #if defined(YYCOVERAGE) || defined(XAPIAN_DEBUG_LOG) 1546 static const char *
const yyTokenName[] = {
1590 static const char *
const yyRuleName[] = {
1593 "expr ::= bool_arg AND bool_arg",
1594 "expr ::= bool_arg NOT bool_arg",
1595 "expr ::= bool_arg AND NOT bool_arg",
1596 "expr ::= bool_arg AND HATE_AFTER_AND bool_arg",
1597 "expr ::= bool_arg OR bool_arg",
1598 "expr ::= bool_arg XOR bool_arg",
1600 "prob_expr ::= prob",
1602 "prob ::= stop_prob RANGE",
1603 "prob ::= stop_term stop_term",
1604 "prob ::= prob stop_term",
1605 "prob ::= LOVE term",
1606 "prob ::= stop_prob LOVE term",
1607 "prob ::= HATE term",
1608 "prob ::= stop_prob HATE term",
1609 "prob ::= HATE BOOLEAN_FILTER",
1610 "prob ::= stop_prob HATE BOOLEAN_FILTER",
1611 "prob ::= BOOLEAN_FILTER",
1612 "prob ::= stop_prob BOOLEAN_FILTER",
1613 "prob ::= LOVE BOOLEAN_FILTER",
1614 "prob ::= stop_prob LOVE BOOLEAN_FILTER",
1615 "stop_prob ::= stop_term",
1616 "stop_term ::= TERM",
1618 "compound_term ::= WILD_TERM",
1619 "compound_term ::= PARTIAL_TERM",
1620 "compound_term ::= QUOTE phrase QUOTE",
1621 "compound_term ::= phrased_term",
1622 "compound_term ::= group",
1623 "compound_term ::= near_expr",
1624 "compound_term ::= adj_expr",
1625 "compound_term ::= BRA expr KET",
1626 "compound_term ::= SYNONYM TERM",
1627 "compound_term ::= UNBROKEN_WORDS",
1629 "phrase ::= UNBROKEN_WORDS",
1630 "phrase ::= phrase TERM",
1631 "phrase ::= phrase UNBROKEN_WORDS",
1632 "phrased_term ::= TERM PHR_TERM",
1633 "phrased_term ::= phrased_term PHR_TERM",
1634 "group ::= TERM GROUP_TERM",
1635 "group ::= group GROUP_TERM",
1636 "group ::= group EMPTY_GROUP_OK",
1637 "near_expr ::= TERM NEAR TERM",
1638 "near_expr ::= near_expr NEAR TERM",
1639 "adj_expr ::= TERM ADJ TERM",
1640 "adj_expr ::= adj_expr ADJ TERM",
1641 "expr ::= prob_expr",
1642 "bool_arg ::= expr",
1643 "prob_expr ::= term",
1644 "stop_prob ::= prob",
1645 "stop_term ::= compound_term",
1646 "term ::= compound_term",
1653 static const char *ParseTokenName(
int tokenType){
1654 if( tokenType>=0 && tokenType<(
int)(
sizeof(yyTokenName)/
sizeof(yyTokenName[0])) ){
1655 return yyTokenName[tokenType];
1664 static const char *ParseRuleName(
int ruleNum){
1665 if( ruleNum>=0 && ruleNum<(
int)(
sizeof(yyRuleName)/
sizeof(yyRuleName[0])) ){
1666 return yyRuleName[ruleNum];
1677 #ifndef YYMALLOCARGTYPE 1678 # define YYMALLOCARGTYPE size_t 1685 #ifdef YYTRACKMAXSTACKDEPTH 1690 pParser->yytos = NULL;
1692 pParser->yystksz = 0;
1693 if( yyGrowStack(pParser) ){
1694 pParser->
yystack = &pParser->yystk0;
1695 pParser->yystksz = 1;
1699 #ifndef YYNOERRORRECOVERY 1703 pParser->yytos = pParser->
yystack;
1704 pParser->
yystack[0].stateno = 0;
1705 pParser->
yystack[0].major = 0;
1714 #ifndef Parse_ENGINEALWAYSONSTACK 1781 #line 1805 "queryparser/queryparser.lemony" 1782 delete (yypminor->
yy0);
1783 #line 1784 "queryparser/queryparser_internal.cc" 1793 #line 1880 "queryparser/queryparser.lemony" 1794 delete (yypminor->
yy39);
1795 #line 1796 "queryparser/queryparser_internal.cc" 1801 #line 1989 "queryparser/queryparser.lemony" 1802 delete (yypminor->
yy40);
1803 #line 1804 "queryparser/queryparser_internal.cc" 1811 #line 2180 "queryparser/queryparser.lemony" 1812 delete (yypminor->
yy32);
1813 #line 1814 "queryparser/queryparser_internal.cc" 1818 #line 2221 "queryparser/queryparser.lemony" 1819 delete (yypminor->
yy14);
1820 #line 1821 "queryparser/queryparser_internal.cc" 1839 LOGLINE(QUERYPARSER,
"Popping " << ParseTokenName(yytos->major));
1852 #ifndef Parse_ENGINEALWAYSONSTACK 1872 #ifdef YYTRACKMAXSTACKDEPTH 1873 int ParseStackPeak(
yyParser *pParser){
1874 return pParser->yyhwm;
1883 #if defined(YYCOVERAGE) 1895 #if defined(YYCOVERAGE) 1896 int ParseCoverage(FILE *out){
1897 int stateno, iLookAhead, i;
1899 for(stateno=0; stateno<
YYNSTATE; stateno++){
1901 for(iLookAhead=0; iLookAhead<
YYNTOKEN; iLookAhead++){
1903 if( yycoverage[stateno][iLookAhead]==0 ) nMissed++;
1905 fprintf(out,
"State %d lookahead %s %s\n", stateno,
1906 yyTokenName[iLookAhead],
1907 yycoverage[stateno][iLookAhead] ?
"ok" :
"missed");
1924 int stateno = pParser->
yystack.back().stateno;
1928 #if defined(YYCOVERAGE) 1929 yycoverage[stateno][iLookAhead] = 1;
1941 if( iLookAhead<
sizeof(yyFallback)/
sizeof(yyFallback[0])
1942 && (iFallback = yyFallback[iLookAhead])!=0 ){
1944 "FALLBACK " << ParseTokenName(iLookAhead) <<
" => " <<
1945 ParseTokenName(iFallback));
1946 Assert( yyFallback[iFallback]==0 );
1947 iLookAhead = iFallback;
1953 int j = i - iLookAhead + YYWILDCARD;
1964 "WILDCARD " << ParseTokenName(iLookAhead) <<
" => " <<
1965 ParseTokenName(YYWILDCARD));
1986 #ifdef YYERRORSYMBOL 1996 #ifdef YYERRORSYMBOL 2013 static void yyStackOverflow(
yyParser *yypParser){
2018 fprintf(yyTraceFILE,
"%sStack Overflow!\n",yyTracePrompt);
2033 #ifdef XAPIAN_DEBUG_LOG 2036 LOGLINE(QUERYPARSER, zTag <<
" '" <<
2037 yyTokenName[yypParser->
yystack.back().major] <<
2038 "', go to state " << yyNewState);
2040 LOGLINE(QUERYPARSER, zTag <<
" '" <<
2041 yyTokenName[yypParser->
yystack.back().major] <<
2046 # define yyTraceShift(X,Y,Z) 2062 #ifdef YYTRACKMAXSTACKDEPTH 2063 if( (
int)(yypParser->
yystack.size()>yypParser->yyhwm ){
2065 Assert( yypParser->yyhwm == (
int)(yypParser->
yystack.size() );
2074 static const struct {
2150 unsigned int yyruleno,
2160 (void)yyLookaheadToken;
2161 yymsp = &yypParser->
yystack.back();
2163 #ifdef XAPIAN_DEBUG_LOG 2167 LOGLINE(QUERYPARSER,
"Reduce " << yyruleno <<
" [" <<
2168 ParseRuleName(yyruleno) <<
"], go to state " <<
2169 yymsp[yysize].stateno);
2171 LOGLINE(QUERYPARSER,
"Reduce " << yyruleno <<
" [" <<
2172 ParseRuleName(yyruleno) <<
"].");
2185 yymsp = &(yypParser->
yystack.back()) - 1;
2187 #ifdef YYTRACKMAXSTACKDEPTH 2188 if( (
int)(yypParser->yytos - yypParser->
yystack)>yypParser->yyhwm ){
2190 Assert( yypParser->yyhwm == (
int)(yypParser->yytos - yypParser->
yystack));
2194 if( yypParser->yytos>=yypParser->yystackEnd ){
2195 yyStackOverflow(yypParser);
2199 if( yypParser->yytos>=&yypParser->
yystack[yypParser->yystksz-1] ){
2200 if( yyGrowStack(yypParser) ){
2201 yyStackOverflow(yypParser);
2204 yymsp = yypParser->yytos;
2222 #line 1862 "queryparser/queryparser.lemony" 2225 if (yymsp[0].minor.yy39) {
2229 state->query =
Query();
2232 #line 2233 "queryparser/queryparser_internal.cc" 2235 #line 1872 "queryparser/queryparser.lemony" 2238 state->query =
Query();
2240 #line 2241 "queryparser/queryparser_internal.cc" 2243 #line 1884 "queryparser/queryparser.lemony" 2249 #line 2250 "queryparser/queryparser_internal.cc" 2253 #line 1890 "queryparser/queryparser.lemony" 2256 if (!yymsp[-2].minor.yy39 && (state->flags & QueryParser::FLAG_PURE_NOT)) {
2263 #line 2264 "queryparser/queryparser_internal.cc" 2267 #line 1900 "queryparser/queryparser.lemony" 2273 #line 2274 "queryparser/queryparser_internal.cc" 2278 #line 1906 "queryparser/queryparser.lemony" 2284 #line 2285 "queryparser/queryparser_internal.cc" 2289 #line 1912 "queryparser/queryparser.lemony" 2295 #line 2296 "queryparser/queryparser_internal.cc" 2299 #line 1918 "queryparser/queryparser.lemony" 2305 #line 2306 "queryparser/queryparser_internal.cc" 2309 #line 1931 "queryparser/queryparser.lemony" 2316 #line 2317 "queryparser/queryparser_internal.cc" 2319 #line 1943 "queryparser/queryparser.lemony" 2324 if (yymsp[0].minor.yy40->love) {
2325 if (yymsp[0].minor.yy40->love->empty()) {
2327 delete yylhsminor.
yy39;
2329 }
else if (yylhsminor.
yy39) {
2338 if (!yymsp[0].minor.yy40->filter.empty()) {
2339 if (yylhsminor.
yy39) {
2343 yylhsminor.
yy39 =
new Query(Query::OP_SCALE_WEIGHT, yymsp[0].minor.yy40->merge_filters(), 0.0);
2348 if (!yylhsminor.
yy39) {
2357 #line 2358 "queryparser/queryparser_internal.cc" 2361 #line 1991 "queryparser/queryparser.lemony" 2368 #line 2369 "queryparser/queryparser_internal.cc" 2371 #line 1998 "queryparser/queryparser.lemony" 2377 #line 2378 "queryparser/queryparser_internal.cc" 2380 #line 2004 "queryparser/queryparser.lemony" 2383 if (yymsp[0].minor.yy39) {
2397 #line 2398 "queryparser/queryparser_internal.cc" 2400 #line 2021 "queryparser/queryparser.lemony" 2403 if (yymsp[0].minor.yy39)
add_to_query(yymsp[-1].minor.yy40->query, state->default_op(), yymsp[0].
minor.
yy39);
2405 #line 2406 "queryparser/queryparser_internal.cc" 2409 #line 2026 "queryparser/queryparser.lemony" 2412 if (state->default_op() == Query::OP_AND) {
2418 #line 2419 "queryparser/queryparser_internal.cc" 2422 #line 2035 "queryparser/queryparser.lemony" 2424 if (state->default_op() == Query::OP_AND) {
2433 #line 2434 "queryparser/queryparser_internal.cc" 2438 #line 2046 "queryparser/queryparser.lemony" 2443 #line 2444 "queryparser/queryparser_internal.cc" 2447 #line 2051 "queryparser/queryparser.lemony" 2451 #line 2452 "queryparser/queryparser_internal.cc" 2456 #line 2055 "queryparser/queryparser.lemony" 2462 #line 2463 "queryparser/queryparser_internal.cc" 2466 #line 2061 "queryparser/queryparser.lemony" 2471 #line 2472 "queryparser/queryparser_internal.cc" 2475 #line 2066 "queryparser/queryparser.lemony" 2481 #line 2482 "queryparser/queryparser_internal.cc" 2485 #line 2072 "queryparser/queryparser.lemony" 2490 #line 2491 "queryparser/queryparser_internal.cc" 2494 #line 2077 "queryparser/queryparser.lemony" 2501 #line 2502 "queryparser/queryparser_internal.cc" 2505 #line 2084 "queryparser/queryparser.lemony" 2510 q |= yymsp[0].
minor.
yy0->get_query();
2513 #line 2514 "queryparser/queryparser_internal.cc" 2517 #line 2099 "queryparser/queryparser.lemony" 2521 #line 2522 "queryparser/queryparser_internal.cc" 2524 #line 2112 "queryparser/queryparser.lemony" 2526 if (state->is_stopword(yymsp[0].
minor.
yy0)) {
2527 yylhsminor.
yy39 = NULL;
2528 state->add_to_stoplist(yymsp[0].minor.yy0);
2530 yylhsminor.
yy39 =
new Query(yymsp[0].minor.yy0->get_query_with_auto_synonyms());
2534 #line 2535 "queryparser/queryparser_internal.cc" 2538 #line 2129 "queryparser/queryparser.lemony" 2540 yylhsminor.
yy39 =
new Query(yymsp[0].minor.yy0->get_query_with_auto_synonyms());
2543 #line 2544 "queryparser/queryparser_internal.cc" 2547 #line 2144 "queryparser/queryparser.lemony" 2549 #line 2550 "queryparser/queryparser_internal.cc" 2552 #line 2147 "queryparser/queryparser.lemony" 2554 #line 2555 "queryparser/queryparser_internal.cc" 2558 #line 2150 "queryparser/queryparser.lemony" 2560 #line 2561 "queryparser/queryparser_internal.cc" 2565 #line 2153 "queryparser/queryparser.lemony" 2567 #line 2568 "queryparser/queryparser_internal.cc" 2570 #line 2156 "queryparser/queryparser.lemony" 2572 #line 2573 "queryparser/queryparser_internal.cc" 2575 #line 2159 "queryparser/queryparser.lemony" 2577 #line 2578 "queryparser/queryparser_internal.cc" 2580 #line 2162 "queryparser/queryparser.lemony" 2582 #line 2583 "queryparser/queryparser_internal.cc" 2586 #line 2165 "queryparser/queryparser.lemony" 2588 #line 2589 "queryparser/queryparser_internal.cc" 2594 #line 2167 "queryparser/queryparser.lemony" 2596 yymsp[-1].
minor.
yy39 =
new Query(yymsp[0].minor.yy0->get_query_with_synonyms());
2599 #line 2600 "queryparser/queryparser_internal.cc" 2603 #line 2172 "queryparser/queryparser.lemony" 2607 #line 2608 "queryparser/queryparser_internal.cc" 2610 #line 2182 "queryparser/queryparser.lemony" 2615 #line 2616 "queryparser/queryparser_internal.cc" 2619 #line 2187 "queryparser/queryparser.lemony" 2622 yymsp[0].
minor.
yy0->as_positional_unbroken(yylhsminor.
yy32);
2624 #line 2625 "queryparser/queryparser_internal.cc" 2629 #line 2192 "queryparser/queryparser.lemony" 2633 #line 2634 "queryparser/queryparser_internal.cc" 2636 #line 2196 "queryparser/queryparser.lemony" 2638 yymsp[0].
minor.
yy0->as_positional_unbroken(yymsp[-1].minor.yy32);
2640 #line 2641 "queryparser/queryparser_internal.cc" 2643 #line 2207 "queryparser/queryparser.lemony" 2649 #line 2650 "queryparser/queryparser_internal.cc" 2653 #line 2223 "queryparser/queryparser.lemony" 2657 #line 2658 "queryparser/queryparser_internal.cc" 2660 #line 2227 "queryparser/queryparser.lemony" 2664 #line 2665 "queryparser/queryparser_internal.cc" 2667 #line 2231 "queryparser/queryparser.lemony" 2671 #line 2672 "queryparser/queryparser_internal.cc" 2676 #line 2241 "queryparser/queryparser.lemony" 2681 if (yymsp[-1].minor.yy0) {
2686 #line 2687 "queryparser/queryparser_internal.cc" 2691 #line 2251 "queryparser/queryparser.lemony" 2694 if (yymsp[-1].minor.yy0) {
2699 #line 2700 "queryparser/queryparser_internal.cc" 2735 #ifndef YYNOERRORRECOVERY 2740 LOGLINE(QUERYPARSER,
"Fail!");
2745 #line 1809 "queryparser/queryparser.lemony" 2748 if (!state->error) state->error =
"parse error";
2749 #line 2750 "queryparser/queryparser_internal.cc" 2766 #define TOKEN yyminor 2768 #line 1814 "queryparser/queryparser.lemony" 2771 #line 2772 "queryparser/queryparser_internal.cc" 2783 LOGLINE(QUERYPARSER,
"Accept!");
2784 #ifndef YYNOERRORRECOVERY 2823 #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) 2826 #ifdef YYERRORSYMBOL 2830 #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) 2831 yyendofinput = (yymajor==0);
2835 #ifdef XAPIAN_DEBUG_LOG 2837 int stateno = yypParser->
yystack.back().stateno;
2839 LOGLINE(QUERYPARSER,
"Input '" << ParseTokenName(yymajor) <<
2840 "'," << (yyminor ? yyminor->name :
"<<null>>") <<
2841 "in state " << stateno);
2843 LOGLINE(QUERYPARSER,
"Input '" << ParseTokenName(yymajor) <<
2844 "'," << (yyminor ? yyminor->name :
"<<null>>") <<
2855 yy_shift(yypParser,yyact,yymajor,yyminor);
2856 #ifndef YYNOERRORRECOVERY 2861 yypParser->
yystack.pop_back();
2866 yyminorunion.
yy0 = yyminor;
2867 #ifdef YYERRORSYMBOL 2870 LOGLINE(QUERYPARSER,
"Syntax Error!");
2871 #ifdef YYERRORSYMBOL 2894 yymx = yypParser->
yystack.back().major;
2895 if( yymx==YYERRORSYMBOL || yyerrorhit ){
2896 LOGLINE(QUERYPARSER,
"Discard input token " << ParseTokenName(yymajor));
2897 yy_destructor(yypParser, static_cast<YYCODETYPE>(yymajor), &yyminorunion);
2900 while( !yypParser->
yystack.empty()
2901 && yymx != YYERRORSYMBOL
2903 yypParser->
yystack.back().stateno,
2908 if( yypParser->
yystack.empty() || yymajor==0 ){
2909 yy_destructor(yypParser,static_cast<YYCODETYPE>(yymajor),&yyminorunion);
2911 #ifndef YYNOERRORRECOVERY 2915 }
else if( yymx!=YYERRORSYMBOL ){
2916 yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
2921 #elif defined(YYNOERRORRECOVERY) 2930 yy_destructor(yypParser,static_cast<YYCODETYPE>(yymajor),&yyminorunion);
2947 yy_destructor(yypParser,static_cast<YYCODETYPE>(yymajor),&yyminorunion);
2950 #ifndef YYNOERRORRECOVERY 2958 #ifdef XAPIAN_DEBUG_LOG 2961 LOGLINE(QUERYPARSER,
"Return. Stack=");
2962 for(i=1; i<=(int)yypParser->
yystack.size(); i++)
2970 #line 799 "queryparser/queryparser.lemony" 2974 QueryParser::Internal::parse_query(
const string &qs,
unsigned flags,
2975 const string &default_prefix)
2980 bool ranges = !rangeprocs.empty() && (qs.find(
"..") != string::npos);
2985 State state(
this, flags);
2989 int correction_offset = 0;
2990 corrected_query.resize(0);
2993 list<const FieldInfo *> prefix_stack;
2999 const FieldInfo * default_field_info = &def_pfx;
3000 if (default_prefix.empty()) {
3001 auto f = field_map.find(
string());
3002 if (f != field_map.end()) default_field_info = &(f->second);
3006 prefix_stack.push_back(default_field_info);
3011 unsigned newprev =
' ';
3014 DEFAULT, IN_QUOTES, IN_PREFIXED_QUOTES, IN_PHRASED_TERM, IN_GROUP,
3015 IN_GROUP2, EXPLICIT_SYNONYM
3017 while (it != end && !state.
error) {
3018 bool last_was_operator =
false;
3019 bool last_was_operator_needing_term =
false;
3020 if (mode == EXPLICIT_SYNONYM) mode = DEFAULT;
3023 if (it == end)
break;
3025 last_was_operator_needing_term =
false;
3026 last_was_operator =
true;
3029 just_had_operator_needing_term:
3030 last_was_operator_needing_term =
true;
3031 last_was_operator =
true;
3033 if (mode == IN_PHRASED_TERM) mode = DEFAULT;
3038 if (it == end)
break;
3042 (mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2)) {
3051 if (ch ==
'.' && *p ==
'.') {
3057 a.resize(a.size() - 1);
3061 if (!a.empty() || (p != end && *p >
' ' && *p !=
')')) {
3065 while (p != end && *p >
' ' && *p !=
')') {
3070 state.
error =
"Unknown range operation";
3071 if (a.find(
':', 1) == string::npos) {
3087 if (ch <=
' ' || ch ==
'(')
break;
3093 unsigned prev = newprev;
3094 unsigned ch = *it++;
3097 if (mode == IN_GROUP || mode == IN_GROUP2)
3104 if (mode == DEFAULT) {
3121 if (flags & QueryParser::FLAG_PHRASE) {
3122 if (ch ==
'"' && it != end && *it ==
'"') {
3129 if (mode == DEFAULT) {
3133 if (mode == IN_PREFIXED_QUOTES)
3134 prefix_stack.pop_back();
3142 if (it == end)
goto done;
3143 if (prev >
' ' && prev !=
'(') {
3154 if (mode == DEFAULT && (flags & FLAG_LOVEHATE)) {
3158 }
else if (last_was_operator) {
3163 Parse(&parser, token, NULL, &state);
3164 goto just_had_operator_needing_term;
3174 if (it == end)
goto done;
3175 if (prev >
' ' && strchr(
"()+-", prev) == NULL) {
3184 if (mode == DEFAULT && (flags & FLAG_BOOLEAN)) {
3185 prefix_stack.push_back(prefix_stack.back());
3191 if (mode == DEFAULT && (flags & FLAG_BOOLEAN)) {
3195 if (prefix_stack.size() > 1) prefix_stack.pop_back();
3202 if (it == end)
goto done;
3203 if (mode == DEFAULT && (flags & FLAG_SYNONYM)) {
3204 if (prev >
' ' && strchr(
"+-(", prev) == NULL) {
3213 mode = EXPLICIT_SYNONYM;
3214 goto just_had_operator_needing_term;
3224 size_t term_start_index = it.raw() - qs.data();
3230 if ((mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2 || mode == EXPLICIT_SYNONYM) &&
3231 !field_map.empty()) {
3234 if (p != end && *p ==
':' && ++p != end && *p >
' ' && *p !=
')') {
3239 map<string, FieldInfo>::const_iterator f;
3240 f = field_map.find(field);
3241 if (f != field_map.end()) {
3245 field_info = &(f->second);
3249 if (mode == IN_GROUP || mode == IN_GROUP2)
3255 bool fancy = (*it !=
'"');
3260 if (++it == end || *it !=
'"')
3277 while (it != end && *it >
' ' && *it !=
')')
3285 Term * token =
new Term(&state, name, field_info, field);
3292 mode = IN_PREFIXED_QUOTES;
3297 prefix_stack.push_back(field_info);
3301 if (ch ==
'(' && (flags & FLAG_BOOLEAN)) {
3308 prefix_stack.push_back(field_info);
3336 bool needs_word_break =
false;
3337 string term = parse_term(it, end, try_word_break,
3338 needs_word_break, was_acronym);
3340 if ((mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2) &&
3341 (flags & FLAG_BOOLEAN) &&
3345 term.size() >= 2 && term.size() <= 4 &&
U_isalpha(term[0])) {
3348 if (flags & FLAG_BOOLEAN_ANY_CASE) {
3349 for (string::iterator i = op.begin(); i != op.end(); ++i) {
3353 if (op.size() == 3) {
3356 goto just_had_operator;
3360 goto just_had_operator;
3364 goto just_had_operator;
3367 if (it != end && *it ==
'/') {
3371 width = (width * 10) + (*p -
'0');
3376 goto just_had_operator;
3380 goto just_had_operator;
3383 }
else if (op.size() == 2) {
3385 Parse(&parser,
OR, NULL, &state);
3386 goto just_had_operator;
3388 }
else if (op.size() == 4) {
3390 if (it != end && *it ==
'/') {
3394 width = (width * 10) + (*p -
'0');
3399 goto just_had_operator;
3403 goto just_had_operator;
3410 if (!field_info) field_info = prefix_stack.back();
3415 string unstemmed_term(term);
3421 if (stem_term != STEM_NONE) {
3423 stem_term = STEM_NONE;
3424 }
else if (stem_term == STEM_SOME ||
3425 stem_term == STEM_SOME_FULL_POS) {
3429 stem_term = STEM_NONE;
3434 Term * term_obj =
new Term(&state, term, field_info,
3435 unstemmed_term, stem_term, term_pos++);
3437 if (needs_word_break) {
3440 if (mode == IN_GROUP || mode == IN_GROUP2)
3442 if (it == end)
break;
3446 if (mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2) {
3448 if ((flags & FLAG_WILDCARD) && *it ==
'*') {
3453 if (mode == IN_GROUP || mode == IN_GROUP2) {
3456 if (mode == IN_GROUP2)
3467 if (flags & FLAG_PARTIAL) {
3468 if (mode == IN_GROUP || mode == IN_GROUP2) {
3471 if (mode == IN_GROUP2)
3485 if ((flags & FLAG_SPELLING_CORRECTION) && !was_acronym) {
3486 const auto& prefixes = field_info->
prefixes;
3487 for (
const string& prefix : prefixes) {
3488 if (!prefix.empty())
3490 const string & suggest = db.get_spelling_suggestion(term);
3491 if (!suggest.empty()) {
3492 if (corrected_query.empty()) corrected_query = qs;
3493 size_t term_end_index = it.raw() - qs.data();
3494 size_t n = term_end_index - term_start_index;
3495 size_t pos = term_start_index + correction_offset;
3496 corrected_query.replace(pos, n, suggest);
3497 correction_offset += suggest.size();
3498 correction_offset -= n;
3504 if (mode == IN_PHRASED_TERM) {
3509 if ((mode == IN_GROUP || mode == IN_GROUP2) &&
3524 if (mode == IN_GROUP || mode == IN_GROUP2) {
3528 Parse(&parser, token, term_obj, &state);
3529 if (token ==
TERM && mode != DEFAULT)
3534 if (it == end)
break;
3544 mode = IN_PHRASED_TERM;
3545 term_start_index = it.raw() - qs.data();
3548 }
else if (mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2) {
3549 int old_mode = mode;
3551 if (!last_was_operator_needing_term &&
is_whitespace(*it)) {
3560 if (old_mode == IN_GROUP || old_mode == IN_GROUP2) {
3572 if (mode == IN_QUOTES || mode == IN_PREFIXED_QUOTES)
3576 while (prefix_stack.size() > 1) {
3578 prefix_stack.pop_back();
3580 Parse(&parser, 0, NULL, &state);
3583 errmsg = state.
error;
3587 #line 3588 "queryparser/queryparser_internal.cc"
static void yy_pop_parser_stack(yyParser *pParser)
Unicode and UTF-8 related classes and functions.
bool is_none() const
Return true if this is a no-op stemmer.
The Xapian namespace contains public interfaces for the Xapian library.
static unsigned int yy_find_shift_action(yyParser *pParser, YYCODETYPE iLookAhead)
void append_utf8(std::string &s, unsigned ch)
Append the UTF-8 representation of a single Unicode character to a std::string.
ParseARG_SDECL vector< yyStackEntry > yystack
bool is_stopword(const Term *term) const
bool operator==(const SynonymIterator &o) const
bool U_isalpha(unsigned ch)
size_t stoplist_size() const
const char * raw() const
Return the raw const char* pointer for the current position.
Xapian::termcount max_wildcard_expansion
unsigned tolower(unsigned ch)
Convert a Unicode character to lowercase.
This class is used to access a database, or a group of databases.
Xapian::termcount_diff difference_type
Database get_database() const
Xapian::termcount max_partial_expansion
InvalidOperationError indicates the API was used in an invalid way.
bool is_digit(unsigned ch)
static void Parse(yyParser *yypParser, int yymajor, ParseTOKENTYPE yyminor ParseARG_PDECL)
QueryParser::Internal * qpi
bool U_isupper(unsigned ch)
void stoplist_resize(size_t s)
bool is_currency(unsigned ch)
Test if a given Unicode character is a currency symbol.
Number, decimal digit (Nd)
void append_filter(const string &grouping, const Query &qnew)
bool is_unbroken_script(unsigned p)
Build a Xapian::Query object from a user query string.
Query * as_group(State *state) const
Convert to a Xapian::Query * using default_op.
void append_filter_range(const string &grouping, const Query &range)
Xapian::TermIterator synonyms_end(const std::string &) const
Corresponding end iterator to synonyms_begin(term).
Convert types to std::string.
Query get_query_with_auto_synonyms() const
const Xapian::Query operator*() const
Query opwindow_subq(Query::op op, const vector< Query > &v, Xapian::termcount w) const
void add_filter_range(const string &grouping, const Query &range)
void add_positional_term(Term *term)
Add an unstemmed Term object to this Terms object.
Xapian::Internal::intrusive_ptr< Internal > internal
Xapian::Query & reference
static Xapian::Stem stemmer
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...
The non-lemon-generated parts of the QueryParser class.
Query as_range_query() const
Range query.
Query * as_adj_query() const
Convert to a Xapian::Query * using OP_PHRASE to implement ADJ.
std::input_iterator_tag iterator_category
Iterator returning unigrams and bigrams.
bool U_isdigit(unsigned ch)
Term * range(const string &a, const string &b)
Query get_query_with_synonyms() const
Hierarchy of classes which Xapian can throw as exceptions.
Class for iterating over a list of terms.
unsigned XAPIAN_TERMCOUNT_BASE_TYPE termcount
A counts of terms.
static void yy_parse_failed(yyParser *)
Term(const string &name_, const FieldInfo *field_info_)
void add_term(Term *term)
Add a Term object to this TermGroup object.
static void ParseFinalize(yyParser *pParser)
#define YY_MAX_SHIFTREDUCE
Term(const string &name_)
Information about how to handle a field prefix in the query string.
Query * as_near_query() const
Convert to a Xapian::Query * using OP_NEAR.
const FieldInfo * field_info
static void yy_shift(yyParser *yypParser, int yyNewState, int yyMajor, ParseTOKENTYPE yyMinor)
Base class for field processors.
Query * as_wildcarded_query(State *state) const
Match only documents where all subqueries match near and in order.
Indicates an attempt to use a feature which is unavailable.
bool is_double_quote(unsigned ch)
SynonymIterator(const Xapian::TermIterator &i_, Xapian::termpos pos_=0, const Xapian::Query *first_=NULL)
#define yyTraceShift(X, Y, Z)
stem_strategy
Stemming strategies, for use with set_stemming_strategy().
static void ParseInit(yyParser *pParser)
Match only documents where a value slot is >= a given value.
Xapian::TermIterator synonym_keys_begin(const std::string &prefix=std::string()) const
An iterator which returns all terms which have synonyms.
static const YYACTIONTYPE yy_default[]
const unsigned UNICODE_IGNORE
Value representing "ignore this" when returned by check_infix() or check_infix_digit().
size_t window
Window size.
bool is_phrase_generator(unsigned ch)
const vector< string > * prefixes
The list of prefixes of the terms added.
Parser State shared between the lexer and the parser.
Match only documents where a value slot is within a given range.
Xapian::TermIterator synonym_keys_end(const std::string &=std::string()) const
Corresponding end iterator to synonym_keys_begin(prefix).
string str(int value)
Convert int to std::string.
vector< string > prefixes
Field prefix strings.
Match only documents where a value slot is <= a given value.
Term(const string &name_, termpos pos_)
TermGroup(Term *t1, Term *t2)
void add_to_unstem(const string &term, const string &unstemmed)
bool startswith(const std::string &s, char pfx)
Construct an invalid query.
Query * as_unbroken_query() const
Build a query for a string of words without explicit word breaks.
static int yy_find_reduce_action(int stateno, YYCODETYPE iLookAhead)
unsigned check_infix_digit(unsigned ch)
Query merge_filters() const
bool is_stem_preventer(unsigned ch)
Term(const Xapian::Query &q, const string &grouping)
void add_filter(const string &grouping, const Query &q)
Some terms which form a positional sub-query.
Xapian::TermIterator synonyms_begin(const std::string &term) const
An iterator which returns all the synonyms for a given term.
bool is_positional(Xapian::Query::op op)
A group of terms separated only by whitespace.
Handle text without explicit word breaks.
bool operator!=(const SynonymIterator &o) const
Match like OP_OR but weighting as if a single term.
static void yy_syntax_error(yyParser *yypParser, int yymajor, ParseTOKENTYPE yyminor)
bool should_stem(const string &term)
An iterator which returns Unicode character values from a UTF-8 encoded string.
bool empty_ok
Controls how to handle a group where all terms are stopwords.
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())
int get_max_partial_type() const
XAPIAN_TERMCOUNT_BASE_TYPE termcount_diff
A signed difference between two counts of terms.
SynonymIterator & operator++()
yyStackEntry(YYACTIONTYPE stateno_, YYCODETYPE major_, ParseTOKENTYPE minor_)
bool is_wordchar(unsigned ch)
Test if a given Unicode character is "word character".
bool prefix_needs_colon(const string &prefix, unsigned ch)
list< RangeProc > rangeprocs
Term(State *state_, const string &name_, const FieldInfo *field_info_, const string &unstemmed_, QueryParser::stem_strategy stem_=QueryParser::STEM_NONE, termpos pos_=0)
int get_max_wildcard_type() const
Match only documents where all subqueries match near each other.
void add_to_stoplist(const Term *term)
string get_grouping() const
void adjust_window(size_t alternative_window)
map< string, Query > filter
Value returned by get_type() for a term.
bool empty() const
Check if this query is Xapian::Query::MatchNothing.
bool is_suffix(unsigned ch)
static void yy_reduce(yyParser *yypParser, unsigned int yyruleno, int yyLookahead, ParseTOKENTYPE yyLookaheadToken)
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.
Xapian::termcount get_max_wildcard_expansion() const
Various handy helpers which std::string really should provide.
bool is_whitespace(unsigned ch)
Test if a given Unicode character is a whitespace character.
Xapian::termcount get_max_partial_expansion() const
void get_unbroken(Xapian::Utf8Iterator &it)
Abstract base class for stop-word decision functor.
bool is_not_wordchar(unsigned ch)
op get_type() const
Get the type of the top level of the query.
category get_category(int info)
Xapian::valueno get_slot() const
static const YYCODETYPE yy_lookahead[]
void as_positional_unbroken(Terms *terms) const
Handle text without explicit word breaks in a positional context.
multimap< string, string > unstem
const Xapian::Query * first
static void add_to_query(Query *&q, Query::op op, Query *term)
QueryParser::stem_strategy stem
static const unsigned short int yy_shift_ofst[]
Various assertion macros.
bool uniform_prefixes
Keep track of whether the terms added all have the same list of prefixes.
bool is_not_whitespace(unsigned ch)
static const YYACTIONTYPE yy_action[]
#define YY_MIN_SHIFTREDUCE
bool is_ngram_enabled()
Should we use the n-gram code?
Class representing a query.
void set_empty_ok()
Set the empty_ok flag.
termpos get_termpos() const
Query::op default_op() const
static TermGroup * create(Term *t1, Term *t2)
Factory function - ensures heap allocation.
string make_term(const string &prefix) const
static const struct @13 yyRuleInfo[]
static Terms * create(State *state)
Factory function - ensures heap allocation.
unsigned check_infix(unsigned ch)
Xapian::Internal::opt_intrusive_ptr< const Stopper > stopper
Class used to pass information about a token from lexer to parser.
static void yy_accept(yyParser *)
static void yy_destructor(yyParser *yypParser, YYCODETYPE yymajor, YYMINORTYPE *yypminor)
Query * as_opwindow_query(Query::op op, Xapian::termcount w_delta) const
Convert to a query using the given operator and window size.
string stem_term(const string &term)
Query * as_phrase_query() const
Convert to a Xapian::Query * using adjacent OP_PHRASE.
Query::op effective_default_op
#define VET_BOOL_ARGS(A, B, OP_TXT)
State(QueryParser::Internal *qpi_, unsigned flags_)
UnimplementedError indicates an attempt to use an unimplemented feature.
static const short yy_reduce_ofst[]
filter_type type
The type of this field.
const Stopper * get_stopper() const