2010年11月21日 星期日

Expression Parser - 五則運算式解析

import java.util.HashMap;

public class OperatorPrioritySaver {
 HashMap priorityMap = new HashMap();
 public OperatorPrioritySaver() {
  priorityMap.put("+", 1);
  priorityMap.put("-", 1);
  priorityMap.put("*", 2);
  priorityMap.put("/", 2);
  priorityMap.put("%", 2);
 }
 int comp(String op1, String op2) throws RuntimeException{
  if(priorityMap.get(op1)==null ){
   throw new RuntimeException("not an accept op :" +op1);
  }
  if(priorityMap.get(op2)==null ){
   throw new RuntimeException("not an accept op :" +op2);
  }
  return priorityMap.get(op1).compareTo(priorityMap.get(op2));
 }
 boolean acceptOperator(String test){
  return priorityMap.keySet().contains(test);
 }
}
import java.util.Stack;

public class ExpressionParser {
 private String exprString ;
 private int value ;

 OperatorPrioritySaver opsvr = new OperatorPrioritySaver();

 Stack nums = new Stack();
 Stack ops = new Stack();
 
 public ExpressionParser(String exprString) {
  this.exprString = exprString ;
 }
 public String getExprString(){
  return exprString ;
 }
 public int getValue() {
  return value;
 }
 
 public String toString() {
  return exprString +" = " + value ;
 }
 public void parse() {
  String terns[] = exprStr2Terns();
  
  int num = 0 ;
  String op = null ;
  for(String tern : terns){
   try{
    num = Integer.parseInt(tern) ;
    op = null ;
   }catch(NumberFormatException e){
    op = tern ;
   }
   
   if(op == null){ // number
    nums.push(num);
   }else{ // operator
    String top = null ;
    if("(".equals(op) || ")".equals(op)){
     if("(".equals(op)){
      ops.push(op);
     }else if(")".equals(op)){
      while( (top = ops.pop()) != null && 
        (!top.equals("("))){
       doOperator(top);
      }
     }
    }else if(opsvr.acceptOperator(op)){
     while( ops.size() > 0 &&
       (top = ops.peek()) != null && 
       (!top.equals("(")) && 
       (opsvr.comp(top, op)>=0)){
      top = ops.pop();
      doOperator(top);
     }
     ops.push(op);
    }else {
     System.err.println("Unsupported operator : " + op);
    }
   }
  }
  while(ops.size() != 0){
   doOperator(ops.pop());
  }
  
  value = nums.get(0);
 }
 private String[] exprStr2Terns() {
  // 目前使用空格隔開所有的符號
  // 想不用空格隔開 可以自行修改
  return exprString.split(" ");
 }

 private void doOperator(String op) {
  char opCh = op.toCharArray()[0];
  int num2 = 0, num1 = 0;
  switch(opCh){
  case '+':
   num2 = nums.pop();
   num1 = nums.pop();
   nums.push(num1+num2);
   break;
  case '-': 
   num2 = nums.pop();
   num1 = nums.pop();
   nums.push(num1-num2);
   break;
  case '*': 
   num2 = nums.pop();
   num1 = nums.pop();
   nums.push(num1*num2);
   break;
  case '/': 
   num2 = nums.pop();
   num1 = nums.pop();
   nums.push(num1/num2);
   break;
  case '%': 
   num2 = nums.pop();
   num1 = nums.pop();
   nums.push(num1%num2);
   break;
  }
 }
 public static void main(String[] args) {
  ExpressionParser expr = new ExpressionParser("( 1 + 2 ) * 3");
  expr.parse();
  System.out.println(expr);
 }
}

沒有留言:

張貼留言