parser parseo parse make how generador python parsing

parseo - Analizador de expresiones seguras en Python



url parse python (5)

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

SymPy pretende convertirse en un CAS de Python completo.

¿Cómo puedo permitir que los usuarios ejecuten expresiones matemáticas de forma segura? ¿Debo escribir un analizador completo?

¿Hay algo como ast.literal_eval () , pero para expresiones?


Hace algunas semanas hice algo similar, pero para expresiones lógicas (o, y, no, comparaciones, paréntesis, etc.). Hice esto usando Ply parser. 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.


La página de ejemplos de Pyparsing enumera varios analizadores de expresiones:

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

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

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


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 pura expresión matemática, 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.


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 específicas (por ej. 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 ... Estoy de acuerdo con 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 alternativas 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:

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 eludir ... (^_^) Por cierto, sé que puede llamar a funciones como abs2783 o _983, si es que existieron, pero no lo harán. Me refiero a algo práctico.

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