Ich habe einen einfachen Parser für einfache Abfragen, um Daten aus einem Datenspeicher zu holen. Die Operanden ich verwendet habe, sind <, < =,>,> =, ==,! = Der Parser arbeitet für jeden Operanden in Ordnung, außer für < Ich bin ein wenig überrascht, mit dem Verhalten, da die Regex für jeden Operanden ist fast gleich. Ich kann nicht finden, was ich falsch gemacht habe.RegEx Parse Fehler von Parsley Python
Code:
import parsley
from FieldSet import FieldSet
from Field import Field
class QueryParser(object):
def __init__(self,getter):
self.__defineParser()
self.getter = getter
def __defineParser(self):
self.parseField = parsley.makeGrammar("""
neq = <letterOrDigit*>:field ws '!=' ws <letterOrDigit*>:value ->Field(field,value,'!=')
eq = <letterOrDigit*>:field ws '==' ws <letterOrDigit*>:value ->Field(field,value,'==')
lte = <letterOrDigit*>:field ws '<=' ws <digit*'.'?digit*>:value ->Field(field,value,'<=')
gte = <letterOrDigit*>:field ws '>=' ws <digit*'.'?digit*>:value ->Field(field,value,'>=')
lt = <letterOrDigit*>:field ws '<' ws <digit*'.'?digit*>:value ->Field(field,value,'<')
gt = <letterOrDigit*>:field ws '>' ws <digit*'.'?digit*>:value ->Field(field,value,'>')
fieldCondition = ws (neq | eq | lte | lt | gte |gt):evalTuple ws -> evalTuple
""",{'Field':Field})
self.parse = parsley.makeGrammar("""
neq = <letterOrDigit* ws '!=' ws letterOrDigit*>:s ->str(s)
eq = <letterOrDigit* ws '==' ws letterOrDigit*>:s ->str(s)
lte = <letterOrDigit* ws '<=' ws digit*'.'?digit*>:s->str(s)
gte = <letterOrDigit* ws '>=' ws digit*'.'?digit*>:s ->str(s)
lt = <letterOrDigit* ws '<' ws digit*'.'?digit*>:s->str(s)
gt = <letterOrDigit* ws '>' ws digit*'.'?digit*>:s ->str(s)
parens = ws '(' ws expr:e ws ')' ws -> e
value = ws parens | neq | eq | lte | lt | gte |gt ws
ws = ' '*
and = 'AND' ws expr3:n -> ('AND', n)
or = 'OR' ws expr3:n -> ('OR', n)
not = 'NOT' ws value:n -> ('NOT', n)
checknot = ws (value|not)
andor = ws (and | or)
expr = expr3:left andor*:right -> performOperations(left, right)
expr3 = ws checknot:right -> getVal(right)
""", {"performOperations": self.performOperations,'getVal':self.getVal})
def processQuery(self,field):
if type(field) is FieldSet:
return field
elif type(field) is Field:
elements = FieldSet(field,self.getter)
return elements
else:
raise Exception("Invalid Input")
def performOperations(self,start, pairs):
result = start
if type(result) is Field:
result = self.processQuery(start)
for op, value in pairs:
if op == 'AND':
secondField = self.processQuery(value)
result.union(secondField)
elif op == 'OR':
secondField = self.processQuery(value)
result.intersection(secondField)
print type(result)
print result.getSet()
return result
'''This functions will be returning sets'''
def getVal(self,field):
if type(field) is tuple:
_op,value = field
result = self.parseField(value).fieldCondition()
result.negate()
elif type(field) is FieldSet:
result = field
else:
result = self.parseField(field).fieldCondition()
print "res",result
return result
def getResults(self,query):
return self.parse(query).expr().getSet()
if __name__=="__main__":
pae = QueryParser("POP")
print pae.getResults("lame>10")
Für jeden anderen Operanden ist der Ausgang so etwas wie diese
res lame<10
set(['-&-lame<10'])
set(['-&-lame<10'])
Aber für '>' der Ausgang/Fehler wie:
Traceback (most recent call last):
File "D:\Nother\engine\parser\QueryParser.py", line 107, in <module>
print pae.getResults("lame>10")
File "D:\Nother\engine\parser\QueryParser.py", line 104, in getResults
return self.parse(query).expr().getSet()
File "D:\Nother\lookup_env\lib\site-packages\parsley.py", line 98, in invokeRule
raise err
ometa.runtime.EOFError:
lame>10
^
Parse error at line 2, column 0: end of input. trail: [digit]
Ich nehme an, es versucht, eine Ziffer zu finden, und es ist nicht in der Lage, aber eine ähnliche Regex wurde für andere Operanden geschrieben und führt nicht zu einem Fehler, der seltsam erscheint. Würde mich freuen, wenn sich jemand damit befassen und mir sagen könnte, wo ich falsch liege.