El Examples page en el pyparsing wiki incluye una muestra de SimpleBool.py que analizar y evaluar expresiones tales como:
test = ["p and not q",
"not not p",
"not(p and q)",
"q or not p and r",
"q or not (p and r)",
"p or q or r",
"p or q or r and False",
]
(Hmmm, no hay ejemplos con parens anidados, pero estos son . apoyado también)
El analizador real se define en su totalidad mediante este código:
boolOperand = Word(alphas,max=1) | oneOf("True False")
boolExpr = operatorPrecedence(boolOperand,
[
("not", 1, opAssoc.RIGHT, BoolNot),
("and", 2, opAssoc.LEFT, BoolAnd),
("or", 2, opAssoc.LEFT, BoolOr),
])
El resto del ejemplo proporciona las implementaciones de BoolNot, BoolOr y BoolAnd. El constructo operatorPrecedence define la secuencia de operaciones, su arity y asociatividad, y opcionalmente una clase que se construirá con los elementos analizados. operatorPrecedence se encarga de definir la gramática, incluida la definición recursiva de boolExpr dentro de paréntesis anidados. La estructura resultante es similar a un AST anidado utilizando las clases BoolXxx dadas.Estas clases a su vez definen eval
métodos para que las expresiones pueden analizarse y evaluarse utilizando este código:
p = True
q = False
r = True
for t in test:
res = boolExpr.parseString(t)[0]
print t,'\n', res, '=', bool(res),'\n'
pyparsing sí mismo es un módulo de algo bastante largo, pero es un solo fichero fuente por lo que su huella de instalación es bastante pequeña. La licencia de MIT permite el uso no comercial y comercial.
¿Qué estás tratando de hacer exactamente? – Gumbo
Tengo una implementación JS personalizada del lado del cliente que produce una expresión aritmética booleana (donde a, b, c ... en realidad son búsquedas de campo para su uso posterior en filtros ORM de Django) que luego se envía al servidor y se analiza con Python . Espero que tenga sentido. – nikola
Entonces, ¿desea analizar esa expresión para evaluarla más tarde, correcto? – Gumbo