code: public Node parse(String text) {
          if (text.isEmpty()) {
              return null;
          }
          String postfix = toPostfix(text);
  
          Deque<Node> stack = new ArrayDeque<Node>();
  
          StringTokenizer tokenizer = new StringTokenizer(postfix);
          String token;
          FunctionFactory factory = FactoryManager.instance().function();
          while (tokenizer.hasMoreTokens()) {
              token = tokenizer.nextToken();
  
              Element element = factory.getObject(token);
  
              boolean isOperand = element == null && !"(".equals(token) && !")".equals(token)
                      && !",".equals(token);
  
              if (element != null) {
                  if (element.getArity() > stack.size()) {
                      throw new RuntimeException(String.format("[function error] " +
                                      "operator <%s> has arity <%d>, "
                                      + "but <%d> elements are available: (%s)",
                              element.getName(), element.getArity(), stack.size(),
                              Op.join(stack, ", ")));
                  }
  
                  Node node;
                  try {
                      node = new Node(element.clone());
                  } catch (Exception ex) {
                      throw new RuntimeException(ex);
                  }
                  node.left = stack.pop();
                  if (element.getArity() == 2) {
                      node.right = stack.pop();
                  }
                  stack.push(node);
              } else if (isOperand) {
                  Node node;
                  try {
                      double value = Op.toDouble(token);
                      node = new Node(value);
                  } catch (Exception ex) {
                      node = new Node(token);
                  }
                  stack.push(node);
              }
          }
          if (stack.size() != 1) {
              throw new RuntimeException(String.format(
                      "[function error] ill-formed formula <%s> due to: <%s>",
                      text, Op.join(stack, ";")));
          }
          return stack.pop();
      }
docs: Creates a node representing a binary expression tree from the given formula
  
  @param text is the right-hand side of a mathematical equation expressed in
  infix notation
  @return a node representing a binary expression tree from the given formula
  
  @throws RuntimeException if the formula has syntax errors