2012-04-02 35 views
14

¿Puede darme algunas ideas sobre cómo puedo hacer un analizador simple de expresiones matemáticas en C?Evaluar la función matemática de la cadena

El usuario ingresa una función matemática en una cadena y de la cadena Quiero crear la función en C. por ej. x + sin(2*x)

->return x + sin(2x);

Gracias de antemano.

+0

Eche un vistazo a la documentación de Bison, hay [ejemplos] (http://www.gnu.org/software/bison/manual/html_node/Infix-Calc.html#Infix-Calc) que lo guiarán. –

+0

posible duplicado de http://stackoverflow.com/questions/1151127/evaluating-mathematical-expressions, [¿Qué es un analizador matemático rápido C o Objective-C?] (Http://stackoverflow.com/questions/4892152/what -is-a-fast-c-or-objective-c-math-parser), http://stackoverflow.com/questions/5115872/what-is-the-best-way-to-evaluate-mathematical-expression- in-c/5117028 # 5117028, http://stackoverflow.com/questions/4071456/opensouce-cc-math-expression-parser-library/4071701#4071701, y muchos otros. – lhf

+0

Pruebe [TinyExpr] (https://github.com/codeplea/tinyexpr). Está en un solo archivo de código fuente y encabezado. – 131

Respuesta

6

Puede analizar la expresión basada en "Algoritmo de yarda de derivación" http://en.wikipedia.org/wiki/Shunting-yard_algorithm. Tendrá que extender para manejar las llamadas de función como sin, cos etc ...

+0

+1 para el patio de maniobras. Este es el enfoque correcto (simplicidad algorítmica, sin riesgo de desbordamientos de pila) para analizar tareas que pueda manejar. –

1

Una forma de hacerlo es usar notación polaca inversa para las expresiones y una pila para los operandos. Algunos rápida pseudo-código:

if element is operand 
    push in stack 
else if element is operation 
    pop last 2 elements 
    perform operation 
    push result in stack 

Repetir hasta el final de la expresión. El resultado final es el único elemento en la pila.

3

Esto no es algo simple de hacer, en realidad, es algo difícil. Necesita un analizador gramatical completo, combinado con constantes/funciones predefinidas (sin, log, pi, etc.).

Si no tiene una amplia experiencia previa con CI, esto no sería recomendable, pero si realmente desea hacerlo, consulte recursive descent parsing, que es posiblemente la manera más fácil de hacerlo (sin poner una carga sobre el usuario, como el pulido inverso notación).

Por último pero no menos importante, usted dice que desea crear una C función desde la entrada generada por el usuario. Esto es casi siempre algo incorrecto: generar código a partir de la entrada del usuario, en cambio, el enfoque más fácil es el preprocesamiento para crear una representación intermedia que se puede ejecutar de manera eficiente.

+0

Me gustaría saber que probablemente debas estudiar [BNF (Formulario Backus-Naur)] (http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form) sentencia – Eregrith

+0

Me gustaría decir que esto no es un cosa simple de hacer No es horrible, de hecho es bastante elegante, pero de ninguna manera es simple. Recursive decente es el método más simple, la precedencia del operador es más sofisticada pero considerablemente más complicada –

0

Escribir un analizador de expresiones y un evaluador es uno de los ejemplos habituales utilizados cuando se analizan las técnicas de escritura del analizador. Por ejemplo, puede consultar la documentación de flex/bison o lex/yacc. Eso tendrá ejemplos de construir analizadores sintácticos/evaluadores de expresiones.

Cuestiones relacionadas