expression parser: beautification

bzr revid: christophe@tinyerp.com-20080731120054-hmkxdh62drs6f2qm
This commit is contained in:
Christophe Simonis 2008-07-31 14:00:54 +02:00
parent 6010603de4
commit d98d6fe17b
1 changed files with 31 additions and 28 deletions

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
class expression( object ): class expression(object):
""" """
parse a domain expression parse a domain expression
examples: examples:
@ -41,31 +41,31 @@ class expression( object ):
ValueError: Bad expression: ('&', ('fail', 'is', 'True')) ValueError: Bad expression: ('&', ('fail', 'is', 'True'))
""" """
def _is_operator( self, element ): def _is_operator(self, element):
return isinstance( element, str ) \ return isinstance(element, str) \
and element in ['&','|'] and element in ['&','|']
def _is_leaf( self, element ): def _is_leaf(self, element):
return isinstance( element, tuple ) \ return isinstance(element, tuple) \
and len( element ) == 3 \ and len(element) == 3 \
and element[1] in ('=', '<>', '<=', '<', '>', '>=', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of') and element[1] in ('=', '<>', '<=', '<', '>', '>=', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of')
def _is_expression( self, element ): def _is_expression(self, element):
return isinstance( element, tuple ) \ return isinstance(element, tuple) \
and len( element ) > 2 \ and len(element) > 2 \
and self._is_operator( element[0] ) and self._is_operator(element[0])
def __init__( self, exp ): def __init__(self, exp):
if isinstance( exp, tuple ): if isinstance(exp, tuple):
if not self._is_leaf( exp ) and not self._is_operator( exp[0] ): if not self._is_leaf(exp) and not self._is_operator(exp[0]):
exp = list( exp ) exp = list(exp)
if isinstance( exp, list ): if isinstance(exp, list):
if len( exp ) == 1 and self._is_leaf( exp[0] ): if len(exp) == 1 and self._is_leaf(exp[0]):
exp = exp[0] exp = exp[0]
else: else:
if not self._is_operator( exp[0][0] ): if not self._is_operator(exp[0][0]):
exp.insert( 0, '&' ) exp.insert(0, '&')
exp = tuple( exp ) exp = tuple(exp)
else: else:
exp = exp[0] exp = exp[0]
@ -78,21 +78,24 @@ class expression( object ):
self.left, self.operator, self.right = self.exp self.left, self.operator, self.right = self.exp
if isinstance(self.right, list): if isinstance(self.right, list):
self.right = tuple(self.right) self.right = tuple(self.right)
elif not self._is_expression( self.exp ): elif not self._is_expression(self.exp):
raise ValueError, 'Bad expression: %r' % (self.exp,) raise ValueError, 'Bad expression: %r' % (self.exp,)
def parse( self ): def parse(self):
if not self._is_leaf( self.exp ) and self._is_expression( self.exp ): if self._is_leaf(self.exp):
pass
elif self._is_expression(self.exp):
self.operator = self.exp[0] self.operator = self.exp[0]
for element in self.exp[1:]: for element in self.exp[1:]:
if not self._is_operator( element ): if not self._is_operator(element):
self.children.append( expression(element).parse() ) self.children.append(expression(element).parse())
return self return self
def to_sql( self ): def to_sql(self):
if self._is_leaf( self.exp ): if self._is_leaf(self.exp):
return "%s %s %s" % ( self.left, self.operator, self.right ) return "%s %s %s" % (self.left, self.operator, self.right)
else: else:
return "( %s )" % (" %s " % {'&' : 'AND', '|' : 'OR' }[self.operator]).join([child.to_sql() for child in self.children]) return "( %s )" % (" %s " % {'&' : 'AND', '|' : 'OR' }[self.operator]).join([child.to_sql() for child in self.children])