Для начала опишите минимальный язык ваших выражений:
<выражение> ::= <литерал> <оператор> <литерал>
<литерал> ::= <число> | (<выражение>)
<число> ::= [<число> | "-"]<0-9> // или всё, что парсится parseInt.
<оператор> ::= < + | - | * | / >
Теперь можно видеть структуру вашего выражения, и применить какой-то алгоритм парсинга:
Выражение начинается с литерала, значит, считываем символы из входной строки, пока не встретим пробел или \0: если это цифры, то наш литерал - число, если "(" - выражение, для которого нужно повторить всю процедуру, ожидая закрытия ")". Дальше считываем оператор. А потом снова литерал. Если что-то по правилам не подходит, то завершаемся с ошибкой.
Ну и каждый литерал может быть вычислен - число возвращает число, а выражение возвращает результат применения оператора к двум литералам. Общий результат - результат вычисления корневого выражения.