Add unit test for the query parser, fix some bugs in said query parser, and upgrade...
[python-rwhoisd.git] / rwhoisd / QueryParser.py
index 2e2ce6e..7b9ed84 100644 (file)
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 # USA
 
+# This module uses PLY (Python Lex-Yacc).  See
+# http://www.dabeaz.com/ply/ for more info.
+
+# This module is actually the grammar definition.  The lexer finds
+# variables and functions starting with 't_', as well as a list called
+# 'tokens'.  The parser (i.e., yacc) finds things starting with 'p_'.
 
 # queryparser.db must be set to a DB class instance.
 db = None
@@ -50,6 +56,8 @@ def t_firstvalue(t):
 
     if db.is_objectclass(t.value):
         t.type = 'CLASS'
+    elif db.is_attribute(t.value):
+        t.type = 'ATTR'
     else:
         t.type = 'VALUE'
     return t
@@ -57,13 +65,14 @@ def t_firstvalue(t):
 def t_VALUE(t):
     r'\*?[^\s"\'=!*]+\*{0,2}'
 
-    if t.value.upper() == 'AND':
+    v = t.value.upper()
+    if v == 'AND':
         t.type = 'AND'
-        t.value = t.value.upper()
+        t.value = v
         return t
-    if t.value.upper() == 'OR':
+    if v == 'OR':
         t.type = 'OR'
-        t.value = t.value.upper()
+        t.value = v
         return t
     if db.is_attribute(t.value):
         t.type = 'ATTR'
@@ -125,17 +134,18 @@ def p_querystr_attr_value(t):
 
     t[0] = (t[1], t[2], t[3])
 
-def p_querystr_attr(t):
-    'querystr : ATTR'
+def p_querystr_attr_attr(t):
+    '''querystr : ATTR EQ ATTR
+                | ATTR NEQ ATTR'''
 
-    t[0] = (None, '=', t[1])
+    t[0] = (t[1], t[2], t[3])
 
 def p_querystr_value(t):
-    'querystr : value'
+    '''querystr : ATTR
+                | value'''
 
     t[0] = (None, '=', t[1])
 
-
 def p_value(t):
     'value : VALUE'
 
@@ -150,7 +160,6 @@ def p_quotedvalue(t):
 
 
 def p_error(t):
-     # print "Syntax error at '%s:%s'" % (t.type, t.value)
      raise yacc.YaccError, "Syntax error at %r" % t.value
 
     
@@ -223,42 +232,5 @@ def parse(p, query):
     assert db
     try:
         return p.parse(query)
-    except (lex.LexError, yacc.YaccError):
-        raise Rwhois.RwhoisError, (350, "")
-
-if __name__ == "__main__":
-    import sys
-    import MemDB
-
-    mydb = MemDB.MemDB()
-
-    print "loading schema:", sys.argv[1]
-    mydb.init_schema(sys.argv[1])
-    for data_file in sys.argv[2:]:
-        print "loading data file:", data_file
-        mydb.load_data(data_file)
-    mydb.index_data()
-
-    db = mydb
-    qp = get_parser()
-    
-    for line in sys.stdin.readlines():
-        line = line.rstrip('\n')
-        line = line.strip()
-        if not line: continue
-        print 'inputting:', `line`
-        try:
-            res = qp.parse(line)
-            print repr(res)
-        except (lex.LexError, yacc.YaccError), x:
-            print "parse error occurred:", x
-            print "query:", line
-
-
-#         lex.input(line)
-#         while 1:
-#             tok = lex.token()
-#             if not tok: break
-#             print tok
-        
-    
+    except (lex.LexError, yacc.YaccError), e:
+        raise Rwhois.RwhoisError, (350, "Invalid Query Syntax: " + e.message)