Infix to Postfix Convertor

  1. /**
  2.  * filename: InfixToPostfixConvertor.java
  3.  * package: 
  4.  * author: Nick Ma
  5.  * email: [email protected]
  6.  * date: Nov 1, 2008
  7.  * description: this class implements a string convertor from infix to postfix.
  8.  */
  9. import  java.util.*;
  10. public   class  InfixToPostfixConvertor {
  11.          // Data Field
  12.         
  13.          /** the operator stack */
  14.          private  Stack<Character> operatorStack;
  15.         
  16.          /** the operators */
  17.          private   static   final  String OPERATORS =  "+-*/()" ;
  18.         
  19.          /** the precedence of the operators */
  20.          private   static   final   int [] PRECEDENCE = { 1 1 2 2 , - 1 , - 1 };
  21.         
  22.          /** the postfix string */
  23.          private  StringBuilder postfix;
  24.         
  25.          /**
  26.          * description: the default constructor
  27.          */
  28.          public  InfixToPostfixConvertor() {
  29.                  // TODO Auto-generated constructor stub
  30.                 
  31.                 postfix =  new  StringBuilder();
  32.         }
  33.          /**
  34.          * description: convert a string from infix to postfix
  35.          * @param infix - the infix string to input
  36.          * @return - the postfix string
  37.          * @throws Exception
  38.          */
  39.          public  String convert(String infix)  throws  Exception {
  40.                 operatorStack =  new  Stack<Character>();
  41.                 
  42.                 StringTokenizer infixTokens =  new  StringTokenizer(infix);
  43.                  try  {
  44.                          // process each token in the infix string
  45.                          while (infixTokens.hasMoreTokens()) {
  46.                                 String nextToken = infixTokens.nextToken();
  47.                                  char  firstChar = nextToken.charAt( 0 );
  48.                                  // determine if it is an operator
  49.                                  if (Character.isJavaIdentifierStart(firstChar)
  50.                                                 || Character.isDigit(firstChar)){
  51.                                         postfix.append(nextToken);
  52.                                         postfix.append( ' ' );
  53.                                 }  else   if (isOperator(firstChar)) {
  54.                                         processOperator(firstChar);
  55.                                 }  else  {
  56.                                          throw   new  SyntaxErrorException( "syntax error!" );
  57.                                 }
  58.                         }
  59.                         
  60.                          // pop any remaining operators and append them to postfix
  61.                          while (!operatorStack.isEmpty()) {
  62.                                 Character op = operatorStack.pop();
  63.                                  // any '(' on the stack is not matched
  64.                                  if (op.charValue() ==  '(' ) {
  65.                                          throw   new  SyntaxErrorException( "syntax error!" );
  66.                                 }
  67.                                 postfix.append(op);
  68.                                 postfix.append( ' ' );
  69.                         }
  70.                          return  postfix.toString();
  71.                 }  catch (EmptyStackException e) {
  72.                          throw   new  SyntaxErrorException( "the stack is empty!" );
  73.                 }
  74.         }
  75.         
  76.          /**
  77.          * description: process operators
  78.          * @param op - the operator
  79.          */
  80.          private   void  processOperator( char  op) {
  81.                  if (operatorStack.isEmpty() || op ==  '(' ) {
  82.                         operatorStack.push(op);
  83.                 }  else  {
  84.                          // peek the operator stack
  85.                          char  topOp = operatorStack.peek().charValue();
  86.                          if (precedence(op) > precedence(topOp)) {
  87.                                 operatorStack.push(op);
  88.                         }  else  {
  89.                                  // pop all stacked operators with equal or higher precedence than op
  90.                                  while (!operatorStack.isEmpty() && precedence(op) <= precedence(topOp)) {
  91.                                         operatorStack.pop();
  92.                                          if (topOp ==  '(' ) {
  93.                                                  break ;
  94.                                         }
  95.                                         postfix.append(topOp);
  96.                                         postfix.append( ' ' );
  97.                                          if (!operatorStack.isEmpty()) {
  98.                                                  // reset topOp
  99.                                                 topOp = operatorStack.peek().charValue();
  100.                                         }
  101.                                 }
  102.                                  if (op !=  ')' ) {
  103.                                         operatorStack.push(op);
  104.                                 }
  105.                         }
  106.                 }
  107.         }
  108.         
  109.          /**
  110.          * description: determine the precedence of an operator
  111.          * @param op - the operator
  112.          * @return - the precedence
  113.          */
  114.          private   int  precedence( char  op) {
  115.                  return  PRECEDENCE[OPERATORS.indexOf(op)];
  116.         }
  117.         
  118.          /**
  119.          * description: determine whether a char is an operator
  120.          * @param op - the given char
  121.          * @return - true if the char is an operator
  122.          */
  123.          private   boolean  isOperator( char  op) {
  124.                  return  OPERATORS.indexOf(op) != - 1 ;
  125.         }
  126.         
  127.          // test function
  128.          public   static   void  main(String[] args) {
  129.                 InfixToPostfixConvertor pc =  new  InfixToPostfixConvertor();
  130.                  try  {
  131.                         System.out.println(pc.convert( "( x + y ) * ( ( a + b ) / c )" ));
  132.                 }  catch (Exception e) {
  133.                         e.printStackTrace();
  134.                 }       
  135.         }
  136. }
  137. /**
  138.  * filename: SyntaxErrorException.java
  139.  * package:  
  140.  * author:   Li Ma
  141.  * email:    [email protected]
  142.  * date:     Oct 3, 2008
  143.  * description: this exception shows a syntax error.
  144.  */
  145. public   class  SyntaxErrorException  extends  Exception {
  146.          private   static   final   long  serialVersionUID = 1L;
  147.          public  SyntaxErrorException( final  String message) {
  148.                  super (message);
  149.         }
  150. }
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章