
Pour ça on est obligé (si on utilise pyparsing) de générer la liste de tous les charactère unicode. Daniel fait remarquer que ça n'est pas joli d'instancier une chaine de 63Ko quand on veux parser quelque chose. On ne le fait tout de même que de façon paresseuse la première fois que l'on a besoin de parser quelquechose (dans filter2, filter3 est juste un proof of concept). Pour faire du human_to_ldap, on peut utiliser directement la fonction de filter.py qui n'est pas impacté par le problème, mais pour ressucite, on a pour le moment pas le choix puisqu'on utilise la fonction human_to_list qui n'est fournie que dans les modules filter2 et filter3.
75 lines
1.8 KiB
Python
75 lines
1.8 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf8 -*-
|
|
"""Plus rapide"""
|
|
|
|
def simplify(l):
|
|
if not isinstance(l, list):
|
|
return l
|
|
if len(l) == 1:
|
|
return simplify(l[0])
|
|
else:
|
|
return [simplify(i) for i in l]
|
|
|
|
def toprefix(l):
|
|
if not isinstance(l, list):
|
|
return l
|
|
op=l[1]
|
|
args=[toprefix(i) for i in l if i!=op]
|
|
return [op]+args
|
|
|
|
def prioritize(l):
|
|
if not isinstance(l, list):
|
|
return l
|
|
l=simplify(l)
|
|
for c in ['!=', '=', '&', '|']:
|
|
i=0
|
|
while i<len(l):
|
|
if l[i] == c:
|
|
tmp=[prioritize(l[i-1]), l[i], prioritize(l[i+1])]
|
|
l[i-1]=tmp
|
|
del(l[i+1])
|
|
del(l[i])
|
|
i-=1
|
|
i+=1
|
|
return simplify(l)
|
|
|
|
def collapse(l):
|
|
"""retire les parentheses inutiles"""
|
|
if not isinstance(l, list):
|
|
return l
|
|
if not isinstance(l[1], list):
|
|
return [l[0], collapse(l[1]), collapse(l[2])]
|
|
if l[0] == l[1][0]:
|
|
return [l[0], collapse(l[1][1]), collapse(l[1][2]), collapse(l[2])]
|
|
else:
|
|
return [l[0], collapse(l[1]), collapse(l[2])]
|
|
|
|
|
|
def toldapfilter(l):
|
|
if not isinstance(l, list):
|
|
return l
|
|
op=l[0]
|
|
if op == "=":
|
|
return "%s=%s" % (l[1], l[2])
|
|
elif op == "!=":
|
|
return "!(%s=%s)" % (l[1], l[2])
|
|
return op + ''.join(['(%s)' % toldapfilter(i) for i in l[1:]])
|
|
|
|
|
|
# Import et definition de la grammaire de parsing de façon paresseuse
|
|
expr=None
|
|
def pypexpr():
|
|
global expr
|
|
if not expr:
|
|
import pyparsing
|
|
unicodePrintables = u''.join(unichr(c) for c in xrange(65536) if not unichr(c).isspace())
|
|
txt = "".join(c for c in unicodePrintables if c not in '()&|!=')
|
|
expr = pyparsing.nestedExpr("(", ")", pyparsing.Word(txt) | pyparsing.oneOf("& | != ="))
|
|
return expr
|
|
|
|
def human_to_list(data):
|
|
if data:
|
|
return collapse(toprefix(prioritize(pypexpr().parseString("(%s)" % data).asList())))
|
|
|
|
def human_to_ldap(data):
|
|
return u"(%s)" % toldapfilter(human_to_list(data))
|