/* 
 
Software Architecture Design Patterns in Java 
by Partha Kuchana  
 
Auerbach Publications 
 
*/ 
 
 
 
import java.util.HashMap; 
import java.util.Stack; 
 
public class Calculator { 
  private String expression; 
 
  private HashMap operators; 
 
  private Context ctx; 
 
  public static void main(String[] args) { 
    Calculator calc = new Calculator(); 
    //instantiate the context 
    Context ctx = new Context(); 
 
    //set the expression to evaluate 
    calc.setExpression("(a+b)*(c-d)"); 
 
    //configure the calculator with the 
    // Context 
    calc.setContext(ctx); 
 
    //Display the result 
    System.out.println(" Variable Values: " + "a=" + ctx.getValue("a") 
        + ", b=" + ctx.getValue("b") + ", c=" + ctx.getValue("c") 
        + ", d=" + ctx.getValue("d")); 
    System.out.println(" Expression = (a+b)*(c-d)"); 
    System.out.println(" Result = " + calc.evaluate()); 
  } 
 
  public Calculator() { 
    operators = new HashMap(); 
    operators.put("+", "1"); 
    operators.put("-", "1"); 
    operators.put("/", "2"); 
    operators.put("*", "2"); 
    operators.put("(", "0"); 
  } 
 
  public void setContext(Context c) { 
    ctx = c; 
  } 
 
  public void setExpression(String expr) { 
    expression = expr; 
  } 
 
  public int evaluate() { 
    //infix to Postfix 
    String pfExpr = infixToPostFix(expression); 
 
    //build the Binary Tree 
    Expression rootNode = buildTree(pfExpr); 
 
    //Evaluate the tree 
    return rootNode.evaluate(ctx); 
  } 
 
  private NonTerminalExpression getNonTerminalExpression(String operation, 
      Expression l, Expression r) { 
    if (operation.trim().equals("+")) { 
      return new AddExpression(l, r); 
    } 
    if (operation.trim().equals("-")) { 
      return new SubtractExpression(l, r); 
    } 
    if (operation.trim().equals("*")) { 
      return new MultiplyExpression(l, r); 
    } 
 
    return null; 
  } 
 
  private Expression buildTree(String expr) { 
    Stack s = new Stack(); 
 
    for (int i = 0; i < expr.length(); i++) { 
      String currChar = expr.substring(i, i + 1); 
 
      if (isOperator(currChar) == false) { 
        Expression e = new TerminalExpression(currChar); 
        s.push(e); 
      } else { 
        Expression r = (Expression) s.pop(); 
        Expression l = (Expression) s.pop(); 
        Expression n = getNonTerminalExpression(currChar, l, r); 
        s.push(n); 
      } 
    }//for 
    return (Expression) s.pop(); 
  } 
 
  private String infixToPostFix(String str) { 
    Stack s = new Stack(); 
    String pfExpr = ""; 
    String tempStr = ""; 
 
    String expr = str.trim(); 
    for (int i = 0; i < str.length(); i++) { 
 
      String currChar = str.substring(i, i + 1); 
 
      if ((isOperator(currChar) == false) && (!currChar.equals("(")) 
          && (!currChar.equals(")"))) { 
        pfExpr = pfExpr + currChar; 
      } 
      if (currChar.equals("(")) { 
        s.push(currChar); 
      } 
      //for ')' pop all stack contents until '(' 
      if (currChar.equals(")")) { 
        tempStr = (String) s.pop(); 
        while (!tempStr.equals("(")) { 
          pfExpr = pfExpr + tempStr; 
          tempStr = (String) s.pop(); 
        } 
        tempStr = ""; 
      } 
      //if the current character is an 
      // operator 
      if (isOperator(currChar)) { 
        if (s.isEmpty() == false) { 
          tempStr = (String) s.pop(); 
          String strVal1 = (String) operators.get(tempStr); 
          int val1 = new Integer(strVal1).intValue(); 
          String strVal2 = (String) operators.get(currChar); 
          int val2 = new Integer(strVal2).intValue(); 
 
          while ((val1 >= val2)) { 
            pfExpr = pfExpr + tempStr; 
            val1 = -100; 
            if (s.isEmpty() == false) { 
              tempStr = (String) s.pop(); 
              strVal1 = (String) operators.get(tempStr); 
              val1 = new Integer(strVal1).intValue(); 
 
            } 
          } 
          if ((val1 < val2) && (val1 != -100)) 
            s.push(tempStr); 
        } 
        s.push(currChar); 
      }//if 
 
    }// for 
    while (s.isEmpty() == false) { 
      tempStr = (String) s.pop(); 
      pfExpr = pfExpr + tempStr; 
    } 
    return pfExpr; 
  } 
 
  private boolean isOperator(String str) { 
    if ((str.equals("+")) || (str.equals("-")) || (str.equals("*")) 
        || (str.equals("/"))) 
      return true; 
    return false; 
  } 
} // End of class 
 
class Context { 
  private HashMap varList = new HashMap(); 
 
  public void assign(String var, int value) { 
    varList.put(var, new Integer(value)); 
  } 
 
  public int getValue(String var) { 
    Integer objInt = (Integer) varList.get(var); 
    return objInt.intValue(); 
  } 
 
  public Context() { 
    initialize(); 
  } 
 
  //Values are hardcoded to keep the example simple 
  private void initialize() { 
    assign("a", 20); 
    assign("b", 40); 
    assign("c", 30); 
    assign("d", 10); 
  } 
 
} 
 
class TerminalExpression implements Expression { 
  private String var; 
 
  public TerminalExpression(String v) { 
    var = v; 
  } 
 
  public int evaluate(Context c) { 
    return c.getValue(var); 
  } 
} 
 
interface Expression { 
  public int evaluate(Context c); 
} 
 
abstract class NonTerminalExpression implements Expression { 
  private Expression leftNode; 
 
  private Expression rightNode; 
 
  public NonTerminalExpression(Expression l, Expression r) { 
    setLeftNode(l); 
    setRightNode(r); 
  } 
 
  public void setLeftNode(Expression node) { 
    leftNode = node; 
  } 
 
  public void setRightNode(Expression node) { 
    rightNode = node; 
  } 
 
  public Expression getLeftNode() { 
    return leftNode; 
  } 
 
  public Expression getRightNode() { 
    return rightNode; 
  } 
}// NonTerminalExpression 
 
class AddExpression extends NonTerminalExpression { 
  public int evaluate(Context c) { 
    return getLeftNode().evaluate(c) + getRightNode().evaluate(c); 
  } 
 
  public AddExpression(Expression l, Expression r) { 
    super(l, r); 
  } 
}// AddExpression 
 
class SubtractExpression extends NonTerminalExpression { 
  public int evaluate(Context c) { 
    return getLeftNode().evaluate(c) - getRightNode().evaluate(c); 
  } 
 
  public SubtractExpression(Expression l, Expression r) { 
    super(l, r); 
  } 
}// SubtractExpression 
 
class MultiplyExpression extends NonTerminalExpression { 
  public int evaluate(Context c) { 
    return getLeftNode().evaluate(c) * getRightNode().evaluate(c); 
  } 
 
  public MultiplyExpression(Expression l, Expression r) { 
    super(l, r); 
  } 
 
}// MultiplyExpression 
 
 
//File: Interprepter.properties 
/* 
a=10 
b=20 
c=30 
d=40 
 
*/ 
 
 
            
       
  |