2010-08-27 18 views

Respuesta

10

Los Pyparsing examples page enumera varios programas de análisis de expresión:

http://pyparsing.wikispaces.com/file/view/fourFn.py - Una aplicación aritmética infija convencional notación analizador/evaluador usando pyparsing (a pesar de su nombre, este hecho hace 5-función aritmética, además de varias funciones trigonométricas)

http://pyparsing.wikispaces.com/file/view/simpleBool.py - a notación infija boolean analizador/evaluador, utilizando un método pyparsing ayudante operatorPrecedence, lo que simplifica la definición de notaciones operador infijo

http://pyparsing.wikispaces.com/file/view/simpleArith.pyhttp://pyparsing.wikispaces.com/file/view/eval_arith.py - Un par de ejemplos que rediseñan fourFn.py usando operatorPrecedence. El primero solo analiza y devuelve un árbol de análisis, el segundo agrega lógica de evaluación.

+0

pyparsing es realmente genial, aunque un poco aterrador a primera vista – dmitry

0

Sí. Incluso si hubiera un equivalente de ast.literal_eval() para expresiones, una expresión de Python puede ser un montón de cosas además de una expresión matemática pura, por ejemplo, una llamada de función arbitraria.

No me sorprendería si ya hay un buen analizador/evaluador de expresiones matemáticas disponible en algún módulo de código abierto, pero si no, es bastante fácil escribir uno propio.

0

las funciones matemáticas constarán de caracteres numéricos y de puntuación, posible 'E' o 'e' si permite la notación científica para números racionales, y el único (otro) uso legal de caracteres alfabéticos será si permite/proporciona funciones matemáticas (por ejemplo, stddev). Por lo tanto, debe ser trivial para ejecutar a lo largo de la cadena de caracteres alfabéticos y comprobar que el siguiente poco no es sospechoso, entonces simplemente evalúa la cadena en un bloque try/except.

Re los comentarios que esta respuesta ha recibido ... Acepto que este enfoque es jugar con fuego. Aún así, eso no significa que no se pueda hacer de manera segura. Soy nuevo en python (< 2 meses), por lo que es posible que no sepa las soluciones a las que esto es vulnerable (y, por supuesto, una nueva versión de Python siempre podría volverlo inseguro en el futuro), pero por lo poco que vale (principalmente mi propia diversión) - aquí está mi grieta en ella:

def evalMaths(s): 
    i = 0 
    while i < len(s): 
     while s[i].isalpha() and i < len(s): 
      idn += s[i] 
      i += 1 
     if (idn and idn != 'e' and idn != 'abs' and idn != 'round'): 
      raise Exception("you naughty boy: don't " + repr(idn)) 
     else: 
      i += 1 
    return eval(s) 

estaría muy interesado en saber si/cómo se puede evitar ... (^_^) BTW/sé que usted puede llamar a funciones como abs2783 o _983 - si existieron, pero no lo harán. Me refiero a algo práctico.

De hecho, si alguien puede hacerlo, crearé una pregunta con 200 generosidad y aceptaré su respuesta.

+2

-1 No hagas esto. 'eval' -ing una cadena de entrada de usuario es __never__ una buena idea. Alguien encontrará una forma de evitar su protección. – katrielalex

+0

¿Qué hay de proporcionar una justificación en lugar de una afirmación completamente inútil? Puede que no sea lindo, pero si quiere hacer algo, hay un análisis de costo-beneficio al no tener una solución de trabajo, o jugar con algo más complejo. –

+0

@Tony, el costo de estropear esto es infinito y más allá. – carl

2

¿Qué tipo de expresiones quieres? ¿Asignación variable? Evaluación de la función?

SymPy pretende convertirse en un CAS de Python con todas las de la ley.

+0

Soy capaz de modificar mis necesidades en función de las posibilidades disponibles. SymPy parece interesante. Una pequeña biblioteca de un solo archivo sería aún mejor. –

+0

@Ivo: ¡las posibilidades dependen de sus necesidades! @Paul vinculó varias formas simples de hacer esto con 'pyparsing'. 'SymPy' produce más potencia, a un mayor costo (grande, puede ser lento). – katrielalex

+0

'SymPy' no es seguro para las entradas que no son de confianza. –

1

Hace algunas semanas hice algo similar, pero para expresiones lógicas (o, y, no, comparaciones, paréntesis, etc.). Lo hice usando el analizador Ply. He creado el analizador y el analizador simple. El analizador generó un árbol AST que luego se usó para realizar cálculos. Hacer esto de esa manera le permite controlar completamente lo que ingresa el usuario, porque solo se analizarán las expresiones que sean compatibles con la gramática.

+0

¿dónde puedo obtener su analizador de expresiones lógicas? Gracias por adelantado. –

Cuestiones relacionadas