我为简单查询创建了一个简单的解析器,用于从数据存储中获取数据。我使用的操作数是<,< =,>,> =,==,!= 对于每个操作数,解析器都可以正常工作,除了< 我对这种行为感到有些惊讶,因为每个操作数的正则表达式几乎相同。我无法找到我可能做错的事。
代码:
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")
对于其他每个操作数,输出都是这样的
res lame<10
set(['-&-lame<10'])
set(['-&-lame<10'])
但是对于&#39;&gt;&#39;输出/错误如下:
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]
我想它试图找到一些数字并且它不能。但是已经为其他操作数编写了类似的正则表达式并且它不会导致错误,这似乎很奇怪。 如果有人能够调查并告诉我错在哪里,我将不胜感激。
答案 0 :(得分:1)
这个regEx的问题是我如何处理值regEx。
value = ws parens | neq | eq | lte | lt | gte |gt ws
这里我在所有可能的选项之前和之后添加了空格,因此不是空格是可选的,而是强制执行。 所以我没有在这里使用ws,而是使用ws,我使用值标记进行搜索,并将值更改为
value = parens | neq | eq | lte | lt | gte |gt
这解决了我的问题。