You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2012/06/29 07:33:58 UTC
[lucy-commits] svn commit: r1355241 - in /lucy/trunk/core/Lucy/Search: QueryParser.c
QueryParser.cfh QueryParser/ParserElem.c QueryParser/ParserElem.cfh
Author: marvin
Date: Fri Jun 29 05:33:57 2012
New Revision: 1355241
URL: http://svn.apache.org/viewvc?rev=1355241&view=rev
Log:
Consolidate ParserClause into ParserElem.
Modified:
lucy/trunk/core/Lucy/Search/QueryParser.c
lucy/trunk/core/Lucy/Search/QueryParser.cfh
lucy/trunk/core/Lucy/Search/QueryParser/ParserElem.c
lucy/trunk/core/Lucy/Search/QueryParser/ParserElem.cfh
Modified: lucy/trunk/core/Lucy/Search/QueryParser.c
URL: http://svn.apache.org/viewvc/lucy/trunk/core/Lucy/Search/QueryParser.c?rev=1355241&r1=1355240&r2=1355241&view=diff
==============================================================================
--- lucy/trunk/core/Lucy/Search/QueryParser.c (original)
+++ lucy/trunk/core/Lucy/Search/QueryParser.c Fri Jun 29 05:33:57 2012
@@ -15,7 +15,6 @@
*/
#define C_LUCY_QUERYPARSER
-#define C_LUCY_PARSERCLAUSE
#define C_LUCY_VIEWCHARBUF
#include <stdlib.h>
#include <ctype.h>
@@ -49,6 +48,7 @@
#define TOKEN_AND LUCY_QPARSER_TOKEN_AND
#define TOKEN_FIELD LUCY_QPARSER_TOKEN_FIELD
#define TOKEN_STRING LUCY_QPARSER_TOKEN_STRING
+#define TOKEN_QUERY LUCY_QPARSER_TOKEN_QUERY
// Recursing helper function for Tree().
static Query*
@@ -371,11 +371,11 @@ S_do_tree(QueryParser *self, CharBuf *qu
if (CB_Starts_With(text, self->phrase_label)) {
CharBuf *inner_text
= (CharBuf*)Hash_Fetch(extractions, (Obj*)text);
- Query *query = (Query*)LeafQuery_new(field, inner_text);
- ParserClause *clause = ParserClause_new(query, default_occur);
+ LeafQuery *query = LeafQuery_new(field, inner_text);
+ ParserElem *new_elem = ParserElem_new(TOKEN_QUERY, (Obj*)query);
+ ParserElem_Set_Occur(new_elem, default_occur);
DECREF(Hash_Delete(extractions, (Obj*)text));
- VA_Store(elems, i, (Obj*)clause);
- DECREF(query);
+ VA_Store(elems, i, (Obj*)new_elem);
}
// Recursively parse parenthetical groupings.
else if (CB_Starts_With(text, self->bool_group_label)) {
@@ -385,18 +385,19 @@ S_do_tree(QueryParser *self, CharBuf *qu
= S_do_tree(self, inner_text, field, extractions);
DECREF(Hash_Delete(extractions, (Obj*)text));
if (query) {
- ParserClause *clause
- = ParserClause_new(query, default_occur);
- VA_Store(elems, i, (Obj*)clause);
- DECREF(query);
+ ParserElem *new_elem
+ = ParserElem_new(TOKEN_QUERY, (Obj*)query);
+ ParserElem_Set_Occur(new_elem, default_occur);
+ VA_Store(elems, i, (Obj*)new_elem);
}
}
// What's left is probably a term, so generate a LeafQuery.
else {
- Query *query = (Query*)LeafQuery_new(field, text);
- ParserClause *clause = ParserClause_new(query, default_occur);
- VA_Store(elems, i, (Obj*)clause);
- DECREF(query);
+ LeafQuery *query = LeafQuery_new(field, text);
+ ParserElem *new_elem
+ = ParserElem_new(TOKEN_QUERY, (Obj*)query);
+ ParserElem_Set_Occur(new_elem, default_occur);
+ VA_Store(elems, i, (Obj*)new_elem);
}
}
}
@@ -404,22 +405,16 @@ S_do_tree(QueryParser *self, CharBuf *qu
// Apply +, -, NOT.
for (uint32_t i = VA_Get_Size(elems); i--;) {
- ParserClause *clause = (ParserClause*)VA_Fetch(elems, i);
- if (Obj_Is_A((Obj*)clause, PARSERCLAUSE)) {
+ ParserElem *elem = (ParserElem*)VA_Fetch(elems, i);
+ if (ParserElem_Get_Type(elem) == TOKEN_QUERY) {
for (uint32_t j = i; j--;) {
- ParserElem *elem = (ParserElem*)VA_Fetch(elems, j);
- if (Obj_Is_A((Obj*)elem, PARSERELEM)) {
- uint32_t type = ParserElem_Get_Type(elem);
- if (type == TOKEN_MINUS || type == TOKEN_NOT) {
- clause->occur = clause->occur == MUST_NOT
- ? MUST
- : MUST_NOT;
- }
- else if (type == TOKEN_PLUS) {
- if (clause->occur == SHOULD) {
- clause->occur = MUST;
- }
- }
+ ParserElem *prev = (ParserElem*)VA_Fetch(elems, j);
+ uint32_t prev_type = ParserElem_Get_Type(prev);
+ if (prev_type == TOKEN_MINUS || prev_type == TOKEN_NOT) {
+ ParserElem_Negate(elem);
+ }
+ else if (prev_type == TOKEN_PLUS) {
+ ParserElem_Require(elem);
}
else {
break;
@@ -431,11 +426,14 @@ S_do_tree(QueryParser *self, CharBuf *qu
// Wrap negated queries with NOTQuery objects.
for (uint32_t i = 0, max = VA_Get_Size(elems); i < max; i++) {
- ParserClause *clause = (ParserClause*)VA_Fetch(elems, i);
- if (Obj_Is_A((Obj*)clause, PARSERCLAUSE) && clause->occur == MUST_NOT) {
- Query *not_query = QParser_Make_NOT_Query(self, clause->query);
- DECREF(clause->query);
- clause->query = not_query;
+ ParserElem *elem = (ParserElem*)VA_Fetch(elems, i);
+ if (ParserElem_Get_Type(elem) == TOKEN_QUERY
+ && ParserElem_Get_Occur(elem) == MUST_NOT
+ ) {
+ Query *inner_query = (Query*)ParserElem_As(elem, QUERY);
+ Query *not_query = QParser_Make_NOT_Query(self, inner_query);
+ ParserElem_Set_Value(elem, (Obj*)not_query);
+ DECREF(not_query);
}
}
@@ -443,19 +441,19 @@ S_do_tree(QueryParser *self, CharBuf *qu
// 'OR a AND AND OR b AND'.
for (uint32_t i = 0; i < VA_Get_Size(elems); i++) {
ParserElem *elem = (ParserElem*)VA_Fetch(elems, i);
- if (Obj_Is_A((Obj*)elem, PARSERELEM)) {
+ if (ParserElem_Get_Type(elem) != TOKEN_QUERY) {
uint32_t num_to_zap = 0;
- ParserClause *preceding = (ParserClause*)VA_Fetch(elems, i - 1);
- ParserClause *following = (ParserClause*)VA_Fetch(elems, i + 1);
- if (!preceding || !Obj_Is_A((Obj*)preceding, PARSERCLAUSE)) {
+ ParserElem *preceding = (ParserElem*)VA_Fetch(elems, i - 1);
+ ParserElem *following = (ParserElem*)VA_Fetch(elems, i + 1);
+ if (!preceding || ParserElem_Get_Type(preceding) != TOKEN_QUERY) {
num_to_zap = 1;
}
- if (!following || !Obj_Is_A((Obj*)following, PARSERCLAUSE)) {
+ if (!following || ParserElem_Get_Type(following) != TOKEN_QUERY) {
num_to_zap = 1;
}
for (uint32_t j = i + 1, jmax = VA_Get_Size(elems); j < jmax; j++) {
- ParserClause *clause = (ParserClause*)VA_Fetch(elems, j);
- if (Obj_Is_A((Obj*)clause, PARSERCLAUSE)) { break; }
+ ParserElem *maybe = (ParserElem*)VA_Fetch(elems, j);
+ if (ParserElem_Get_Type(maybe) == TOKEN_QUERY) { break; }
else { num_to_zap++; }
}
if (num_to_zap) { VA_Excise(elems, i, num_to_zap); }
@@ -465,37 +463,38 @@ S_do_tree(QueryParser *self, CharBuf *qu
// Apply AND.
for (uint32_t i = 0; i + 2 < VA_Get_Size(elems); i++) {
ParserElem *elem = (ParserElem*)VA_Fetch(elems, i + 1);
- if (Obj_Is_A((Obj*)elem, PARSERELEM)
- && ParserElem_Get_Type(elem) == TOKEN_AND
- ) {
- ParserClause *preceding = (ParserClause*)VA_Fetch(elems, i);
+ if (ParserElem_Get_Type(elem) == TOKEN_AND) {
+ ParserElem *preceding = (ParserElem*)VA_Fetch(elems, i);
VArray *children = VA_new(2);
uint32_t num_to_zap = 0;
// Add first clause.
- VA_Push(children, INCREF(preceding->query));
+ Query *preceding_query = (Query*)ParserElem_As(preceding, QUERY);
+ VA_Push(children, INCREF(preceding_query));
// Add following clauses.
for (uint32_t j = i + 1, jmax = VA_Get_Size(elems);
j < jmax;
j += 2, num_to_zap += 2
) {
- ParserElem *maybe_and = (ParserElem*)VA_Fetch(elems, j);
- ParserClause *following
- = (ParserClause*)VA_Fetch(elems, j + 1);
- if (!Obj_Is_A((Obj*)maybe_and, PARSERELEM)
- || ParserElem_Get_Type(maybe_and) != TOKEN_AND
- ) {
+ ParserElem *maybe_and = (ParserElem*)VA_Fetch(elems, j);
+ ParserElem *following = (ParserElem*)VA_Fetch(elems, j + 1);
+ if (ParserElem_Get_Type(maybe_and) != TOKEN_AND) {
break;
}
+ else if (ParserElem_Get_Type(following) == TOKEN_QUERY) {
+ Query *next = (Query*)ParserElem_As(following, QUERY);
+ VA_Push(children, INCREF(next));
+ }
else {
- CERTIFY(following, PARSERCLAUSE);
+ THROW(ERR, "Unexpected type: %u32",
+ ParserElem_Get_Type(following));
}
- VA_Push(children, INCREF(following->query));
}
- DECREF(preceding->query);
- preceding->query = QParser_Make_AND_Query(self, children);
- preceding->occur = default_occur;
+ Query *and_query = QParser_Make_AND_Query(self, children);
+ ParserElem_Set_Value(preceding, (Obj*)and_query);
+ ParserElem_Set_Occur(preceding, default_occur);
+ DECREF(and_query);
DECREF(children);
VA_Excise(elems, i + 1, num_to_zap);
@@ -508,36 +507,38 @@ S_do_tree(QueryParser *self, CharBuf *qu
// Apply OR.
for (uint32_t i = 0; i + 2 < VA_Get_Size(elems); i++) {
ParserElem *elem = (ParserElem*)VA_Fetch(elems, i + 1);
- if (Obj_Is_A((Obj*)elem, PARSERELEM)
- && ParserElem_Get_Type(elem) == TOKEN_OR) {
- ParserClause *preceding = (ParserClause*)VA_Fetch(elems, i);
+ if (ParserElem_Get_Type(elem) == TOKEN_OR) {
+ ParserElem *preceding = (ParserElem*)VA_Fetch(elems, i);
VArray *children = VA_new(2);
uint32_t num_to_zap = 0;
// Add first clause.
- VA_Push(children, INCREF(preceding->query));
+ Query *preceding_query = (Query*)ParserElem_As(preceding, QUERY);
+ VA_Push(children, INCREF(preceding_query));
// Add following clauses.
for (uint32_t j = i + 1, jmax = VA_Get_Size(elems);
j < jmax;
j += 2, num_to_zap += 2
) {
- ParserElem *maybe_or = (ParserElem*)VA_Fetch(elems, j);
- ParserClause *following
- = (ParserClause*)VA_Fetch(elems, j + 1);
- if (!Obj_Is_A((Obj*)maybe_or, PARSERELEM)
- || ParserElem_Get_Type(maybe_or) != TOKEN_OR
- ) {
+ ParserElem *maybe_or = (ParserElem*)VA_Fetch(elems, j);
+ ParserElem *following = (ParserElem*)VA_Fetch(elems, j + 1);
+ if (ParserElem_Get_Type(maybe_or) != TOKEN_OR) {
break;
}
+ else if (ParserElem_Get_Type(following) == TOKEN_QUERY) {
+ Query *next = (Query*)ParserElem_As(following, QUERY);
+ VA_Push(children, INCREF(next));
+ }
else {
- CERTIFY(following, PARSERCLAUSE);
+ THROW(ERR, "Unexpected type: %u32",
+ ParserElem_Get_Type(following));
}
- VA_Push(children, INCREF(following->query));
}
- DECREF(preceding->query);
- preceding->query = QParser_Make_OR_Query(self, children);
- preceding->occur = default_occur;
+ Query *or_query = QParser_Make_OR_Query(self, children);
+ ParserElem_Set_Value(preceding, (Obj*)or_query);
+ ParserElem_Set_Occur(preceding, default_occur);
+ DECREF(or_query);
DECREF(children);
VA_Excise(elems, i + 1, num_to_zap);
@@ -560,8 +561,9 @@ S_do_tree(QueryParser *self, CharBuf *qu
}
}
else if (VA_Get_Size(elems) == 1 && !apply_parens) {
- ParserClause *clause = (ParserClause*)VA_Fetch(elems, 0);
- retval = (Query*)INCREF(clause->query);
+ ParserElem *elem = (ParserElem*)VA_Fetch(elems, 0);
+ Query *query = (Query*)ParserElem_As(elem, QUERY);
+ retval = (Query*)INCREF(query);
}
else {
uint32_t num_elems = VA_Get_Size(elems);
@@ -573,15 +575,17 @@ S_do_tree(QueryParser *self, CharBuf *qu
// Demux elems into bins.
for (uint32_t i = 0; i < num_elems; i++) {
- ParserClause *clause = (ParserClause*)VA_Fetch(elems, i);
- if (clause->occur == MUST) {
- VA_Push(required, INCREF(clause->query));
+ ParserElem *elem = (ParserElem*)VA_Fetch(elems, i);
+ uint32_t occur = ParserElem_Get_Occur(elem);
+ Query *query = (Query*)ParserElem_As(elem, QUERY);
+ if (occur == MUST) {
+ VA_Push(required, INCREF(query));
}
- else if (clause->occur == SHOULD) {
- VA_Push(optional, INCREF(clause->query));
+ else if (occur == SHOULD) {
+ VA_Push(optional, INCREF(query));
}
- else if (clause->occur == MUST_NOT) {
- VA_Push(negated, INCREF(clause->query));
+ else if (occur == MUST_NOT) {
+ VA_Push(negated, INCREF(query));
}
}
uint32_t num_required = VA_Get_Size(required);
@@ -1193,24 +1197,3 @@ QParser_make_req_opt_query(QueryParser *
return (Query*)ReqOptQuery_new(required_query, optional_query);
}
-/********************************************************************/
-
-ParserClause*
-ParserClause_new(Query *query, uint32_t occur) {
- ParserClause *self = (ParserClause*)VTable_Make_Obj(PARSERCLAUSE);
- return ParserClause_init(self, query, occur);
-}
-
-ParserClause*
-ParserClause_init(ParserClause *self, Query *query, uint32_t occur) {
- self->query = (Query*)INCREF(query);
- self->occur = occur;
- return self;
-}
-
-void
-ParserClause_destroy(ParserClause *self) {
- DECREF(self->query);
- SUPER_DESTROY(self, PARSERCLAUSE);
-}
-
Modified: lucy/trunk/core/Lucy/Search/QueryParser.cfh
URL: http://svn.apache.org/viewvc/lucy/trunk/core/Lucy/Search/QueryParser.cfh?rev=1355241&r1=1355240&r2=1355241&view=diff
==============================================================================
--- lucy/trunk/core/Lucy/Search/QueryParser.cfh (original)
+++ lucy/trunk/core/Lucy/Search/QueryParser.cfh Fri Jun 29 05:33:57 2012
@@ -227,23 +227,6 @@ public class Lucy::Search::QueryParser c
Destroy(QueryParser *self);
}
-/** Private utility class.
- */
-class Lucy::QueryParser::ParserClause inherits Lucy::Object::Obj {
-
- uint32_t occur;
- Query *query;
-
- inert incremented ParserClause*
- new(Query *query, uint32_t occur);
-
- inert ParserClause*
- init(ParserClause *self, Query *query, uint32_t occur);
-
- public void
- Destroy(ParserClause *self);
-}
-
__C__
#define LUCY_QPARSER_SHOULD 0x00000001
@@ -258,6 +241,7 @@ __C__
#define LUCY_QPARSER_TOKEN_AND 0x00000200
#define LUCY_QPARSER_TOKEN_FIELD 0x00000400
#define LUCY_QPARSER_TOKEN_STRING 0x00000800
+#define LUCY_QPARSER_TOKEN_QUERY 0x00001000
__END_C__
Modified: lucy/trunk/core/Lucy/Search/QueryParser/ParserElem.c
URL: http://svn.apache.org/viewvc/lucy/trunk/core/Lucy/Search/QueryParser/ParserElem.c?rev=1355241&r1=1355240&r2=1355241&view=diff
==============================================================================
--- lucy/trunk/core/Lucy/Search/QueryParser/ParserElem.c (original)
+++ lucy/trunk/core/Lucy/Search/QueryParser/ParserElem.c Fri Jun 29 05:33:57 2012
@@ -17,6 +17,7 @@
#define C_LUCY_PARSERELEM
#include "Lucy/Util/ToolSet.h"
#include "Lucy/Search/QueryParser/ParserElem.h"
+#include "Lucy/Search/QueryParser.h"
ParserElem*
ParserElem_new(uint32_t type, Obj *value) {
@@ -28,6 +29,7 @@ ParserElem*
ParserElem_init(ParserElem *self, uint32_t type, Obj *value) {
self->type = type;
self->value = value;
+ self->occur = LUCY_QPARSER_SHOULD;
return self;
}
@@ -37,6 +39,13 @@ ParserElem_destroy(ParserElem *self) {
SUPER_DESTROY(self, PARSERELEM);
}
+void
+ParserElem_set_value(ParserElem *self, Obj *value) {
+ INCREF(value);
+ DECREF(self->value);
+ self->value = value;
+}
+
Obj*
ParserElem_as(ParserElem *self, VTable *metaclass) {
if (self->value && Obj_Is_A(self->value, metaclass)) {
@@ -50,3 +59,56 @@ ParserElem_get_type(ParserElem *self) {
return self->type;
}
+void
+ParserElem_set_occur(ParserElem *self, uint32_t occur) {
+ self->occur = occur;
+}
+
+uint32_t
+ParserElem_get_occur(ParserElem *self) {
+ return self->occur;
+}
+
+void
+ParserElem_require(ParserElem *self) {
+ switch (self->occur) {
+ case LUCY_QPARSER_SHOULD:
+ self->occur = LUCY_QPARSER_MUST;
+ break;
+ case LUCY_QPARSER_MUST_NOT:
+ case LUCY_QPARSER_MUST:
+ break;
+ default:
+ THROW(ERR, "Internal error in value of occur: %u32", self->occur);
+ }
+}
+
+void
+ParserElem_unrequire(ParserElem *self) {
+ switch (self->occur) {
+ case LUCY_QPARSER_MUST:
+ self->occur = LUCY_QPARSER_SHOULD;
+ break;
+ case LUCY_QPARSER_MUST_NOT:
+ case LUCY_QPARSER_SHOULD:
+ break;
+ default:
+ THROW(ERR, "Internal error in value of occur: %u32", self->occur);
+ }
+}
+
+void
+ParserElem_negate(ParserElem *self) {
+ switch (self->occur) {
+ case LUCY_QPARSER_SHOULD:
+ case LUCY_QPARSER_MUST:
+ self->occur = LUCY_QPARSER_MUST_NOT;
+ break;
+ case LUCY_QPARSER_MUST_NOT:
+ self->occur = LUCY_QPARSER_MUST; // Apply double negative.
+ break;
+ default:
+ THROW(ERR, "Internal error in value of occur: %u32", self->occur);
+ }
+}
+
Modified: lucy/trunk/core/Lucy/Search/QueryParser/ParserElem.cfh
URL: http://svn.apache.org/viewvc/lucy/trunk/core/Lucy/Search/QueryParser/ParserElem.cfh?rev=1355241&r1=1355240&r2=1355241&view=diff
==============================================================================
--- lucy/trunk/core/Lucy/Search/QueryParser/ParserElem.cfh (original)
+++ lucy/trunk/core/Lucy/Search/QueryParser/ParserElem.cfh Fri Jun 29 05:33:57 2012
@@ -21,6 +21,7 @@ parcel Lucy;
class Lucy::QueryParser::ParserElem inherits Lucy::Object::Obj {
uint32_t type;
+ uint32_t occur;
Obj *value;
inert incremented ParserElem*
@@ -32,6 +33,9 @@ class Lucy::QueryParser::ParserElem inhe
public void
Destroy(ParserElem *self);
+ void
+ Set_Value(ParserElem *self, Obj *value);
+
/** Return the value of the elem if it matches the specification, NULL
* otherwise.
*/
@@ -40,5 +44,29 @@ class Lucy::QueryParser::ParserElem inhe
uint32_t
Get_Type(ParserElem *self);
+
+ /** Manipulate the value of <code>occur</code> so that the element becomes
+ * forbidden.
+ */
+ void
+ Negate(ParserElem *self);
+
+ /** Manipulate the value of <code>occur</code> so that the element becomes
+ * required.
+ */
+ void
+ Require(ParserElem *self);
+
+ /** If an element is required, make it optional. If it's negated, leave
+ * it as is.
+ */
+ void
+ Unrequire(ParserElem *self);
+
+ void
+ Set_Occur(ParserElem *self, uint32_t occur);
+
+ uint32_t
+ Get_Occur(ParserElem *self);
}