14

Can you give me some ideas about how can I make a simple mathematical expression parser in C?

User enters a mathematical function in a string and from the string I want to create the function in C. eg. x + sin(2*x)

-> return x + sin(2x);

Thanks in advance.

ForceBru
  • 43,482
  • 10
  • 63
  • 98
bokarinho
  • 193
  • 1
  • 1
  • 6
  • Have a look at Bison documentation, there are [examples](http://www.gnu.org/software/bison/manual/html_node/Infix-Calc.html#Infix-Calc) which will guide you. – Alexandre C. Apr 02 '12 at 13:11
  • possible duplicate of http://stackoverflow.com/questions/1151127/evaluating-mathematical-expressions, [What is a fast C or Objective-C math parser?](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-c-c-math-expression-parser-library/4071701#4071701, and several others. – lhf Apr 02 '12 at 13:35
  • Try [TinyExpr](https://github.com/codeplea/tinyexpr). It's in a single C source code file and header. – 131 Jan 22 '16 at 21:32

4 Answers4

6

You can parse the expression based "Shunting-Yard Algorithm" http://en.wikipedia.org/wiki/Shunting-yard_algorithm. You will need to extend to handle the function calls such as sin, cos etc...

anilsinaci
  • 386
  • 1
  • 4
3

This is not a simple thing to do at all, in face, it's a hard thing. You need a full grammar parser, combined with pre-defined constants/functions (sin, log, pi, etc).

If you have no extensive previous experience with C I would disrecommend doing this, but if you really want to do this look at recursive descent parsing which is arguably the easiest way to do this (without putting a burden on the user, like reverse polish notation).

Last but not least you say you want to create a C function from the user-generated input. This is almost always a wrong thing to do - generating code from user input, instead the easiest approach is pre-processing to create a intermediate representation that can be efficiently executed.

orlp
  • 112,504
  • 36
  • 218
  • 315
  • I would pile on that you should probably study [BNF (Backus-Naur Form)](http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form) ruling – Eregrith Apr 02 '12 at 13:11
  • I would second that this is not a simple thing to do. It's not horrible, in fact it is quite elegant, but it's by no means simple. Recursive decent is the simplest method, operator precedence is more sophisticated but considerable more complicated – Tom Quarendon Apr 02 '12 at 13:13
0

One way to do it is to use reverse polish notation for the expressions and a stack for the operands. Some quick pseudo-code:

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

Repeat till end of expression. Final result is the only element in stack.

Alexander
  • 8,117
  • 1
  • 35
  • 46
0

Writing an expression parser and evaluator is one of the usual examples used when discussions parser writing techniques. For example you could look the documentation for flex/bison or lex/yacc. That will have examples of constructing parsers/expression evaluators.

Tom Quarendon
  • 5,625
  • 5
  • 23
  • 30