Expression.java
上传用户:njled888
上传日期:2007-01-07
资源大小:29k
文件大小:8k
源码类别:

游戏

开发平台:

Java

  1. /*
  2.  * @(#)Expression.java Version 1.0 98/03/12
  3.  * 
  4.  * Copyright (c) 1998 by Huahai Yang
  5.  * 
  6.  * Use at your own risk. I do not guarantee the fitness of this 
  7.  * software for any purpose, and I do not accept responsibility for 
  8.  * any damage you do to yourself or others by using this software.
  9.  * This file may be distributed freely, provided its contents 
  10.  * are not tampered with in any way.
  11.  *
  12.  */
  13. import java.util.*;
  14. /**
  15.  * Expression implements an simple arithmetic expression 
  16.  * ( can only handle 6 operators: +, -, *, /, ( and ) ) 
  17.  * evaluation algorithem called operator precedence parsing.  
  18.  * Treats a String or a Vector as expression and return its 
  19.  * value (double) or throw an exception. It can skip whitespace. 
  20.  * 
  21.  * @version  1.0, 03/12/98
  22.  * @author     Huahai Yang
  23.  */
  24. public class Expression 
  25. {
  26.    protected String inputExpression;
  27.    
  28.    private Stack operatorStack,  //operator stack for conversion
  29.                  postFixStack;   //stack for postfix machine
  30.    
  31.    //define tokens              
  32.    private final int EOL = 0,    //end of line
  33.                      VALUE = 1,  //number
  34.                      OPAREN = 2, //open parenthesis
  35.                      CPAREN = 3, //close parenthesis
  36.                      MULT = 4,   //multiply
  37.                      DIV = 5,    //division
  38.                      PLUS = 6,   
  39.                      MINUS = 7;
  40.    
  41.    //define token precedences
  42.    private final int [] INPUT_PRECEDENCE =
  43.                            { 0, 0, 100, 0, 3, 3, 1, 1 },
  44.                         STACK_PRECEDENCE =
  45.                            { -1, 0, 0, 99, 4, 4, 2, 2 };
  46.    
  47.    private double currentValue;
  48.    private double theResult;
  49.    private int lastToken;
  50.    
  51.    /**
  52.     * Constructs an empty exprssion
  53.     */
  54.    public Expression()
  55.    {
  56.       inputExpression = null;
  57.       
  58.       operatorStack = new Stack();
  59.       postFixStack = new Stack();
  60.       
  61.       operatorStack.push(new Integer(EOL));
  62.    } // 0 param constructor
  63.    
  64.    /**
  65.     * Takes a String as an expression
  66.     * @param inString input string
  67.     */
  68.    public Expression(String inString) 
  69.    {
  70.          
  71.       inputExpression = inString.trim();
  72.       
  73.       operatorStack = new Stack();
  74.       postFixStack = new Stack();
  75.       
  76.       operatorStack.push(new Integer(EOL));
  77.    } // string param constructor
  78.    
  79.    /**
  80.     * Takes a vector as an expression, by converting elements of 
  81.     * vector into strings
  82.     * @param inVector input vector
  83.     */
  84.    public Expression(Vector inVector)
  85.    {
  86.       StringBuffer tmpString = new StringBuffer();
  87.             
  88.       for (Enumeration e = inVector.elements(); e.hasMoreElements();)
  89.       {
  90.          tmpString.append( e.nextElement() ) ; 
  91.       } // for
  92.       
  93.       inputExpression = (tmpString.toString()).trim();
  94.       
  95.       operatorStack = new Stack();
  96.       postFixStack = new Stack();
  97.       
  98.       operatorStack.push(new Integer(EOL));
  99.    } // vector param constructor  
  100.    
  101.    /**
  102.     * Sets the input string
  103.     * @param inString input string
  104.     */
  105.    public void setExpression(String inString)
  106.    {
  107.       inputExpression = inString;
  108.    } // setExpression
  109.    
  110.    /**
  111.     * Gets the result of expression
  112.     * @return     result value of this expression
  113.     * @exception  IllegalExpressionException if encounter error while
  114.     *             while parsing input string as an expression
  115.     */
  116.    public double getValue() throws IllegalExpressionException 
  117.    {
  118.       String token;
  119.       char firstChar;
  120.       StringTokenizer parser = 
  121.             new StringTokenizer(inputExpression, "+-*/() ", true);
  122.       
  123.       do
  124.       {
  125.          //end of expression
  126.          if(!parser.hasMoreTokens())
  127.          {
  128.             lastToken = EOL;
  129.             processToken();
  130.             continue;
  131.          } // if
  132.          
  133.          token = parser.nextToken();
  134.          firstChar = token.charAt(0);
  135.          
  136.          // skip the ' '
  137.          if(Character.isWhitespace(firstChar))
  138.          {
  139.             continue;
  140.          } // if 
  141.          
  142.          if( (token.length() == 1) && isOperator(firstChar) )
  143.          {
  144.             switch (firstChar)
  145.             {
  146.                case '+': 
  147.                   lastToken = PLUS;
  148.                   break;
  149.                case '-':
  150.                   lastToken = MINUS;
  151.                   break;
  152.                case '*':
  153.                   lastToken = MULT;
  154.                   break;
  155.                case '/':
  156.                   lastToken = DIV;
  157.                   break;
  158.                case '(':
  159.                   lastToken = OPAREN;
  160.                   break;
  161.                case ')':
  162.                   lastToken = CPAREN;
  163.                   break;
  164.             } // switch
  165.          } // if is operator
  166.          else
  167.          {
  168.             try
  169.             {
  170.                currentValue = Double.valueOf(token).doubleValue();
  171.                lastToken = VALUE;
  172.             } //try
  173.             catch ( NumberFormatException e )
  174.             {
  175.                throw new IllegalExpressionException("Unknown symbol");
  176.             } //catch
  177.          } // else suppose a number 
  178.          processToken();
  179.       
  180.       } while( lastToken != EOL );   
  181.           
  182.       if( postFixStack.empty() )
  183.       {
  184.          throw new IllegalExpressionException("Missing operand");
  185.       } // if missing operand
  186.       
  187.       theResult = ((Double)postFixStack.pop()).doubleValue();
  188.       
  189.       if( !postFixStack.empty() )
  190.       {
  191.          throw new IllegalExpressionException("Missing operator");
  192.       } // if missing operator
  193.       
  194.       return theResult;
  195.       
  196.    } // getValue
  197.    
  198.    private void processToken() throws IllegalExpressionException
  199.    {
  200.       int topOperator;
  201.       
  202.       switch(lastToken)
  203.       {
  204.          case VALUE:
  205.             postFixStack.push(new Double(currentValue));
  206.             return;
  207.          case CPAREN:
  208.             while( (topOperator = 
  209.                   ((Integer)operatorStack.peek()).intValue())
  210.                   != OPAREN && topOperator != EOL )
  211.             {
  212.                applyOperation( topOperator );
  213.             } // while
  214.             if( topOperator == OPAREN )
  215.             {
  216.                operatorStack.pop();
  217.             } // if
  218.             else
  219.             {
  220.                throw new IllegalExpressionException("Missing " + 
  221.                      "open parenthesis");
  222.             } //else
  223.             break;
  224.          default:
  225.             while( INPUT_PRECEDENCE[lastToken] <=
  226.                   STACK_PRECEDENCE[ topOperator = 
  227.                   ((Integer)operatorStack.peek()).intValue() ] )
  228.             {
  229.                applyOperation( topOperator );
  230.             } //while
  231.             if( lastToken != EOL )
  232.             {
  233.                operatorStack.push(new Integer(lastToken));
  234.             } // if
  235.             break;
  236.          } //switch   
  237.    } //processToken
  238.    
  239.    private void applyOperation(int topOperator)
  240.                         throws IllegalExpressionException
  241.    {
  242.       double leftOperand,
  243.              rightOperand;
  244.       
  245.       if( topOperator == OPAREN )
  246.       {
  247.          throw new IllegalExpressionException("Unbalanced parenthesis");
  248.       } //if
  249.       
  250.       rightOperand = getPostStackTop();
  251.       leftOperand = getPostStackTop();
  252.       
  253.       if( topOperator == PLUS )
  254.       {
  255.          postFixStack.push(new Double(leftOperand + rightOperand));
  256.       } // if +
  257.       else if( topOperator == MINUS )
  258.       {
  259.          postFixStack.push(new Double(leftOperand - rightOperand));
  260.       } // else if -
  261.       else if( topOperator == MULT )
  262.       {
  263.          postFixStack.push(new Double(leftOperand * rightOperand));
  264.       } // else if *
  265.       else if( topOperator == DIV )
  266.       {
  267.          if( rightOperand != 0)
  268.          {
  269.             postFixStack.push(new Double(leftOperand / rightOperand));
  270.          } // if
  271.          else
  272.          {
  273.             throw new IllegalExpressionException("Division by zero");
  274.          } // else erro
  275.       } // if /
  276.       
  277.       operatorStack.pop();
  278.    } // applyOperation
  279.    
  280.    private double getPostStackTop() throws IllegalExpressionException   
  281.    {
  282.       if( postFixStack.empty() )
  283.       {
  284.          throw new IllegalExpressionException("Missing operand");
  285.       } // if
  286.       return ((Double)postFixStack.pop()).doubleValue();
  287.    } //getPostStackTop
  288.    
  289.    private boolean isOperator(char c)
  290.    {
  291.       return (c == '+' || c =='-' || c == '*' || c == '/'
  292.               || c == '(' || c == ')' );
  293.    } // isOperator
  294.    
  295. } // Expression