问题描述
我为简单查询创建了一个简单的解析器,以从数据存储区中获取数据.我使用的操作数是<,< =,>,> =,==,!= 解析器对除<之外的每个操作数都适用.由于每个操作数的正则表达式几乎相同,因此我对此行为感到有些惊讶.我找不到我做错了什么.
I have made a simple parser for simple queries, to fetch data from a datastore. The operands I have used are <,<=,>,>=,==,!=The Parser works fine for every operand except for <I am a bit surprised with the behavior since the regex for each operand are almost identical. I am unable to find what i might have done wrong.
代码:
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")
对于其他每个操作数,输出都是这样
For Every other Operand the output is something like this
res lame<10
set(['-&-lame<10'])
set(['-&-lame<10'])
但是对于>",输出/错误为:
But for '>' the output/error is as:
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]
我猜想它试图找到某个数字并且不能找到它,但是已经为其他操作数编写了类似的正则表达式,并且它不会导致错误,这似乎很奇怪.如果有人可以调查一下并告诉我我错了,将不胜感激.
I suppose its trying to find some digit and its not able to.But similar regex has been written for other operands and it does not result in an error, which seems to be weird.Would appreciate if anyone could look into this and tell me where I am wrong.
推荐答案
此regEx的问题是我如何处理值regEx.
The problem with this regEx was how I handled the value regEx.
value = ws parens | neq | eq | lte | lt | gte |gt ws
在这里,我在所有可能的选项之前和之后添加了空格,因此不是强制选择空格,而是强制执行了空格.因此,我没有在这里使用ws作为值,而是在使用价值令牌进行搜索的地方使用了ws,并将值更改为
Here I have added whitespace before and after all the possible options, thus instead of whitespace being optional it was being enforced.So rather than using ws here at value, I used ws where I was using the value token for searching , and changed value to
value = parens | neq | eq | lte | lt | gte |gt
这解决了我的问题.
这篇关于Parsley Python的RegEx解析错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!