title: Unary operators, binary expression tree and shunting yard algorithm
body: <p>I am writing the mathematics expression solver which takes infix expression and solves them, both binary expression tree and shunting-yard are doing good for me (I have even solved the problem of handling unary and ternary operators). Encountered an issue with trigonometric functions. When I write 45sin or (45)sin or (44+1)sin, shunting-yard converts it to valid Reverse Polish Notation(RPN) and evaluation is successful. Though the valid infix expression is sin(44+1) or sin45 + 1. Please suggest to solve this pr1oblem.</p>
  
  <p>Here is the java code from class ExpressionEval which converts infix to RPN.</p>
  
  <pre><code>public String infixToPostFix2(String[] expression)
  {
      String val = "";
  
      if (expression == null || expression.length &lt;= 0)
      return "";
  
      Stack&lt;String&gt; stack = new Stack&lt;String&gt;();
      ArrayList&lt;String&gt; exp = new ArrayList&lt;String&gt;();
  
      for (String token : expression)
      {
          if (OperatorList.isOperator(token))
          {
              Operator o1 = OperatorList.getOperator(token);
              Operator o2 = null;
              while (!stack.empty() &amp;&amp; OperatorList.isOperator(stack.peek()))
              {
                  o2 = OperatorList.getOperator(stack.peek());
                  if (    (o1.getAssociativity() == Associativity.LEFT &amp;&amp; o1.lessThanEqual(o2))
                      || (o1.getAssociativity() == Associativity.RIGHT &amp;&amp; o1.lessThan(o2))
                      )
                  {
                      exp.add(stack.pop());
                      continue;
                  }
                  break;
              }
              stack.push(token);
          }
          else if(OperatorList.isLeftParenthesis(token))
          {
              stack.push(token);
          }
          else if (OperatorList.isRightParentheis(token))
          {
              while(!OperatorList.isLeftParenthesis(stack.peek()))
              {
                  if (stack.empty())
                  {
                      this.error = Error.MISMATCHED_PARANTHESIS;
                      return ""; //Mismatched paranthesis
                  }
                  exp.add(stack.pop());
              }
  
              stack.pop();//Pop off the left paranthesis but not move to output
          }
          else //Operands
          {
              exp.add(token);
          }
          }
  
          while(!stack.empty())
          {
          String s = stack.pop();
          if (OperatorList.isParanthesis(s))
          {
              this.error = Error.MISMATCHED_PARANTHESIS;
              return "";
          }
          exp.add(s);
      }
  
      postfixExpression = new String[exp.size()];
      int index = 0;
      for (String elem : exp)
      {
      postfixExpression[index++] = elem;
      }
  
      CalcDebug.printArray(postfixExpression);
  
      return val;
  }
  </code></pre>
  
  <p>Once we have post-fix expression the evaluation is done in this function of ExpressionEval class</p>
  
  <pre><code> public double evaluateExpression(String[] postfixExpression) {
  
      CalcDebug.Debug("evaluateExpression()");
  
      double val = 0.0;
      if (postfixExpression == null || postfixExpression.length &lt;= 0)
          return val;
  
      Stack&lt;String&gt; operationStack = new Stack&lt;String&gt;();
  
      CalcDebug.printArray(postfixExpression);
  
      for (String elem : postfixExpression) {
  
          CalcDebug.Debug("elem = " + elem);
  
          if (!OperatorList.isOperator(elem)) {
              operationStack.push(elem);
          } else {
              double arg0 = 0.0;
              double arg1 = 0.0;
              double arg2 = 0.0;
  
              OperatorType t = OperatorList.getOperatorType(elem);
              if (t == OperatorType.BINARY) {
                  arg1 = Double.parseDouble(operationStack.pop());
                  arg0 = Double.parseDouble(operationStack.pop());
                  val = CalculatorBrain.performCalculation(elem, arg0, arg1);
              } else if (t == OperatorType.UNARY) {
                  arg0 = Double.parseDouble(operationStack.pop());
                  val = CalculatorBrain.performCalculation(elem, arg0);
              } else if (t == OperatorType.TERNARY) {
                  arg2 = Double.parseDouble(operationStack.pop());
                  arg1 = Double.parseDouble(operationStack.pop());
                  arg0 = Double.parseDouble(operationStack.pop());
                  val = CalculatorBrain.performCalculation(elem, arg0, arg1,
                          arg2);
              }
              operationStack.push(Double.toString(val));
          }
  
          CalcDebug.printStack(operationStack);
      }
  
      val = Double.parseDouble(operationStack.pop());
  
      CalcDebug.Debug("val = " + val);
  
      return val;
  }
  </code></pre>
  
  <p>Operator class is somewhat similar to this.</p>
  
  <pre><code>package com.studentscalculator;
  
  import com.studentscalculator.OperatorComparator.OPERATOR_PRIORITY;
  
  public class Operator
  {
  
      public enum OperatorType
      {
          UNARY, BINARY, TERNARY
      }
  
      public enum Associativity
      {
          LEFT, RIGHT
      }
  
      private String operator;
      public String getOperator(){return operator;}
      public void setOperator(String operator){this.operator = operator;}
  
      private int order;
      public int getOrder(){return order;}
      public void setOrder(int order){this.order = order;}
  
      private OperatorType type;
      public OperatorType getType(){ return type; }
      public void setType(OperatorType type){ this.type = type; }
  
      private Associativity associativity;
      public Associativity getAssociativity(){ return associativity;}
      public void setAssociativity(Associativity associativity){ this.associativity = associativity; }
  
      //Constructors
      public Operator(String operator)
      {
          this.setOperator(operator);
          this.setOrder(OperatorList.getOperatorOrder(operator));
          this.setType(OperatorList.getOperatorType(operator));
          this.setAssociativity(OperatorList.getOperatorAssociativity(operator));
      }
  
      public Operator(String operator, int order)
      {
          this.setOperator(operator);
          this.setOrder(order);
          this.setType(OperatorList.getOperatorType(operator));
      }
  
      public Operator(String operator, int order, OperatorType t)
      {
         init(operator, order, t, Associativity.LEFT);
      }
  
      public Operator(String operator, int order, OperatorType t, Associativity a)
      {
         init(operator, order, t, a);
      }
  
      void init(String operator, int order, OperatorType t, Associativity a)
      {
          this.setOperator(operator);
          this.setOrder(order);
          this.setType(t);
          this.setAssociativity(a);
      }
  
  
      public boolean lessThanEqual(Operator arg0)
      {
          int val = -(this.order - arg0.order);
          if (val &lt;= 0)
              return true;
          else
              return false;
      }
  
      public boolean lessThan(Operator arg0)
      {
          int val = -(this.order - arg0.order);
          if (val &lt; 0)
              return true;
          else
              return false;
      }
  
      @Override
      public String toString()
      {
          String val = String.format("Operator = %s : Order %s", getOperator(), getOrder());
          return val;
      }
  
  }
  </code></pre>