diff --git a/src/query/wasaparse.cpp b/src/query/wasaparse.cpp index 8247e2b9..163cd28d 100644 --- a/src/query/wasaparse.cpp +++ b/src/query/wasaparse.cpp @@ -32,7 +32,7 @@ // First part of user declarations. -#line 1 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:399 +#line 1 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:399 #define YYDEBUG 1 #include "autoconfig.h" @@ -48,7 +48,7 @@ using namespace std; -// #define LOG_PARSER +//#define LOG_PARSER #ifdef LOG_PARSER #define LOGP(X) {cerr << X;} #else @@ -63,11 +63,13 @@ static void qualify(Rcl::SearchDataClauseDist *, const string &); static void addSubQuery(WasaParserDriver *d, Rcl::SearchData *sd, Rcl::SearchData *sq) { - sd->addClause(new Rcl::SearchDataClauseSub(STD_SHARED_PTR(sq))); + if (sd && sq) + sd->addClause( + new Rcl::SearchDataClauseSub(STD_SHARED_PTR(sq))); } -#line 71 "y.tab.c" // lalr1.cc:399 +#line 73 "y.tab.c" // lalr1.cc:399 # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus @@ -81,7 +83,7 @@ static void addSubQuery(WasaParserDriver *d, // User implementation prologue. -#line 85 "y.tab.c" // lalr1.cc:407 +#line 87 "y.tab.c" // lalr1.cc:407 #ifndef YY_ @@ -167,7 +169,7 @@ static void addSubQuery(WasaParserDriver *d, namespace yy { -#line 171 "y.tab.c" // lalr1.cc:474 +#line 173 "y.tab.c" // lalr1.cc:474 /* Return YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is @@ -384,30 +386,30 @@ namespace yy { { case 3: // WORD -#line 49 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:599 +#line 51 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:599 {delete (yysym.value.str);} -#line 390 "y.tab.c" // lalr1.cc:599 +#line 392 "y.tab.c" // lalr1.cc:599 break; case 4: // QUOTED -#line 49 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:599 +#line 51 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:599 {delete (yysym.value.str);} -#line 397 "y.tab.c" // lalr1.cc:599 +#line 399 "y.tab.c" // lalr1.cc:599 break; case 5: // QUALIFIERS -#line 49 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:599 +#line 51 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:599 {delete (yysym.value.str);} -#line 404 "y.tab.c" // lalr1.cc:599 +#line 406 "y.tab.c" // lalr1.cc:599 break; case 22: // complexfieldname -#line 49 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:599 +#line 51 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:599 {delete (yysym.value.str);} -#line 411 "y.tab.c" // lalr1.cc:599 +#line 413 "y.tab.c" // lalr1.cc:599 break; @@ -647,83 +649,100 @@ namespace yy { switch (yyn) { case 2: -#line 70 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 72 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { - LOGP("END PARSING\n"); - d->m_result = (yystack_[0].value.sd); + // It's possible that we end up with no query (e.g.: because just a + // date filter was set, no terms). Allocate an empty query so that we + // have something to set the global criteria on (this will yield a + // Xapian search like FILTER xxx + if ((yystack_[0].value.sd) == 0) + d->m_result = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); + else + d->m_result = (yystack_[0].value.sd); } -#line 656 "y.tab.c" // lalr1.cc:847 +#line 664 "y.tab.c" // lalr1.cc:847 break; case 3: -#line 77 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 85 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("q: query query\n"); - Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); - addSubQuery(d, sd, (yystack_[1].value.sd)); - addSubQuery(d, sd, (yystack_[0].value.sd)); + Rcl::SearchData *sd = 0; + if ((yystack_[1].value.sd) || (yystack_[0].value.sd)) { + sd = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); + addSubQuery(d, sd, (yystack_[1].value.sd)); + addSubQuery(d, sd, (yystack_[0].value.sd)); + } (yylhs.value.sd) = sd; } -#line 668 "y.tab.c" // lalr1.cc:847 +#line 679 "y.tab.c" // lalr1.cc:847 break; case 4: -#line 85 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 96 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("q: query AND query\n"); - Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); - addSubQuery(d, sd, (yystack_[2].value.sd)); - addSubQuery(d, sd, (yystack_[0].value.sd)); + Rcl::SearchData *sd = 0; + if ((yystack_[2].value.sd) || (yystack_[0].value.sd)) { + sd = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); + addSubQuery(d, sd, (yystack_[2].value.sd)); + addSubQuery(d, sd, (yystack_[0].value.sd)); + } (yylhs.value.sd) = sd; } -#line 680 "y.tab.c" // lalr1.cc:847 - break; - - case 5: -#line 93 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 - { - LOGP("q: query OR query\n"); - Rcl::SearchData *top = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); - Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_OR, d->m_stemlang); - addSubQuery(d, sd, (yystack_[2].value.sd)); - addSubQuery(d, sd, (yystack_[0].value.sd)); - addSubQuery(d, top, sd); - (yylhs.value.sd) = top; -} #line 694 "y.tab.c" // lalr1.cc:847 break; + case 5: +#line 107 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 + { + LOGP("query: query OR query\n"); + Rcl::SearchData *top = 0; + if ((yystack_[2].value.sd) || (yystack_[0].value.sd)) { + top = new Rcl::SearchData(Rcl::SCLT_OR, d->m_stemlang); + addSubQuery(d, top, (yystack_[2].value.sd)); + addSubQuery(d, top, (yystack_[0].value.sd)); + } + (yylhs.value.sd) = top; +} +#line 709 "y.tab.c" // lalr1.cc:847 + break; + case 6: -#line 103 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 118 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("q: ( query )\n"); (yylhs.value.sd) = (yystack_[1].value.sd); } -#line 703 "y.tab.c" // lalr1.cc:847 +#line 718 "y.tab.c" // lalr1.cc:847 break; case 7: -#line 109 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 124 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("q: fieldexpr\n"); Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); - d->addClause(sd, (yystack_[0].value.cl)); - (yylhs.value.sd) = sd; + if (d->addClause(sd, (yystack_[0].value.cl))) { + (yylhs.value.sd) = sd; + } else { + delete sd; + (yylhs.value.sd) = 0; + } } -#line 714 "y.tab.c" // lalr1.cc:847 +#line 733 "y.tab.c" // lalr1.cc:847 break; case 8: -#line 118 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 137 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("fe: simple fieldexpr: " << (yystack_[0].value.cl)->gettext() << endl); (yylhs.value.cl) = (yystack_[0].value.cl); } -#line 723 "y.tab.c" // lalr1.cc:847 +#line 742 "y.tab.c" // lalr1.cc:847 break; case 9: -#line 123 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 142 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("fe: " << *(yystack_[2].value.str) << " = " << (yystack_[0].value.cl)->gettext() << endl); (yystack_[0].value.cl)->setfield(*(yystack_[2].value.str)); @@ -731,11 +750,11 @@ namespace yy { (yylhs.value.cl) = (yystack_[0].value.cl); delete (yystack_[2].value.str); } -#line 735 "y.tab.c" // lalr1.cc:847 +#line 754 "y.tab.c" // lalr1.cc:847 break; case 10: -#line 131 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 150 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("fe: " << *(yystack_[2].value.str) << " : " << (yystack_[0].value.cl)->gettext() << endl); (yystack_[0].value.cl)->setfield(*(yystack_[2].value.str)); @@ -743,11 +762,11 @@ namespace yy { (yylhs.value.cl) = (yystack_[0].value.cl); delete (yystack_[2].value.str); } -#line 747 "y.tab.c" // lalr1.cc:847 +#line 766 "y.tab.c" // lalr1.cc:847 break; case 11: -#line 139 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 158 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP(cerr << "fe: " << *(yystack_[2].value.str) << " < " << (yystack_[0].value.cl)->gettext() << endl); (yystack_[0].value.cl)->setfield(*(yystack_[2].value.str)); @@ -755,11 +774,11 @@ namespace yy { (yylhs.value.cl) = (yystack_[0].value.cl); delete (yystack_[2].value.str); } -#line 759 "y.tab.c" // lalr1.cc:847 +#line 778 "y.tab.c" // lalr1.cc:847 break; case 12: -#line 147 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 166 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("fe: " << *(yystack_[2].value.str) << " <= " << (yystack_[0].value.cl)->gettext() << endl); (yystack_[0].value.cl)->setfield(*(yystack_[2].value.str)); @@ -767,11 +786,11 @@ namespace yy { (yylhs.value.cl) = (yystack_[0].value.cl); delete (yystack_[2].value.str); } -#line 771 "y.tab.c" // lalr1.cc:847 +#line 790 "y.tab.c" // lalr1.cc:847 break; case 13: -#line 155 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 174 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("fe: " << *(yystack_[2].value.str) << " > " << (yystack_[0].value.cl)->gettext() << endl); (yystack_[0].value.cl)->setfield(*(yystack_[2].value.str)); @@ -779,11 +798,11 @@ namespace yy { (yylhs.value.cl) = (yystack_[0].value.cl); delete (yystack_[2].value.str); } -#line 783 "y.tab.c" // lalr1.cc:847 +#line 802 "y.tab.c" // lalr1.cc:847 break; case 14: -#line 163 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 182 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("fe: " << *(yystack_[2].value.str) << " >= " << (yystack_[0].value.cl)->gettext() << endl); (yystack_[0].value.cl)->setfield(*(yystack_[2].value.str)); @@ -791,69 +810,69 @@ namespace yy { (yylhs.value.cl) = (yystack_[0].value.cl); delete (yystack_[2].value.str); } -#line 795 "y.tab.c" // lalr1.cc:847 +#line 814 "y.tab.c" // lalr1.cc:847 break; case 15: -#line 171 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 190 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("fe: - fieldexpr[" << (yystack_[0].value.cl)->gettext() << "]" << endl); (yystack_[0].value.cl)->setexclude(true); (yylhs.value.cl) = (yystack_[0].value.cl); } -#line 805 "y.tab.c" // lalr1.cc:847 +#line 824 "y.tab.c" // lalr1.cc:847 break; case 16: -#line 181 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 200 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("cfn: WORD" << endl); (yylhs.value.str) = (yystack_[0].value.str); } -#line 814 "y.tab.c" // lalr1.cc:847 +#line 833 "y.tab.c" // lalr1.cc:847 break; case 17: -#line 187 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 206 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("cfn: complexfieldname ':' WORD" << endl); (yylhs.value.str) = new string(*(yystack_[2].value.str) + string(":") + *(yystack_[0].value.str)); delete (yystack_[2].value.str); delete (yystack_[0].value.str); } -#line 825 "y.tab.c" // lalr1.cc:847 +#line 844 "y.tab.c" // lalr1.cc:847 break; case 18: -#line 196 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 215 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("term[" << *(yystack_[0].value.str) << "]" << endl); (yylhs.value.cl) = new Rcl::SearchDataClauseSimple(Rcl::SCLT_AND, *(yystack_[0].value.str)); delete (yystack_[0].value.str); } -#line 835 "y.tab.c" // lalr1.cc:847 +#line 854 "y.tab.c" // lalr1.cc:847 break; case 19: -#line 202 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 221 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { (yylhs.value.cl) = (yystack_[0].value.cl); } -#line 843 "y.tab.c" // lalr1.cc:847 +#line 862 "y.tab.c" // lalr1.cc:847 break; case 20: -#line 208 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 227 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("QUOTED[" << *(yystack_[0].value.str) << "]" << endl); (yylhs.value.cl) = new Rcl::SearchDataClauseDist(Rcl::SCLT_PHRASE, *(yystack_[0].value.str), 0); delete (yystack_[0].value.str); } -#line 853 "y.tab.c" // lalr1.cc:847 +#line 872 "y.tab.c" // lalr1.cc:847 break; case 21: -#line 214 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 +#line 233 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:847 { LOGP("QUOTED[" << *(yystack_[1].value.str) << "] QUALIFIERS[" << *(yystack_[0].value.str) << "]" << endl); Rcl::SearchDataClauseDist *cl = @@ -863,11 +882,11 @@ namespace yy { delete (yystack_[1].value.str); delete (yystack_[0].value.str); } -#line 867 "y.tab.c" // lalr1.cc:847 +#line 886 "y.tab.c" // lalr1.cc:847 break; -#line 871 "y.tab.c" // lalr1.cc:847 +#line 890 "y.tab.c" // lalr1.cc:847 default: break; } @@ -1220,9 +1239,9 @@ namespace yy { const unsigned char parser::yyrline_[] = { - 0, 69, 69, 76, 84, 92, 102, 108, 117, 122, - 130, 138, 146, 154, 162, 170, 180, 186, 195, 201, - 207, 213 + 0, 71, 71, 84, 95, 106, 117, 123, 136, 141, + 149, 157, 165, 173, 181, 189, 199, 205, 214, 220, + 226, 232 }; // Print the state stack on the debug stream. @@ -1304,8 +1323,8 @@ namespace yy { } // yy -#line 1308 "y.tab.c" // lalr1.cc:1155 -#line 225 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:1156 +#line 1327 "y.tab.c" // lalr1.cc:1155 +#line 244 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:1156 #include diff --git a/src/query/wasaparse.hpp b/src/query/wasaparse.hpp index 93928ba1..186bc4f5 100644 --- a/src/query/wasaparse.hpp +++ b/src/query/wasaparse.hpp @@ -123,7 +123,7 @@ namespace yy { /// Symbol semantic values. union semantic_type { - #line 44 "/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:372 + #line 46 "/y/home/dockes/projets/fulltext/recoll/src/query/wasaparse.ypp" // lalr1.cc:372 std::string *str; Rcl::SearchDataClauseSimple *cl; diff --git a/src/query/wasaparse.ypp b/src/query/wasaparse.ypp index 92fad1a1..9725f6d8 100644 --- a/src/query/wasaparse.ypp +++ b/src/query/wasaparse.ypp @@ -28,7 +28,9 @@ static void qualify(Rcl::SearchDataClauseDist *, const string &); static void addSubQuery(WasaParserDriver *d, Rcl::SearchData *sd, Rcl::SearchData *sq) { - sd->addClause(new Rcl::SearchDataClauseSub(STD_SHARED_PTR(sq))); + if (sd && sq) + sd->addClause( + new Rcl::SearchDataClauseSub(STD_SHARED_PTR(sq))); } %} @@ -54,8 +56,8 @@ static void addSubQuery(WasaParserDriver *d, %type query %type complexfieldname - /* Non operator tokens need precedence because of the possibility of - concatenation which needs to have lower prec than OR */ +/* Non operator tokens need precedence because of the possibility of + concatenation which needs to have lower prec than OR */ %left WORD %left QUOTED %left QUALIFIERS @@ -68,35 +70,48 @@ static void addSubQuery(WasaParserDriver *d, topquery: query { - LOGP("END PARSING\n"); - d->m_result = $1; + // It's possible that we end up with no query (e.g.: because just a + // date filter was set, no terms). Allocate an empty query so that we + // have something to set the global criteria on (this will yield a + // Xapian search like FILTER xxx + if ($1 == 0) + d->m_result = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); + else + d->m_result = $1; } query: query query %prec UCONCAT { LOGP("q: query query\n"); - Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); - addSubQuery(d, sd, $1); - addSubQuery(d, sd, $2); + Rcl::SearchData *sd = 0; + if ($1 || $2) { + sd = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); + addSubQuery(d, sd, $1); + addSubQuery(d, sd, $2); + } $$ = sd; } | query AND query { LOGP("q: query AND query\n"); - Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); - addSubQuery(d, sd, $1); - addSubQuery(d, sd, $3); + Rcl::SearchData *sd = 0; + if ($1 || $3) { + sd = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); + addSubQuery(d, sd, $1); + addSubQuery(d, sd, $3); + } $$ = sd; } | query OR query { - LOGP("q: query OR query\n"); - Rcl::SearchData *top = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); - Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_OR, d->m_stemlang); - addSubQuery(d, sd, $1); - addSubQuery(d, sd, $3); - addSubQuery(d, top, sd); + LOGP("query: query OR query\n"); + Rcl::SearchData *top = 0; + if ($1 || $3) { + top = new Rcl::SearchData(Rcl::SCLT_OR, d->m_stemlang); + addSubQuery(d, top, $1); + addSubQuery(d, top, $3); + } $$ = top; } | '(' query ')' @@ -109,8 +124,12 @@ fieldexpr %prec UCONCAT { LOGP("q: fieldexpr\n"); Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_AND, d->m_stemlang); - d->addClause(sd, $1); - $$ = sd; + if (d->addClause(sd, $1)) { + $$ = sd; + } else { + delete sd; + $$ = 0; + } } ; diff --git a/src/query/wasaparseaux.cpp b/src/query/wasaparseaux.cpp index 22a11ee7..aa6b4fed 100644 --- a/src/query/wasaparseaux.cpp +++ b/src/query/wasaparseaux.cpp @@ -51,6 +51,19 @@ SearchData *wasaStringToRcl(const RclConfig *config, return sd; } +WasaParserDriver::WasaParserDriver(const RclConfig *c, const std::string sl, + const std::string& as) + : m_stemlang(sl), m_autosuffs(as), m_config(c), + m_index(0), m_result(0), m_haveDates(false), + m_maxSize((size_t)-1), m_minSize((size_t)-1) +{ + +} + +WasaParserDriver::~WasaParserDriver() +{ +} + SearchData *WasaParserDriver::parse(const std::string& in) { m_input = in; @@ -67,6 +80,28 @@ SearchData *WasaParserDriver::parse(const std::string& in) m_result = 0; } + if (m_result == 0) + return m_result; + + // Set the top level filters (types, dates, size) + for (vector::const_iterator it = m_filetypes.begin(); + it != m_filetypes.end(); it++) { + m_result->addFiletype(*it); + } + for (vector::const_iterator it = m_nfiletypes.begin(); + it != m_nfiletypes.end(); it++) { + m_result->remFiletype(*it); + } + if (m_haveDates) { + m_result->setDateSpan(&m_dates); + } + if (m_minSize != (size_t)-1) { + m_result->setMinSize(m_minSize); + } + if (m_maxSize != (size_t)-1) { + m_result->setMaxSize(m_maxSize); + } + //if (m_result) m_result->dump(cout); return m_result; } @@ -114,12 +149,12 @@ bool WasaParserDriver::addClause(SearchData *sd, // MIME types and categories if (!fld.compare("mime") || !fld.compare("format")) { if (cl->getexclude()) { - sd->remFiletype(cl->gettext()); + m_nfiletypes.push_back(cl->gettext()); } else { - sd->addFiletype(cl->gettext()); + m_filetypes.push_back(cl->gettext()); } delete cl; - return true; + return false; } if (!fld.compare("rclcat") || !fld.compare("type")) { @@ -128,14 +163,14 @@ bool WasaParserDriver::addClause(SearchData *sd, for (vector::iterator mit = mtypes.begin(); mit != mtypes.end(); mit++) { if (cl->getexclude()) { - sd->remFiletype(*mit); + m_nfiletypes.push_back(*mit); } else { - sd->addFiletype(*mit); + m_filetypes.push_back(*mit); } } } delete cl; - return true; + return false; } // Handle "date" spec @@ -150,9 +185,10 @@ bool WasaParserDriver::addClause(SearchData *sd, } LOGDEB(("addClause:: date span: %d-%d-%d/%d-%d-%d\n", di.y1,di.m1,di.d1, di.y2,di.m2,di.d2)); - sd->setDateSpan(&di); + m_haveDates = true; + m_dates = di; delete cl; - return true; + return false; } // Handle "size" spec @@ -178,22 +214,21 @@ bool WasaParserDriver::addClause(SearchData *sd, switch (rel) { case SearchDataClause::REL_EQUALS: - sd->setMaxSize(size); - sd->setMinSize(size); + m_maxSize = m_minSize = size; break; case SearchDataClause::REL_LT: case SearchDataClause::REL_LTE: - sd->setMaxSize(size); + m_maxSize = size; break; case SearchDataClause::REL_GT: case SearchDataClause::REL_GTE: - sd->setMinSize(size); + m_minSize = size; break; default: m_reason = "Bad relation operator with size query. Use > < or ="; return false; } - return true; + return false; } if (!fld.compare("dir")) { diff --git a/src/query/wasaparserdriver.h b/src/query/wasaparserdriver.h index da6fe6dd..8c5a35b9 100644 --- a/src/query/wasaparserdriver.h +++ b/src/query/wasaparserdriver.h @@ -19,6 +19,9 @@ #include #include +#include + +#include "smallut.h" class WasaParserDriver; namespace Rcl { @@ -35,10 +38,9 @@ class WasaParserDriver { public: WasaParserDriver(const RclConfig *c, const std::string sl, - const std::string& as) - : m_stemlang(sl), m_autosuffs(as), m_config(c), - m_index(0), m_result(0) {} - + const std::string& as); + ~WasaParserDriver(); + Rcl::SearchData *parse(const std::string&); bool addClause(Rcl::SearchData *sd, Rcl::SearchDataClauseSimple* cl); @@ -62,11 +64,23 @@ private: std::string m_autosuffs; const RclConfig *m_config; + // input string. std::string m_input; + // Current position in m_input unsigned int m_index; + // Characters pushed-back, ready for next getchar. std::stack m_returns; + // Result, set by parser. Rcl::SearchData *m_result; + // Storage for top level filters + std::vector m_filetypes; + std::vector m_nfiletypes; + bool m_haveDates; + DateInterval m_dates; // Restrict to date interval + size_t m_maxSize; + size_t m_minSize; + std::string m_reason; // Let the quoted string reader store qualifiers in there, simpler diff --git a/src/rcldb/searchdata.cpp b/src/rcldb/searchdata.cpp index cc2be91c..b192787d 100644 --- a/src/rcldb/searchdata.cpp +++ b/src/rcldb/searchdata.cpp @@ -210,14 +210,35 @@ void SearchData::simplify() clsubp->getSub()->simplify(); // If this subquery has special attributes, it's not a - // candidate for collapsing + // candidate for collapsing, except if it has no clauses, because + // then, we just pick the attributes. if (!clsubp->getSub()->m_filetypes.empty() || !clsubp->getSub()->m_nfiletypes.empty() || clsubp->getSub()->m_haveDates || clsubp->getSub()->m_maxSize != size_t(-1) || clsubp->getSub()->m_minSize != size_t(-1) || - clsubp->getSub()->m_haveWildCards) - continue; + clsubp->getSub()->m_haveWildCards) { + if (!clsubp->getSub()->m_query.empty()) + continue; + m_filetypes.insert(m_filetypes.end(), + clsubp->getSub()->m_filetypes.begin(), + clsubp->getSub()->m_filetypes.end()); + m_nfiletypes.insert(m_nfiletypes.end(), + clsubp->getSub()->m_nfiletypes.begin(), + clsubp->getSub()->m_nfiletypes.end()); + if (clsubp->getSub()->m_haveDates && !m_haveDates) { + m_dates = clsubp->getSub()->m_dates; + } + if (m_maxSize == size_t(-1)) + m_maxSize = clsubp->getSub()->m_maxSize; + if (m_minSize == size_t(-1)) + m_minSize = clsubp->getSub()->m_minSize; + m_haveWildCards = m_haveWildCards || + clsubp->getSub()->m_haveWildCards; + // And then let the clauses processing go on, there are + // none anyway, we will just delete the subquery. + } + bool allsametp = true; for (qlist_it_t it1 = clsubp->getSub()->m_query.begin(); @@ -277,18 +298,22 @@ static const char * tpToString(SClType t) } } +static string dumptabs; + void SearchData::dump(ostream& o) const { - o << "SearchData: " << tpToString(m_tp) << " qs " << int(m_query.size()) << + o << dumptabs << + "SearchData: " << tpToString(m_tp) << " qs " << int(m_query.size()) << " ft " << m_filetypes.size() << " nft " << m_nfiletypes.size() << " hd " << m_haveDates << " maxs " << int(m_maxSize) << " mins " << int(m_minSize) << " wc " << m_haveWildCards << "\n"; for (std::vector::const_iterator it = m_query.begin(); it != m_query.end(); it++) { + o << dumptabs; (*it)->dump(o); o << "\n"; } - o << "\n"; +// o << dumptabs << "\n"; } void SearchDataClause::dump(ostream& o) const @@ -341,8 +366,10 @@ void SearchDataClauseDist::dump(ostream& o) const void SearchDataClauseSub::dump(ostream& o) const { o << "ClauseSub {\n"; + dumptabs += '\t'; m_sub->dump(o); - o << "}"; + dumptabs.erase(dumptabs.size()- 1); + o << dumptabs << "}"; } } // Namespace Rcl