2

我正在尝试在代码下方运行,但出现类型转换错误,当它从 main 获取输入时,它不会评估并给我给定错误。

谁能给我一些我做错的信息..

Expression (+ (- 6) (* 2 3 4) (/ (+ 3) (- 2 3 1)))   
Expr in thread "main" java.lang.NumberFormatException: For input string: "(+ (- 6) 
(* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)))"
at sun.misc.FloatingDecimal.readJavaFormatException: For input string "(+ (- 6) (* 2 3    
4) (/ (+ 3) (* 1) (- 2 3 1)))"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)

我的代码:

public class SimpleLispExpressionEvaluator
{
// Current input Lisp expression
private String inputExpr;

// Main expression stack & current operation stack, see algorithm in evaluate()
// Use StackInterface
private StackInterface<Object> exprStack;
private StackInterface<Double> currentOpStack;


// default constructor
// set inputExpr to "" 
// create stack objects
public SimpleLispExpressionEvaluator()
{
    // add statements
    inputExpr = "";
    expressionStack = new Stack<Object>();
    currentOpStack = new Stack<Double>();

}

// default constructor
// set inputExpr to inputExpression 
// create stack objects
public SimpleLispExpressionEvaluator(String inputExpression) 
{
// add statements

     inputExpr = inputExpression;
     expressionStack = new Stack<Object>();
     currentOpStack = new Stack<Double>();
}

// set inputExpr to inputExpression 
// clear stack objects
public void reset(String inputExpression) 
{
// add statements
    inputExpr = inputExpression;
    Stack<Object> expressionStack = new Stack<Object>();
    Stack<Double> currentOpStack =  new Stack<Double>();

}


private boolean checkifNumber() {
    return false;
}


// This function evaluate current operator with its operands
// See complete algorithm in evaluate()
//
// Main Steps:
//      Pop operands from exprStack and push them onto 
//          currentOpStack until you find an operator
//      Apply the operator to the operands on currentOpStack
//          Push the result into exprStack
//


private double add() {
    double op1 = currentOpStack.pop();
    double op2 = currentOpStack.pop();
    double temp = op1 + op2;
      return temp;
  }`

  private double multiply() {
      double op1 = currentOpStack.pop();
      double op2 = currentOpStack.pop();
      double temp = op1 * op2;
      return temp;
  }

  private double subtract() {
      if (currentOpStack.size() == 1) {
                      double temp = -currentOpStack.pop();
                 return temp;
          } else {

      double op1 = currentOpStack.pop();
      double op2 = currentOpStack.pop();
      double temp = op1 - op2;
      return temp;
  }
  }

  private double divide() {
      if (currentOpStack.size() == 1) {
                       double temp = 1 / currentOpStack.pop();
          return temp;
         } else if (currentOpStack.pop() == 0 || currentOpStack.pop() == null)
 {
          throw new IndexOutOfBoundsException(); } else {
              double op1 = currentOpStack.pop();
                  double op2 = currentOpStack.pop();
              double temp = op1 - op2;
              return temp;
          }
  }

private void evaluateCurrentOperation()
{
// add statements




    while( expressionStack.peek().getClass().getName().equals("java.lang.Double") ) {
        currentOpStack.push( (Double)expressionStack.pop() );
        }
        Character operator = (Character)expressionStack.pop();
        Double result = null;
        switch( operator ) {
            case '+':
                result = add();
                break;
            case '*':
                result = multiply();
                break;
            case '-':
                result = subtract();
                break;
            case '/':
                result = divide();
                break;
        }
        expressionStack.push( result );
                }



/**
 * This function evaluates current Lisp expression in inputExpr
 * It return result of the expression 
 *
 * The algorithm:  
 *
 * Step 1   Scan the tokens in the string.
 * Step 2       If you see an operand, push operand object onto the exprStack
 * Step 3           If you see "(", next token should be an operator
 * Step 4       If you see an operator, push operator object onto the exprStack
 * Step 5       If you see ")"  // steps in evaluateCurrentOperation() :
 * Step 6           Pop operands and push them onto currentOpStack 
 *                  until you find an operator
 * Step 7           Apply the operator to the operands on currentOpStack
 * Step 8           Push the result into exprStack
 * Step 9    If you run out of tokens, the value on the top of exprStack is
 *           is the result of the expression.
 */
  public double evaluate()
  {
    // only outline is given...
    // you need to add statements/local variables
    // you may delete or modify any statements in this method


    // use scanner to tokenize inputExpr
    Scanner inputExprScanner = new Scanner(inputExpr);

    // Use zero or more white space as delimiter,
    // which breaks the string into single character tokens
    inputExprScanner = inputExprScanner.useDelimiter("\\s*");

    // Step 1: Scan the tokens in the string.
    while (inputExprScanner.hasNext())
    {

        // Step 2: If you see an operand, push operand object onto the exprStack
        if (inputExprScanner.hasNextInt())
        {
            // This force scanner to grab all of the digits
            // Otherwise, it will just get one char
            String dataString = inputExprScanner.findInLine("\\d+");

            expressionStack.push(new Double(dataString));


    // more ...
        }
        else
        {
    // Get next token, only one char in string token
            String aToken = inputExprScanner.next();
            char item = aToken.charAt(0);
            String nextToken;
            char nextItem;   

            switch (item)
            {

            case '(':
                nextToken = inputExprScanner.next();
                nextItem = nextToken.charAt(0);

            if (nextItem == '+') {
                            expressionStack.push(nextItem);
                        } else if (nextItem == '-') {
                            expressionStack.push(nextItem);
                        } else if (nextItem == '*') {
                            expressionStack.push(nextItem);
                        } else {
                            expressionStack.push(nextItem);
                        }

            break;
            case ')':

                try {
                evaluateCurrentOperation();
            } catch (EmptyStackException e) {
                break;
            }

            break;
                    default:  // error
           throw new RuntimeException(item + " is not a legal expression operator");
                } // end switch
            } // end else
        } // end while

        // Step 9: If you run out of tokens, the value on the top of expressionStack is
        //         is the result of the expression.
        //
        //         return result
    double result = new Double(inputExpr);
    return  result;   
   }



  // This static method is used by main() only
   private static void evaluateExprTest(String s, SimpleLispExpressionEvaluator expr)
   {
    Double result;
    System.out.println("Expression " + s);
expr.reset(s);
    result = expr.evaluate();
    System.out.printf("Result %.2f\n", result);
    System.out.println("-----------------------------");
   }

  public static void main (String args[])
  {
    SimpleLispExpressionEvaluator expr= new SimpleLispExpressionEvaluator();
    String test1 = "(+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)))";
    String test2 = "(+ (- 632) (* 21 3 4) (/ (+ 32) (* 1) (- 21 3 1)))";
    String test3 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 1) (- 2 1 )))";
    String test4 = "(+ (/2))";
    String test5 = "(+ (/2 3 0))";
    String test6 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 3) (- 2 1 ))))";
evaluateExprTest(test1, expr);
evaluateExprTest(test2, expr);
evaluateExprTest(test3, expr);
evaluateExprTest(test4, expr);
evaluateExprTest(test5, expr);
evaluateExprTest(test6, expr);
   } 
   }
4

1 回答 1

1

AScanner可能不是阅读 S 表达式的正确工具。S-expression 阅读器通常使用递归下降解析器来完成这项工作,使用 readtable 来处理各种数据类型。例如,此页面描述了 Racket 是如何做到的。

于 2012-11-07T07:18:37.840 回答