Initial almost working implementation of pyparsing based string selector
Two test cases are still failing
This commit is contained in:
parent
f8c377c2f7
commit
bde0fddc05
|
@ -420,6 +420,58 @@ class InverseSelector(Selector):
|
||||||
return SubtractSelector(Selector(), self.selector).filter(objectList)
|
return SubtractSelector(Selector(), self.selector).filter(objectList)
|
||||||
|
|
||||||
|
|
||||||
|
def _makeGrammar():
|
||||||
|
"""
|
||||||
|
Define the string selector grammar using PyParsing
|
||||||
|
"""
|
||||||
|
|
||||||
|
#float definition
|
||||||
|
point = Literal('.')
|
||||||
|
plusmin = Literal('+') | Literal('-')
|
||||||
|
number = Word(nums)
|
||||||
|
integer = Combine(Optional(plusmin) + number)
|
||||||
|
floatn = Combine(integer + Optional(point + Optional(number)))
|
||||||
|
|
||||||
|
#vector definition
|
||||||
|
lbracket = Literal('(')
|
||||||
|
rbracket = Literal(')')
|
||||||
|
comma = Literal(',')
|
||||||
|
vector = Combine(lbracket + floatn('x') + comma + \
|
||||||
|
floatn('y') + comma + floatn('z') + rbracket)
|
||||||
|
|
||||||
|
#direction definition
|
||||||
|
simple_dir = oneOf(['X','Y','Z','XY','XZ','YZ'])
|
||||||
|
direction = simple_dir('simple_dir') | vector('vector_dir')
|
||||||
|
|
||||||
|
#CQ type definition
|
||||||
|
cqtype = oneOf(['Plane','Cylinder','Sphere','Line','Circle','Arc'])
|
||||||
|
|
||||||
|
#type operator
|
||||||
|
type_op = Literal('%')
|
||||||
|
|
||||||
|
#direction operator
|
||||||
|
direction_op = oneOf(['>','<'])
|
||||||
|
|
||||||
|
#index definition
|
||||||
|
ix_number = Optional('-')+Word(nums)
|
||||||
|
lsqbracket = Literal('[').suppress()
|
||||||
|
rsqbracket = Literal(']').suppress()
|
||||||
|
|
||||||
|
index = lsqbracket + ix_number + rsqbracket
|
||||||
|
|
||||||
|
#other operators
|
||||||
|
other_op = oneOf(['|','#','+','-'])
|
||||||
|
|
||||||
|
#named view
|
||||||
|
named_view = oneOf(['front','back','left','right','top','bottom'])
|
||||||
|
|
||||||
|
return (type_op('type_op') + cqtype('cqtype')) | \
|
||||||
|
(direction_op('dir_op') + direction('dir') + Optional(index('index'))) | \
|
||||||
|
(other_op('other_op') + direction('dir')) | \
|
||||||
|
named_view('named_view')
|
||||||
|
|
||||||
|
_grammar = _makeGrammar() #make a grammar instance
|
||||||
|
|
||||||
class StringSyntaxSelector(Selector):
|
class StringSyntaxSelector(Selector):
|
||||||
"""
|
"""
|
||||||
Filter lists objects using a simple string syntax. All of the filters available in the string syntax
|
Filter lists objects using a simple string syntax. All of the filters available in the string syntax
|
||||||
|
@ -457,8 +509,6 @@ class StringSyntaxSelector(Selector):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self,selectorString):
|
def __init__(self,selectorString):
|
||||||
|
|
||||||
self._expr = self._makeGrammar()
|
|
||||||
|
|
||||||
self.axes = {
|
self.axes = {
|
||||||
'X': Vector(1,0,0),
|
'X': Vector(1,0,0),
|
||||||
|
@ -469,101 +519,65 @@ class StringSyntaxSelector(Selector):
|
||||||
'XZ': Vector(1,0,1)
|
'XZ': Vector(1,0,1)
|
||||||
}
|
}
|
||||||
|
|
||||||
namedViews = {
|
self.namedViews = {
|
||||||
'front': ('>','Z' ),
|
'front' : (Vector(0,0,1),True),
|
||||||
'back': ('<','Z'),
|
'back' : (Vector(0,0,1),False),
|
||||||
'left':('<', 'X'),
|
'left' : (Vector(1,0,0),False),
|
||||||
'right': ('>', 'X'),
|
'right' : (Vector(1,0,0),True),
|
||||||
'top': ('>','Y'),
|
'top' : (Vector(0,1,0),True),
|
||||||
'bottom': ('<','Y')
|
'bottom': (Vector(0,1,0),False)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.operatorMinMax = {
|
||||||
|
'>' : True,
|
||||||
|
'<' : False,
|
||||||
|
'+' : True,
|
||||||
|
'-' : False
|
||||||
|
}
|
||||||
|
|
||||||
|
self.operator = {
|
||||||
|
'+' : DirectionSelector,
|
||||||
|
'-' : DirectionSelector,
|
||||||
|
'#' : PerpendicularDirSelector,
|
||||||
|
'|' : ParallelDirSelector}
|
||||||
|
|
||||||
self.selectorString = selectorString
|
self.selectorString = selectorString
|
||||||
r = re.compile("\s*([-\+<>\|\%#])*\s*(\w+)\s*",re.IGNORECASE)
|
parsing_result = _grammar.parseString(selectorString)
|
||||||
m = r.match(selectorString)
|
self.mySelector = self._chooseSelector(parsing_result)
|
||||||
|
|
||||||
if m != None:
|
def _chooseSelector(self,pr):
|
||||||
if namedViews.has_key(selectorString):
|
"""
|
||||||
(a,b) = namedViews[selectorString]
|
Sets up the underlying filters accordingly
|
||||||
self.mySelector = self._chooseSelector(a,b )
|
"""
|
||||||
|
if 'type_op' in pr:
|
||||||
|
return TypeSelector(pr.cq_type)
|
||||||
|
|
||||||
|
elif 'dir_op' in pr:
|
||||||
|
vec = self._getVector(pr)
|
||||||
|
minmax = self.operatorMinMax[pr.dir_op]
|
||||||
|
|
||||||
|
if 'index' in pr:
|
||||||
|
return DirectionNthSelector(vec,int(pr.index),minmax)
|
||||||
else:
|
else:
|
||||||
self.mySelector = self._chooseSelector(m.groups()[0],m.groups()[1])
|
return DirectionMinMaxSelector(vec,minmax)
|
||||||
|
|
||||||
|
elif 'other_op' in pr:
|
||||||
|
vec = self._getVector(pr)
|
||||||
|
return self.operator[pr.other_op](vec)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError ("Selector String format must be [-+<>|#%] X|Y|Z ")
|
args = self.namedViews[pr.named_view]
|
||||||
|
return DirectionMinMaxSelector(*args)
|
||||||
def _makeGrammar(self):
|
|
||||||
'''
|
def _getVector(self,pr):
|
||||||
Define the string selector grammar using PyParsing
|
"""
|
||||||
'''
|
Translate parsed vector string into a CQ Vector
|
||||||
|
"""
|
||||||
#float definition
|
if 'vector_dir' in pr:
|
||||||
point = Literal('.')
|
return Vector(float(pr.x),float(pr.y),float(pr.z))
|
||||||
plusmin = Literal('+') | Literal('-')
|
|
||||||
number = Word(nums)
|
|
||||||
integer = Combine(Optional(plusmin) + number)
|
|
||||||
floatn = Combine(integer + Optional(point + Optional(number)))
|
|
||||||
|
|
||||||
#vector definition
|
|
||||||
lbracket = Literal('(')
|
|
||||||
rbracket = Literal(')')
|
|
||||||
comma = Literal(',')
|
|
||||||
vector = Combine(lbracket + floatn + comma + floatn + comma + floatn + rbracket)
|
|
||||||
|
|
||||||
#direction definition
|
|
||||||
direction = oneOf(['X','Y','Z','XY','XZ','YZ']) | vector
|
|
||||||
direction = direction.setResultsName('dir')
|
|
||||||
|
|
||||||
#CQ type definition
|
|
||||||
cqtype = oneOf(['Plane','Cylinder','Sphere','Line','Circle','Arc'])
|
|
||||||
|
|
||||||
#type operator
|
|
||||||
type_op = Literal('%')
|
|
||||||
|
|
||||||
#direction operator
|
|
||||||
direction_op = oneOf(['>','<'])
|
|
||||||
|
|
||||||
#index definition
|
|
||||||
ix_number = Optional('-')+Word(nums)
|
|
||||||
lsqbracket = Literal('[').suppress()
|
|
||||||
rsqbracket = Literal(']').suppress()
|
|
||||||
|
|
||||||
index = lsqbracket + ix_number + rsqbracket
|
|
||||||
index = index.setResultsName('index')
|
|
||||||
|
|
||||||
#other operators
|
|
||||||
other_op = oneOf(['|','#','+','-'])
|
|
||||||
|
|
||||||
return (type_op('op') + cqtype('cqtype')) | (direction_op('op') + direction + Optional(index)) | (other_op('op') + direction)
|
|
||||||
|
|
||||||
def _chooseSelector(self,selType,selAxis):
|
|
||||||
"""Sets up the underlying filters accordingly"""
|
|
||||||
|
|
||||||
if selType == "%":
|
|
||||||
return TypeSelector(selAxis)
|
|
||||||
|
|
||||||
#all other types need to select axis as a vector
|
|
||||||
#get the axis vector first, will throw an except if an unknown axis is used
|
|
||||||
try:
|
|
||||||
vec = self.axes[selAxis]
|
|
||||||
except KeyError:
|
|
||||||
raise ValueError ("Axis value %s not allowed: must be one of %s" % (selAxis, str(self.axes)))
|
|
||||||
|
|
||||||
if selType in (None, "+"):
|
|
||||||
#use direction filter
|
|
||||||
return DirectionSelector(vec)
|
|
||||||
elif selType == '-':
|
|
||||||
#just use the reverse of the direction vector
|
|
||||||
return DirectionSelector(vec.multiply(-1.0))
|
|
||||||
elif selType == "|":
|
|
||||||
return ParallelDirSelector(vec)
|
|
||||||
elif selType == ">":
|
|
||||||
return DirectionMinMaxSelector(vec,True)
|
|
||||||
elif selType == "<":
|
|
||||||
return DirectionMinMaxSelector(vec,False)
|
|
||||||
elif selType == '#':
|
|
||||||
return PerpendicularDirSelector(vec)
|
|
||||||
else:
|
else:
|
||||||
raise ValueError ("Selector String format must be [-+<>|] X|Y|Z ")
|
return self.axes[pr.simple_dir]
|
||||||
|
|
||||||
def filter(self,objectList):
|
def filter(self,objectList):
|
||||||
"""
|
"""
|
||||||
selects minimum, maximum, positive or negative values relative to a direction
|
selects minimum, maximum, positive or negative values relative to a direction
|
||||||
|
|
Loading…
Reference in New Issue
Block a user