code: public Expression constructTree(ArrayList<String> postTokens)
      {
          Expression root = null;
          Stack<Expression> nodes = new Stack<>();
  
          for(String str: postTokens)
          {
              if(str.isEmpty()){
                  continue;
              }
              if(str.matches("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?")) {
                  nodes.push(new Constant(Double.parseDouble(str)));
              }
              else if(str.equals(var)) {
                  nodes.push(new Variable(var));
              }
              else if(!nodes.isEmpty() && ExpressionParser.isFunction(str)) {
                  Expression function = matchFunc(str, nodes.pop());
                  nodes.push(function);
              }
              else if(!nodes.isEmpty() && str.equals("$")) {
                  Expression unaryMinus = new Negation(nodes.pop());
                  nodes.push(unaryMinus);
              }
              else if(!nodes.isEmpty()){
                  Expression right = nodes.pop();
                  Expression binaryOperator = matchOperator(str, nodes.pop(), right);
                  nodes.push(binaryOperator);
              }
          }
  
          if(!nodes.isEmpty())
              root = nodes.pop();
  
          return root;
      }
docs: reads the "tokens" in order from the list and builds a tree