You are trying to write a parser.
There are so many ways to do this, with some ways being especially optimized for infix expressions, and others being more general.
I personally suggest reading about Recursive Descent parsers, as they are a good starting point to learn about parsers since they are relatively simple and intuitive.
A simple recursive descent parser that handles expression with addition, subtraction, multiplication, division and parentheses would look something like this (This is pseudocode!):
node* readExpr() {
return readAddOrSub();
}
node* readAddOrSub() {
leftTree = readMulOrDiv();
token = peekNextToken(); // look at the next token without consuming it
if (token == '+' || token == '-') {
readNextToken(); // skip operator
rightTree = readAddOrSub();
return an addition or subtraction node with leftTree and rightTree as its left and right sub-trees respectively;
} else {
return leftTree;
}
}
node* readMulOrDiv() {
leftTree = readAtom();
token = peekNextToken();
if (token == '*' || token == '/') {
readNextToken(); // skip operator
rightTree = readMulOrDiv();
return a multiplication node with leftTree and rightTree as its left and right sub-trees respectively;
} else {
return leftTree;
}
}
node* readAtom() {
token = readNextToken()
if (token == '(') {
result = readExpr();
read another token and make sure it's ')';
return result;
} else if (token is a number)
return node holding a number;
else if (token is a variable)
return node holding a variable;
else
error();
}
This assumes you have something that breaks up your string apart into tokens (e.g. "5*(a+12)" should be broken into 7 tokens: the number 5, '*', '(', the variable 'a', '+', the number 12, ')').
Operator precedence is captured by the way that functions that parse an opeator of a certain precedence level call the functions that handle the next level of precedence in a hierarchical fashion. More specifically, a function that tries to parse an addition/subtraction node (readAddOrSub) calls the function that parses the next level of precedence (readMulOrDiv) to get its left and right sub-trees.
Note that readAddOrSub (and readMulOrDiv) calls itself to read the right-subtee so that multiple additions can be chained together ("1+2+3"), but beware that this makes the parser inherently right-associative ("1+2+3" will be parsed as "1+(2+3)").
Of course, it's not very hard to make it left-associative, but I'll leave that to you as an exercise!
Some resources that might help: