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);
 }