public static ArrayList<Symbol> toSymbols(String expression) { ArrayList<Symbol> symbols = new ArrayList<>(); for (int i = 0; i < expression.length(); i++) { char c = expression.charAt(i); if (isBracket(c)) { // bracket symbols.add(new Symbol(c)); } else if (c == ',') { symbols.add(new Symbol(c)); } else if (isOperator(c)) { if (c == '-') { if (i == 0) { // must be first +/-, so add 0 symbols.add(new Symbol(BigDecimal.valueOf(0))); symbols.add(new Symbol(c)); } else { char previous = expression.charAt(i - 1); if ((previous == ')') || isNumber(String.valueOf(previous))) { // must be "minus" // e.g. sin(3)-5, 100-5, symbols.add(new Symbol(c)); } else if ((previous == '(') || (previous == ',')) { // must be "negative" // e.g. (-3+5)/2 symbols.add(new Symbol(BigDecimal.valueOf(0))); symbols.add(new Symbol(c)); } else if ((previous == '*') || (previous == '/') || (previous == '^')) { int end = Symbol.getNumberEndAt(i + 1, expression); symbols.add(new Symbol(new BigDecimal(expression.substring(i, end)))); i = end - 1; } } } else { symbols.add(new Symbol(c)); } } else if (Character.isLetter(c)) { // function int end = Symbol.getFunctionEndAt(i, expression); symbols.add(new Symbol(expression.substring(i, end))); i = end - 1; } else if (Character.isDigit(c)) { int end = Symbol.getNumberEndAt(i, expression); String number = expression.substring(i, end); symbols.add(new Symbol(new BigDecimal(number))); i = end - 1; } } return symbols; }