Parsing Math Expression in C++

Parsing mathematical expression string

Tokenization is the first step towards syntactic analysis. As such, it is probably a good idea to encapsulate it into a layer of abstraction, a function that yields one token at a time. This function also discards white space and combines consecutive digits into numbers. It is hard to delegate these steps to strtok(). Finally, the function may rewrap single characters into more structured information.

#include <ctype.h>
#include <stdio.h>

#define T_NUMBER 0
#define T_OPERATOR 1
#define T_BRACKET 2

typedef struct {
int type;
int value;
} token;

/* Reads the next token from stdin. Returns 1 on success, 0 on EOL. */
int next_token(token *t) {
char c;

/* discard spaces silently */
do {
c = getchar();
} while (c == ' ');

if (isdigit(c)) {
t->type = T_NUMBER;
t->value = 0;
do {
t->value = t->value * 10 + (c - '0');
c = getchar();
} while (isdigit(c));
ungetc(c, stdin); /* save the non-digit for next time */

} else if (c == '+' || c == '-' || c == '*' || c == '/') {
t->type = T_OPERATOR;
t->value = c;

} else if (c == '(' || c == ')') {
t->type = T_BRACKET;
t->value = c;

} else if (c == '\n') {
ungetc(c, stdin); /* make sure we always return 0 from now on */
return 0;

} else {
/* handle illegal character */

}

return 1;
}

int main() {

token t;

while (next_token(&t)) {
switch (t.type) {
case T_NUMBER: printf("number %d\n", t.value); break;
case T_OPERATOR: printf("operator %c\n", t.value); break;
case T_BRACKET: printf("bracket %c\n", t.value); break;
}
}

return 0;
}

Sample run:

(22+   37 * ( 1534-9)) + 18
bracket (
number 22
operator +
number 37
operator *
bracket (
number 1534
operator -
number 9
bracket )
bracket )
operator +
number 18

parsing math expression in c++

Use the Shunting-yard algorithm. The wikipedia description is quite comprehensive, I hope it will suffice.

You can also try to write a formal grammar, for example a parsing-expression grammar, and use a tool to generate a parser. This site about PEGs lists 3 C/C++ libraries for PEG parsing.

C parser for mathematical expressions with one variable and save it into a function

What you want to achieve is totally feasible. You can for instance build an AST (https://en.wikipedia.org/wiki/Abstract_syntax_tree) from the expression, where some nodes of the tree represent the variables.

Then, the evaluation of the expression for some values of the variables corresponds to the evaluation of that tree.

Actually, most parsers will produce such a tree internally and you may be able to find some library producing an AST for your need or you might want to code it yourself (see also https://en.wikipedia.org/wiki/Shunting-yard_algorithm). Here is a simple example of an expression parser producing an AST (in Java though).

parsing of mathematical expressions

You need to write a lexical analyzer to tokenize the input (break it into its component parts--operators, punctuators, identifiers, etc.). Inevitably, you'll end up with some sequence of tokens.

After that, there are a number of ways to evaluate the input. One of the easiest ways to do this is to convert the expression to postfix using the shunting yard algorithm (evaluation of a postfix expression is Easy with a capital E).

How to parse mathematical expressions involving parentheses

Ages ago when working on a simple graphing app, I used this algorithm (which is reasonably easy to understand and works great for simple math expressions like these) to first turn the expression into RPN and then calculated the result. RPN was nice and fast to execute for different variable values.

Of course, language parsing is a very wide topic and there are many other ways of going about it (and pre-made tools for it too)

how to parse a matematical expression in C

There are many available projects doing it.

For example: https://github.com/codeplea/tinyexpr

Clone, test & see how it is done

Parse Math Expression

You can try using DataTable.Compute.

A related one is DataColumn.Expression.

Also check out: Doing math in vb.net like Eval in javascript

Note: I haven't used these myself.

Parsing simple mathematical expressions

To parse a number from the string as a double, you can use strtod():

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
if (argc == 1) {
printf("\n========================================================\n");
printf("Invalid usage: <ProgramName>.exe <MathExpression:string>\n");
printf("eg: 2+3/5*9\n");
printf("========================================================\n");
return 0;
}

char *expr = argv[1];

double answer = strtod(expr, &expr);

while (*expr) {
if (*expr == ' ' || *expr == '\t')
expr++;
else if (*expr == '+')
answer += strtod(expr + 1, &expr);
else if (*expr == '-')
answer -= strtod(expr + 1, &expr);
else if (*expr == '*')
answer *= strtod(expr + 1, &expr);
else if (*expr == '/')
answer /= strtod(expr + 1, &expr);
else
break;
}
printf("answer: %.2f\n", answer);
return 0;
}

Note that invalid input may produce surprising results. Here is a simple way to detect invalid input:

#include <stdio.h>
#include <stdlib.h>

double get_number(const char *expr, char **nextp) {
double value = strtod(expr, nextp);
if (expr == *nextp) {
fprintf(stderr, "invalid input: %s\n", expr);
exit(1);
}
return value;
}

int main(int argc, char *argv[]) {
if (argc == 1) {
printf("\n========================================================\n");
printf("usage: <ProgramName>.exe <MathExpression:string>\n");
printf("eg: '2+3/5*9'\n");
printf("========================================================\n");
return 0;
}

char *expr = argv[1];

double answer = get_number(expr, &expr);

while (*expr) {
if (*expr == ' ' || *expr == '\t')
expr++;
else if (*expr == '+')
answer += get_number(expr + 1, &expr);
else if (*expr == '-')
answer -= get_number(expr + 1, &expr);
else if (*expr == '*')
answer *= get_number(expr + 1, &expr);
else if (*expr == '/')
answer /= get_number(expr + 1, &expr);
else {
printf("invalid input: %s\n", expr);
break;
}
}
printf("answer: %.2f\n", answer);
return 0;
}


Related Topics



Leave a reply



Submit