Expression.java
上传用户:njled888
上传日期:2007-01-07
资源大小:29k
文件大小:8k
- /*
- * @(#)Expression.java Version 1.0 98/03/12
- *
- * Copyright (c) 1998 by Huahai Yang
- *
- * Use at your own risk. I do not guarantee the fitness of this
- * software for any purpose, and I do not accept responsibility for
- * any damage you do to yourself or others by using this software.
- * This file may be distributed freely, provided its contents
- * are not tampered with in any way.
- *
- */
- import java.util.*;
- /**
- * Expression implements an simple arithmetic expression
- * ( can only handle 6 operators: +, -, *, /, ( and ) )
- * evaluation algorithem called operator precedence parsing.
- * Treats a String or a Vector as expression and return its
- * value (double) or throw an exception. It can skip whitespace.
- *
- * @version 1.0, 03/12/98
- * @author Huahai Yang
- */
- public class Expression
- {
- protected String inputExpression;
-
- private Stack operatorStack, //operator stack for conversion
- postFixStack; //stack for postfix machine
-
- //define tokens
- private final int EOL = 0, //end of line
- VALUE = 1, //number
- OPAREN = 2, //open parenthesis
- CPAREN = 3, //close parenthesis
- MULT = 4, //multiply
- DIV = 5, //division
- PLUS = 6,
- MINUS = 7;
-
- //define token precedences
- private final int [] INPUT_PRECEDENCE =
- { 0, 0, 100, 0, 3, 3, 1, 1 },
- STACK_PRECEDENCE =
- { -1, 0, 0, 99, 4, 4, 2, 2 };
-
- private double currentValue;
- private double theResult;
- private int lastToken;
-
- /**
- * Constructs an empty exprssion
- */
- public Expression()
- {
- inputExpression = null;
-
- operatorStack = new Stack();
- postFixStack = new Stack();
-
- operatorStack.push(new Integer(EOL));
- } // 0 param constructor
-
- /**
- * Takes a String as an expression
- * @param inString input string
- */
- public Expression(String inString)
- {
-
- inputExpression = inString.trim();
-
- operatorStack = new Stack();
- postFixStack = new Stack();
-
- operatorStack.push(new Integer(EOL));
- } // string param constructor
-
- /**
- * Takes a vector as an expression, by converting elements of
- * vector into strings
- * @param inVector input vector
- */
- public Expression(Vector inVector)
- {
- StringBuffer tmpString = new StringBuffer();
-
- for (Enumeration e = inVector.elements(); e.hasMoreElements();)
- {
- tmpString.append( e.nextElement() ) ;
- } // for
-
- inputExpression = (tmpString.toString()).trim();
-
- operatorStack = new Stack();
- postFixStack = new Stack();
-
- operatorStack.push(new Integer(EOL));
- } // vector param constructor
-
- /**
- * Sets the input string
- * @param inString input string
- */
- public void setExpression(String inString)
- {
- inputExpression = inString;
- } // setExpression
-
- /**
- * Gets the result of expression
- * @return result value of this expression
- * @exception IllegalExpressionException if encounter error while
- * while parsing input string as an expression
- */
- public double getValue() throws IllegalExpressionException
- {
- String token;
- char firstChar;
- StringTokenizer parser =
- new StringTokenizer(inputExpression, "+-*/() ", true);
-
- do
- {
- //end of expression
- if(!parser.hasMoreTokens())
- {
- lastToken = EOL;
- processToken();
- continue;
- } // if
-
- token = parser.nextToken();
- firstChar = token.charAt(0);
-
- // skip the ' '
- if(Character.isWhitespace(firstChar))
- {
- continue;
- } // if
-
- if( (token.length() == 1) && isOperator(firstChar) )
- {
- switch (firstChar)
- {
- case '+':
- lastToken = PLUS;
- break;
- case '-':
- lastToken = MINUS;
- break;
- case '*':
- lastToken = MULT;
- break;
- case '/':
- lastToken = DIV;
- break;
- case '(':
- lastToken = OPAREN;
- break;
- case ')':
- lastToken = CPAREN;
- break;
- } // switch
- } // if is operator
- else
- {
- try
- {
- currentValue = Double.valueOf(token).doubleValue();
- lastToken = VALUE;
- } //try
- catch ( NumberFormatException e )
- {
- throw new IllegalExpressionException("Unknown symbol");
- } //catch
- } // else suppose a number
- processToken();
-
- } while( lastToken != EOL );
-
- if( postFixStack.empty() )
- {
- throw new IllegalExpressionException("Missing operand");
- } // if missing operand
-
- theResult = ((Double)postFixStack.pop()).doubleValue();
-
- if( !postFixStack.empty() )
- {
- throw new IllegalExpressionException("Missing operator");
- } // if missing operator
-
- return theResult;
-
- } // getValue
-
- private void processToken() throws IllegalExpressionException
- {
- int topOperator;
-
- switch(lastToken)
- {
- case VALUE:
- postFixStack.push(new Double(currentValue));
- return;
- case CPAREN:
- while( (topOperator =
- ((Integer)operatorStack.peek()).intValue())
- != OPAREN && topOperator != EOL )
- {
- applyOperation( topOperator );
- } // while
- if( topOperator == OPAREN )
- {
- operatorStack.pop();
- } // if
- else
- {
- throw new IllegalExpressionException("Missing " +
- "open parenthesis");
- } //else
- break;
- default:
- while( INPUT_PRECEDENCE[lastToken] <=
- STACK_PRECEDENCE[ topOperator =
- ((Integer)operatorStack.peek()).intValue() ] )
- {
- applyOperation( topOperator );
- } //while
- if( lastToken != EOL )
- {
- operatorStack.push(new Integer(lastToken));
- } // if
- break;
- } //switch
- } //processToken
-
- private void applyOperation(int topOperator)
- throws IllegalExpressionException
- {
- double leftOperand,
- rightOperand;
-
- if( topOperator == OPAREN )
- {
- throw new IllegalExpressionException("Unbalanced parenthesis");
- } //if
-
- rightOperand = getPostStackTop();
- leftOperand = getPostStackTop();
-
- if( topOperator == PLUS )
- {
- postFixStack.push(new Double(leftOperand + rightOperand));
- } // if +
- else if( topOperator == MINUS )
- {
- postFixStack.push(new Double(leftOperand - rightOperand));
- } // else if -
- else if( topOperator == MULT )
- {
- postFixStack.push(new Double(leftOperand * rightOperand));
- } // else if *
- else if( topOperator == DIV )
- {
- if( rightOperand != 0)
- {
- postFixStack.push(new Double(leftOperand / rightOperand));
- } // if
- else
- {
- throw new IllegalExpressionException("Division by zero");
- } // else erro
- } // if /
-
- operatorStack.pop();
- } // applyOperation
-
- private double getPostStackTop() throws IllegalExpressionException
- {
- if( postFixStack.empty() )
- {
- throw new IllegalExpressionException("Missing operand");
- } // if
- return ((Double)postFixStack.pop()).doubleValue();
- } //getPostStackTop
-
- private boolean isOperator(char c)
- {
- return (c == '+' || c =='-' || c == '*' || c == '/'
- || c == '(' || c == ')' );
- } // isOperator
-
- } // Expression