[Zope-Checkins] CVS: Zope/lib/python/Products/PluginIndexes/TextIndexNG/queryparser - queryparser.g:1.1.2.2

Andreas Jung andreas@digicool.com
Fri, 11 Jan 2002 15:28:05 -0500


Update of /cvs-repository/Zope/lib/python/Products/PluginIndexes/TextIndexNG/queryparser
In directory cvs.zope.org:/tmp/cvs-serv10670

Modified Files:
      Tag: ajung-textindexng-branch
	queryparser.g 
Log Message:
this version works fine , except it parses the query 
from right to left :-) and all queries must start with '(' and end with ')'


=== Zope/lib/python/Products/PluginIndexes/TextIndexNG/queryparser/queryparser.g 1.1.2.1 => 1.1.2.2 ===
 res= ''
 
+class SB:
+
+    def __init__(self):
+        self.words = []
+        self.op    = ''
+        self.res   = ''
+
+    def addWord(self,w):
+        self.words.append("LL('%s')" % w)
+
+    def setOp(self,op):
+        if self.op and self.op != op:
+            raise RuntimeError,'Operator already set'
+        self.op = op
+
+    def collect(self):
+        if self.res:
+            self.words.append(self.res)
+
+        s = "%s(%s)" % (self.op,",".join(self.words))
+        self.res = s
+
+        self.op = ''
+        self.words = []
+
+    def result(self):
+        return self.res
+
+sb = SB()
 %%
 parser TextIndexQueryParser:
 
@@ -19,36 +48,38 @@
     token END:   "$"
     token NUM:   "[0-9]+"
     token VAR:   "[a-zA-Z_]+"
-    token AND:   "\\&"
+    token AND:   "&"
     token OR:    "\\|"
     token NEAR:  "\\.\\.\\."
 
 
-    rule expr: "(\\(){0,1}"      {{ words = []; op=[] }} 
-                subexpr<<words,op>>*
-               "(\\)){0,1}" {{ if res: words.append(res) }}
-                            {{ global res;c = ("%s(%s)" % (op[0], ','.join(words))) }}
-                            {{ res = c }}
-                            {{ return words,op }}
+    rule expr<<sb>>:  (term<<sb>>) *   {{ print 'inside expr'; }}
+
 
+    rule term<<sb>>:  
+                    "\\(" term<<sb>>     {{ sb.collect(); print sb.result() }}    
+                    | AND term<<sb>>     {{ sb.setOp(OpDict[AND]) }}
+                    | OR term<<sb>>      {{ sb.setOp(OpDict[OR]) }}
+                    | NEAR term<<sb>>    {{ sb.setOp(OpDict[NEAR]) }}
+                    | VAR term<<sb>>     {{ sb.addWord(VAR); }}
+                    | "\\)"              {{ print ')' }}
+
+    rule goal:  expr<<sb>> END           {{ sb.collect(); return sb.result() }}
 
-    rule subexpr<<words,op>>:      
-                       OR   {{ op.append(OpDict[OR]) }}
-                     | AND  {{ op.append(OpDict[AND]) }}
-                     | NEAR {{ op.append(OpDict[NEAR]) }}
-                     | VAR  {{ words.append(quote(VAR,'LL')) }}
-                     | expr
 %%
                   
 
 def test():
-    global res    
-    for s in ['(a | b | d)', '(a | (b | c))', '(a &(b|c)', '(zope...rocks) and mailman' ]:
+    global sb 
+
+    for s in ['(a | b | d)', 'a&(b|c) ', '(a &(b|c))','((a|b) & (c|d))',
+              '(a...b)', '((a...b) & c)']:
         print '-'*78
         print s
         res =  ''
-        print parse('expr', s)
-        print "result=",res
+        sb = SB()
+        print parse('goal', s)
+        print "result=",sb.result()