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_cjk_query()
const;
217 void as_positional_cjk_term(
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> cjk_subqs;
546 const auto& prefixes = field_info->prefixes;
547 for (
const string& prefix : prefixes) {
549 cjk_subqs.push_back(
Query(prefix + *tk, 1, pos));
551 prefix_subqs.push_back(
Query(Query::OP_AND,
552 cjk_subqs.begin(), cjk_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 cjk_ngram,
bool & is_cjk_term,
743 }
while (p != end && *p ==
'.' && ++p != end &&
U_isupper(*p));
746 if (t.length() > 1) {
756 was_acronym = !term.empty();
759 const char* cjk = it.
raw();
761 term.assign(cjk, it.
raw() - cjk);
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 1412 "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 ::= CJKTERM",
1629 "phrase ::= CJKTERM",
1630 "phrase ::= phrase TERM",
1631 "phrase ::= phrase CJKTERM",
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 1801 "queryparser/queryparser.lemony" 1782 delete (yypminor->
yy0);
1783 #line 1784 "queryparser/queryparser_internal.cc" 1793 #line 1876 "queryparser/queryparser.lemony" 1794 delete (yypminor->
yy39);
1795 #line 1796 "queryparser/queryparser_internal.cc" 1801 #line 1985 "queryparser/queryparser.lemony" 1802 delete (yypminor->
yy40);
1803 #line 1804 "queryparser/queryparser_internal.cc" 1811 #line 2176 "queryparser/queryparser.lemony" 1812 delete (yypminor->
yy32);
1813 #line 1814 "queryparser/queryparser_internal.cc" 1818 #line 2217 "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();
2162 #ifdef XAPIAN_DEBUG_LOG 2163 if( yyruleno<(
int)(
sizeof(yyRuleName)/
sizeof(yyRuleName[0])) ){
2166 LOGLINE(QUERYPARSER,
"Reduce " << yyruleno <<
" [" <<
2167 ParseRuleName(yyruleno) <<
"], go to state " <<
2168 yymsp[yysize].stateno);
2170 LOGLINE(QUERYPARSER,
"Reduce " << yyruleno <<
" [" <<
2171 ParseRuleName(yyruleno) <<
"].");
2184 yymsp = &(yypParser->
yystack.back()) - 1;
2186 #ifdef YYTRACKMAXSTACKDEPTH 2187 if( (
int)(yypParser->yytos - yypParser->
yystack)>yypParser->yyhwm ){
2189 Assert( yypParser->yyhwm == (
int)(yypParser->yytos - yypParser->
yystack));
2193 if( yypParser->yytos>=yypParser->yystackEnd ){
2194 yyStackOverflow(yypParser);
2198 if( yypParser->yytos>=&yypParser->
yystack[yypParser->yystksz-1] ){
2199 if( yyGrowStack(yypParser) ){
2200 yyStackOverflow(yypParser);
2203 yymsp = yypParser->yytos;
2221 #line 1858 "queryparser/queryparser.lemony" 2224 if (yymsp[0].minor.yy39) {
2228 state->query =
Query();
2231 #line 2232 "queryparser/queryparser_internal.cc" 2234 #line 1868 "queryparser/queryparser.lemony" 2237 state->query =
Query();
2239 #line 2240 "queryparser/queryparser_internal.cc" 2242 #line 1880 "queryparser/queryparser.lemony" 2248 #line 2249 "queryparser/queryparser_internal.cc" 2252 #line 1886 "queryparser/queryparser.lemony" 2255 if (!yymsp[-2].minor.yy39 && (state->flags & QueryParser::FLAG_PURE_NOT)) {
2262 #line 2263 "queryparser/queryparser_internal.cc" 2266 #line 1896 "queryparser/queryparser.lemony" 2272 #line 2273 "queryparser/queryparser_internal.cc" 2277 #line 1902 "queryparser/queryparser.lemony" 2283 #line 2284 "queryparser/queryparser_internal.cc" 2288 #line 1908 "queryparser/queryparser.lemony" 2294 #line 2295 "queryparser/queryparser_internal.cc" 2298 #line 1914 "queryparser/queryparser.lemony" 2304 #line 2305 "queryparser/queryparser_internal.cc" 2308 #line 1927 "queryparser/queryparser.lemony" 2315 #line 2316 "queryparser/queryparser_internal.cc" 2318 #line 1939 "queryparser/queryparser.lemony" 2323 if (yymsp[0].minor.yy40->love) {
2324 if (yymsp[0].minor.yy40->love->empty()) {
2326 delete yylhsminor.
yy39;
2328 }
else if (yylhsminor.
yy39) {
2337 if (!yymsp[0].minor.yy40->filter.empty()) {
2338 if (yylhsminor.
yy39) {
2342 yylhsminor.
yy39 =
new Query(Query::OP_SCALE_WEIGHT, yymsp[0].minor.yy40->merge_filters(), 0.0);
2347 if (!yylhsminor.
yy39) {
2356 #line 2357 "queryparser/queryparser_internal.cc" 2360 #line 1987 "queryparser/queryparser.lemony" 2367 #line 2368 "queryparser/queryparser_internal.cc" 2370 #line 1994 "queryparser/queryparser.lemony" 2376 #line 2377 "queryparser/queryparser_internal.cc" 2379 #line 2000 "queryparser/queryparser.lemony" 2382 if (yymsp[0].minor.yy39) {
2396 #line 2397 "queryparser/queryparser_internal.cc" 2399 #line 2017 "queryparser/queryparser.lemony" 2402 if (yymsp[0].minor.yy39)
add_to_query(yymsp[-1].minor.yy40->query, state->default_op(), yymsp[0].
minor.
yy39);
2404 #line 2405 "queryparser/queryparser_internal.cc" 2408 #line 2022 "queryparser/queryparser.lemony" 2411 if (state->default_op() == Query::OP_AND) {
2417 #line 2418 "queryparser/queryparser_internal.cc" 2421 #line 2031 "queryparser/queryparser.lemony" 2423 if (state->default_op() == Query::OP_AND) {
2432 #line 2433 "queryparser/queryparser_internal.cc" 2437 #line 2042 "queryparser/queryparser.lemony" 2442 #line 2443 "queryparser/queryparser_internal.cc" 2446 #line 2047 "queryparser/queryparser.lemony" 2450 #line 2451 "queryparser/queryparser_internal.cc" 2455 #line 2051 "queryparser/queryparser.lemony" 2461 #line 2462 "queryparser/queryparser_internal.cc" 2465 #line 2057 "queryparser/queryparser.lemony" 2470 #line 2471 "queryparser/queryparser_internal.cc" 2474 #line 2062 "queryparser/queryparser.lemony" 2480 #line 2481 "queryparser/queryparser_internal.cc" 2484 #line 2068 "queryparser/queryparser.lemony" 2489 #line 2490 "queryparser/queryparser_internal.cc" 2493 #line 2073 "queryparser/queryparser.lemony" 2500 #line 2501 "queryparser/queryparser_internal.cc" 2504 #line 2080 "queryparser/queryparser.lemony" 2509 q |= yymsp[0].
minor.
yy0->get_query();
2512 #line 2513 "queryparser/queryparser_internal.cc" 2516 #line 2095 "queryparser/queryparser.lemony" 2520 #line 2521 "queryparser/queryparser_internal.cc" 2523 #line 2108 "queryparser/queryparser.lemony" 2525 if (state->is_stopword(yymsp[0].
minor.
yy0)) {
2526 yylhsminor.
yy39 = NULL;
2527 state->add_to_stoplist(yymsp[0].minor.yy0);
2529 yylhsminor.
yy39 =
new Query(yymsp[0].minor.yy0->get_query_with_auto_synonyms());
2533 #line 2534 "queryparser/queryparser_internal.cc" 2537 #line 2125 "queryparser/queryparser.lemony" 2539 yylhsminor.
yy39 =
new Query(yymsp[0].minor.yy0->get_query_with_auto_synonyms());
2542 #line 2543 "queryparser/queryparser_internal.cc" 2546 #line 2140 "queryparser/queryparser.lemony" 2548 #line 2549 "queryparser/queryparser_internal.cc" 2551 #line 2143 "queryparser/queryparser.lemony" 2553 #line 2554 "queryparser/queryparser_internal.cc" 2557 #line 2146 "queryparser/queryparser.lemony" 2559 #line 2560 "queryparser/queryparser_internal.cc" 2564 #line 2149 "queryparser/queryparser.lemony" 2566 #line 2567 "queryparser/queryparser_internal.cc" 2569 #line 2152 "queryparser/queryparser.lemony" 2571 #line 2572 "queryparser/queryparser_internal.cc" 2574 #line 2155 "queryparser/queryparser.lemony" 2576 #line 2577 "queryparser/queryparser_internal.cc" 2579 #line 2158 "queryparser/queryparser.lemony" 2581 #line 2582 "queryparser/queryparser_internal.cc" 2585 #line 2161 "queryparser/queryparser.lemony" 2587 #line 2588 "queryparser/queryparser_internal.cc" 2593 #line 2163 "queryparser/queryparser.lemony" 2595 yymsp[-1].
minor.
yy39 =
new Query(yymsp[0].minor.yy0->get_query_with_synonyms());
2598 #line 2599 "queryparser/queryparser_internal.cc" 2602 #line 2168 "queryparser/queryparser.lemony" 2606 #line 2607 "queryparser/queryparser_internal.cc" 2609 #line 2178 "queryparser/queryparser.lemony" 2614 #line 2615 "queryparser/queryparser_internal.cc" 2618 #line 2183 "queryparser/queryparser.lemony" 2621 yymsp[0].
minor.
yy0->as_positional_cjk_term(yylhsminor.
yy32);
2623 #line 2624 "queryparser/queryparser_internal.cc" 2628 #line 2188 "queryparser/queryparser.lemony" 2632 #line 2633 "queryparser/queryparser_internal.cc" 2635 #line 2192 "queryparser/queryparser.lemony" 2637 yymsp[0].
minor.
yy0->as_positional_cjk_term(yymsp[-1].minor.yy32);
2639 #line 2640 "queryparser/queryparser_internal.cc" 2642 #line 2203 "queryparser/queryparser.lemony" 2648 #line 2649 "queryparser/queryparser_internal.cc" 2652 #line 2219 "queryparser/queryparser.lemony" 2656 #line 2657 "queryparser/queryparser_internal.cc" 2659 #line 2223 "queryparser/queryparser.lemony" 2663 #line 2664 "queryparser/queryparser_internal.cc" 2666 #line 2227 "queryparser/queryparser.lemony" 2670 #line 2671 "queryparser/queryparser_internal.cc" 2675 #line 2237 "queryparser/queryparser.lemony" 2680 if (yymsp[-1].minor.yy0) {
2685 #line 2686 "queryparser/queryparser_internal.cc" 2690 #line 2247 "queryparser/queryparser.lemony" 2693 if (yymsp[-1].minor.yy0) {
2698 #line 2699 "queryparser/queryparser_internal.cc" 2734 #ifndef YYNOERRORRECOVERY 2739 LOGLINE(QUERYPARSER,
"Fail!");
2744 #line 1805 "queryparser/queryparser.lemony" 2747 if (!state->error) state->error =
"parse error";
2748 #line 2749 "queryparser/queryparser_internal.cc" 2765 #define TOKEN yyminor 2767 #line 1810 "queryparser/queryparser.lemony" 2770 #line 2771 "queryparser/queryparser_internal.cc" 2782 LOGLINE(QUERYPARSER,
"Accept!");
2783 #ifndef YYNOERRORRECOVERY 2822 #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) 2825 #ifdef YYERRORSYMBOL 2829 #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) 2830 yyendofinput = (yymajor==0);
2834 #ifdef XAPIAN_DEBUG_LOG 2836 int stateno = yypParser->
yystack.back().stateno;
2838 LOGLINE(QUERYPARSER,
"Input '" << ParseTokenName(yymajor) <<
2839 "'," << (yyminor ? yyminor->name :
"<<null>>") <<
2840 "in state " << stateno);
2842 LOGLINE(QUERYPARSER,
"Input '" << ParseTokenName(yymajor) <<
2843 "'," << (yyminor ? yyminor->name :
"<<null>>") <<
2854 yy_shift(yypParser,yyact,yymajor,yyminor);
2855 #ifndef YYNOERRORRECOVERY 2860 yypParser->
yystack.pop_back();
2865 yyminorunion.
yy0 = yyminor;
2866 #ifdef YYERRORSYMBOL 2869 LOGLINE(QUERYPARSER,
"Syntax Error!");
2870 #ifdef YYERRORSYMBOL 2893 yymx = yypParser->
yystack.back().major;
2894 if( yymx==YYERRORSYMBOL || yyerrorhit ){
2895 LOGLINE(QUERYPARSER,
"Discard input token " << ParseTokenName(yymajor));
2896 yy_destructor(yypParser, static_cast<YYCODETYPE>(yymajor), &yyminorunion);
2899 while( !yypParser->
yystack.empty()
2900 && yymx != YYERRORSYMBOL
2902 yypParser->
yystack.back().stateno,
2907 if( yypParser->
yystack.empty() || yymajor==0 ){
2908 yy_destructor(yypParser,static_cast<YYCODETYPE>(yymajor),&yyminorunion);
2910 #ifndef YYNOERRORRECOVERY 2914 }
else if( yymx!=YYERRORSYMBOL ){
2915 yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
2920 #elif defined(YYNOERRORRECOVERY) 2929 yy_destructor(yypParser,static_cast<YYCODETYPE>(yymajor),&yyminorunion);
2946 yy_destructor(yypParser,static_cast<YYCODETYPE>(yymajor),&yyminorunion);
2949 #ifndef YYNOERRORRECOVERY 2957 #ifdef XAPIAN_DEBUG_LOG 2960 LOGLINE(QUERYPARSER,
"Return. Stack=");
2961 for(i=1; i<=(int)yypParser->
yystack.size(); i++)
2969 #line 799 "queryparser/queryparser.lemony" 2973 QueryParser::Internal::parse_query(
const string &qs,
unsigned flags,
2974 const string &default_prefix)
2979 bool ranges = !rangeprocs.empty() && (qs.find(
"..") != string::npos);
2984 State state(
this, flags);
2988 int correction_offset = 0;
2989 corrected_query.resize(0);
2992 list<const FieldInfo *> prefix_stack;
2998 const FieldInfo * default_field_info = &def_pfx;
2999 if (default_prefix.empty()) {
3000 auto f = field_map.find(
string());
3001 if (f != field_map.end()) default_field_info = &(f->second);
3005 prefix_stack.push_back(default_field_info);
3010 unsigned newprev =
' ';
3013 DEFAULT, IN_QUOTES, IN_PREFIXED_QUOTES, IN_PHRASED_TERM, IN_GROUP,
3014 IN_GROUP2, EXPLICIT_SYNONYM
3016 while (it != end && !state.
error) {
3017 bool last_was_operator =
false;
3018 bool last_was_operator_needing_term =
false;
3019 if (mode == EXPLICIT_SYNONYM) mode = DEFAULT;
3022 if (it == end)
break;
3024 last_was_operator_needing_term =
false;
3025 last_was_operator =
true;
3028 just_had_operator_needing_term:
3029 last_was_operator_needing_term =
true;
3030 last_was_operator =
true;
3032 if (mode == IN_PHRASED_TERM) mode = DEFAULT;
3037 if (it == end)
break;
3041 (mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2)) {
3050 if (ch ==
'.' && *p ==
'.') {
3056 a.resize(a.size() - 1);
3060 if (!a.empty() || (p != end && *p >
' ' && *p !=
')')) {
3064 while (p != end && *p >
' ' && *p !=
')') {
3069 state.
error =
"Unknown range operation";
3070 if (a.find(
':', 1) == string::npos) {
3086 if (ch <=
' ' || ch ==
'(')
break;
3092 unsigned prev = newprev;
3093 unsigned ch = *it++;
3096 if (mode == IN_GROUP || mode == IN_GROUP2)
3103 if (mode == DEFAULT) {
3120 if (flags & QueryParser::FLAG_PHRASE) {
3121 if (ch ==
'"' && it != end && *it ==
'"') {
3128 if (mode == DEFAULT) {
3132 if (mode == IN_PREFIXED_QUOTES)
3133 prefix_stack.pop_back();
3141 if (it == end)
goto done;
3142 if (prev >
' ' && prev !=
'(') {
3153 if (mode == DEFAULT && (flags & FLAG_LOVEHATE)) {
3157 }
else if (last_was_operator) {
3162 Parse(&parser, token, NULL, &state);
3163 goto just_had_operator_needing_term;
3173 if (it == end)
goto done;
3174 if (prev >
' ' && strchr(
"()+-", prev) == NULL) {
3183 if (mode == DEFAULT && (flags & FLAG_BOOLEAN)) {
3184 prefix_stack.push_back(prefix_stack.back());
3190 if (mode == DEFAULT && (flags & FLAG_BOOLEAN)) {
3194 if (prefix_stack.size() > 1) prefix_stack.pop_back();
3201 if (it == end)
goto done;
3202 if (mode == DEFAULT && (flags & FLAG_SYNONYM)) {
3203 if (prev >
' ' && strchr(
"+-(", prev) == NULL) {
3212 mode = EXPLICIT_SYNONYM;
3213 goto just_had_operator_needing_term;
3223 size_t term_start_index = it.raw() - qs.data();
3229 if ((mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2 || mode == EXPLICIT_SYNONYM) &&
3230 !field_map.empty()) {
3233 if (p != end && *p ==
':' && ++p != end && *p >
' ' && *p !=
')') {
3238 map<string, FieldInfo>::const_iterator f;
3239 f = field_map.find(field);
3240 if (f != field_map.end()) {
3244 field_info = &(f->second);
3248 if (mode == IN_GROUP || mode == IN_GROUP2)
3254 bool fancy = (*it !=
'"');
3259 if (++it == end || *it !=
'"')
3276 while (it != end && *it >
' ' && *it !=
')')
3284 Term * token =
new Term(&state, name, field_info, field);
3291 mode = IN_PREFIXED_QUOTES;
3296 prefix_stack.push_back(field_info);
3300 if (ch ==
'(' && (flags & FLAG_BOOLEAN)) {
3307 prefix_stack.push_back(field_info);
3335 bool is_cjk_term =
false;
3336 string term = parse_term(it, end, cjk_ngram, is_cjk_term, was_acronym);
3338 if ((mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2) &&
3339 (flags & FLAG_BOOLEAN) &&
3343 term.size() >= 2 && term.size() <= 4 &&
U_isalpha(term[0])) {
3346 if (flags & FLAG_BOOLEAN_ANY_CASE) {
3347 for (string::iterator i = op.begin(); i != op.end(); ++i) {
3351 if (op.size() == 3) {
3354 goto just_had_operator;
3358 goto just_had_operator;
3362 goto just_had_operator;
3365 if (it != end && *it ==
'/') {
3369 width = (width * 10) + (*p -
'0');
3374 goto just_had_operator;
3378 goto just_had_operator;
3381 }
else if (op.size() == 2) {
3383 Parse(&parser,
OR, NULL, &state);
3384 goto just_had_operator;
3386 }
else if (op.size() == 4) {
3388 if (it != end && *it ==
'/') {
3392 width = (width * 10) + (*p -
'0');
3397 goto just_had_operator;
3401 goto just_had_operator;
3408 if (!field_info) field_info = prefix_stack.back();
3413 string unstemmed_term(term);
3419 if (stem_term != STEM_NONE) {
3421 stem_term = STEM_NONE;
3422 }
else if (stem_term == STEM_SOME ||
3423 stem_term == STEM_SOME_FULL_POS) {
3427 stem_term = STEM_NONE;
3432 Term * term_obj =
new Term(&state, term, field_info,
3433 unstemmed_term, stem_term, term_pos++);
3437 if (it == end)
break;
3441 if (mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2) {
3443 if ((flags & FLAG_WILDCARD) && *it ==
'*') {
3448 if (mode == IN_GROUP || mode == IN_GROUP2) {
3451 if (mode == IN_GROUP2)
3462 if (flags & FLAG_PARTIAL) {
3463 if (mode == IN_GROUP || mode == IN_GROUP2) {
3466 if (mode == IN_GROUP2)
3480 if ((flags & FLAG_SPELLING_CORRECTION) && !was_acronym) {
3481 const auto& prefixes = field_info->
prefixes;
3482 for (
const string& prefix : prefixes) {
3483 if (!prefix.empty())
3485 const string & suggest = db.get_spelling_suggestion(term);
3486 if (!suggest.empty()) {
3487 if (corrected_query.empty()) corrected_query = qs;
3488 size_t term_end_index = it.raw() - qs.data();
3489 size_t n = term_end_index - term_start_index;
3490 size_t pos = term_start_index + correction_offset;
3491 corrected_query.replace(pos, n, suggest);
3492 correction_offset += suggest.size();
3493 correction_offset -= n;
3499 if (mode == IN_PHRASED_TERM) {
3504 if ((mode == IN_GROUP || mode == IN_GROUP2) &&
3519 if (mode == IN_GROUP || mode == IN_GROUP2) {
3523 Parse(&parser, token, term_obj, &state);
3524 if (token ==
TERM && mode != DEFAULT)
3529 if (it == end)
break;
3539 mode = IN_PHRASED_TERM;
3540 term_start_index = it.raw() - qs.data();
3543 }
else if (mode == DEFAULT || mode == IN_GROUP || mode == IN_GROUP2) {
3544 int old_mode = mode;
3546 if (!last_was_operator_needing_term &&
is_whitespace(*it)) {
3555 if (old_mode == IN_GROUP || old_mode == IN_GROUP2) {
3567 if (mode == IN_QUOTES || mode == IN_PREFIXED_QUOTES)
3571 while (prefix_stack.size() > 1) {
3573 prefix_stack.pop_back();
3575 Parse(&parser, 0, NULL, &state);
3578 errmsg = state.
error;
3582 #line 3583 "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)
Build a Xapian::Query object from a user query string.
bool is_cjk_enabled()
Should we use the CJK n-gram code?
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 as_positional_cjk_term(Terms *terms) const
Handle a CJK character string in a positional context.
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...
bool codepoint_is_cjk(unsigned codepoint)
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
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)
Tokenise CJK text as n-grams.
void add_to_unstem(const string &term, const string &unstemmed)
bool startswith(const std::string &s, char pfx)
Construct an invalid query.
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.
Iterator returning unigrams and bigrams.
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.
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
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[]
multimap< string, string > unstem
const Xapian::Query * first
static void add_to_query(Query *&q, Query::op op, Query *term)
QueryParser::stem_strategy stem
void get_cjk(Xapian::Utf8Iterator &it)
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
Class representing a query.
Query * as_cjk_query() const
Build a query for a string of CJK characters.
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