# How Would You Write A Dynamic Text Input Calculator?

This topic is 2759 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello all, I was wondering how any of you would write a dynamic text input calculator. I.E Lets say you have a single line text input field where the user can type their formula. How would you go about figuring out how to do the correct math calculations from the variables collected in a string?

Lets say the current input field value is "2 + 2"

structure mathStep Vector
enum m_type;
var value;

cLine = removeSpacesInText

For Each Character in cLine Loop

if cLine Character Does Not Equal to any operator.

Add Character to tempString

Else

Convert tempString into correct variable type determining if the string has a period in it.
Then add the variable to the mathStep Vector
After adding it to the to do list then add the operator to the back of the list. Simply by changing the m_type to PLUS and add it to the vector.

End If

End For Loop

If float/double/int use the correct variable type for the result value variable.

For Each Element in mathStep
Add/Subtract/etc to result value
End If

Return Result

I had something like that in mind, I didn't write it in C++ yet, but I've been pondering if there are better ways and variable types to use then adding a bunch of variables in a struct if it's a float or int, a plus, minus, etc in the text we are figuring out what it result is.

##### Share on other sites
One solution would be to first tokenize the input line using regular expressions. This would convert the input string "2 + 2" to a token list like { Value(2), Operator(+), Value(2) }. Next, perform a syntactic analysis which identifies and organizes (typically in some tree structure) the elements that need to be evaluated. Continuing with our "2 + 2" example this would create a tree from the token list with 3 nodes constituting a single addition expression: { Addition(Value(2),Value(2)) }. Lastly, evaluate the tree (or more specifically each node in the tree), which in our example would yield something like Value(4).

##### Share on other sites
If you can get your hands one Bjarne's "The C++ Programming Language" book, he explains how to create a calculator. The source code can also be found at his site.

##### Share on other sites

One solution would be to first tokenize the input line using regular expressions. This would convert the input string "2 + 2" to a token list like { Value(2), Operator(+), Value(2) }. Next, perform a syntactic analysis which identifies and organizes (typically in some tree structure) the elements that need to be evaluated. Continuing with our "2 + 2" example this would create a tree from the token list with 3 nodes constituting a single addition expression: { Addition(Value(2),Value(2)) }. Lastly, evaluate the tree (or more specifically each node in the tree), which in our example would yield something like Value(4).

The tree structure you would want happens to have a name as well

##### Share on other sites
I would use Flex and Bison.

L. Spiro

##### Share on other sites
The tree structure you would want happens to have a name as well

Thanks, I haven't worked on a compiler since 1998 so I have admittedly forgotten about many of the data structures used in this branch of programming.

##### Share on other sites
A couple of alternatives that haven't been mentioned:

• There is a well-known algorithm that converts infix notation (what you have) to reverse polish notation. Once you have the expression in RPN, computing the result is trivially achieved using a stack.
• You can also write your own recursive descent parser for the types of expressions that you expect. I think this is a good exercise to go through at some point.

##### Share on other sites
I would second alvaro and suggest rolling a recursive descent parser - there are lots of examples and explanations around, and it is indeed a good fundamental excercise.

##### Share on other sites
Here's a recursive descent parser I just hacked together. The hardest part is reporting meaningful errors, which I haven't been careful about:
#include <iostream> #include <cstdio> #include <cctype> #include <cstdlib> void skip_white_space(char const *&s) { while (isspace(*s)) ++s; } double compute_expression(char const *&s); double compute_non_signed_factor(char const *&s) { double result; if (isdigit(*s)) { int n_characters_read; std::sscanf(s, "%lg%n", &result, &n_characters_read); s += n_characters_read; skip_white_space(s); } else if (*s == '(') { ++s; skip_white_space(s); result = compute_expression(s); if (*s != ')') { std::cerr << ")' expected\n"; std::exit(1); } ++s; skip_white_space(s); } else { std::cerr << "Number or (' expected\n"; std::exit(1); } return result; } double compute_factor(char const *&s) { bool positive = true; if (*s == '+') positive = true, ++s, skip_white_space(s); else if (*s == '-') positive = false, ++s, skip_white_space(s); return positive ? compute_non_signed_factor(s) : -compute_non_signed_factor(s); } double compute_term(char const *&s) { double result = 1.0; bool dividing = false; while (1) { result *= dividing ? 1.0 / compute_factor(s) : compute_factor(s); if (*s == '*') dividing = false, ++s, skip_white_space(s); else if (*s == '/') dividing = true, ++s, skip_white_space(s); else break; } return result; } double compute_expression(char const *&s) { double result = 0.0; bool subtracting = false; while (1) { result += subtracting ? -compute_term(s) : compute_term(s); if (*s == '+') subtracting = false, ++s, skip_white_space(s); else if (*s == '-') subtracting = true, ++s, skip_white_space(s); else break; } return result; } double compute(char const *s) { skip_white_space(s); double result = compute_expression(s); if (*s != '\0') { std::cerr << "End of line expected\n"; std::exit(1); } return result; } int main() { std::cout << compute("2+2") << '\n'; } 

EDIT: My code had some issues with unary + and - operators, but I fixed them.

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 9
• 11
• 15
• 21
• 26