Jump to content

prefix expression evaluator

- - - - -

  • Please log in to reply
3 replies to this topic

#1
777th

777th

    Newbie

  • Members
  • Pip
  • 2 posts
well, to start, i try to run the code that i do have, i am met with scorn:

Attached File  image.png   26.55K   21 downloads

to which i would love some wisdom as to what it is i need to fix in my code...

import java.util.*;


public class SimpleLispExpressionEvaluator

{


    // Current input Lisp expression

    private String inputExpr;

    


    // Main stack & temp stack, see algorithm in evaluate()

    private Stack<Object> expressionStack;

    private Stack<Double> tempStack;

    


    // default constructor

    // set inputExpr to "" 

    // create stack objects

    public SimpleLispExpressionEvaluator()

    {

	inputExpr = "";

	expressionStack = new Stack<Object>();

	tempStack = new Stack<Double>();

    }


    


    // default constructor

    // set inputExpr to inputExpression 

    // create stack objects

    public SimpleLispExpressionEvaluator(String inputExpression) 

    {

	    inputExpr = inputExpression;

	    expressionStack = new Stack<Object>();

	    tempStack = new Stack<Double>();

	    }



    // set inputExpr to inputExpression 

    // clear stack objects

    public void reset(String inputExpression) 

    {

	inputExpr = inputExpression;

	Stack<Object> expressionStack = new Stack<Object>();

	Stack<Double> tempstack =  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 expressionStack and push them onto 

    // 			tempStack until you find an operator

    //  	Apply the operator to the operands on tempStack

    //          Push the result into expressionStack

    //

   

   private double add() {

	  double op1 = tempStack.pop();

	  double op2 = tempStack.pop();

	  double temp = op1 + op2;

		return temp;

	}


	private double multiply() {

		double op1 = tempStack.pop();

		double op2 = tempStack.pop();

		double temp = op1 * op2;

		return temp;

	}


	private double subtract() {

		if (tempStack.size() == 1) {

                        double temp = -tempStack.pop();

                   return temp;

	       	} else {

		

		double op1 = tempStack.pop();

		double op2 = tempStack.pop();

		double temp = op1 - op2;

		return temp;

	}

	}


	private double divide() {

		if (tempStack.size() == 1) {

                         double temp = 1 / tempStack.pop();

			return temp;

                        } else if (tempStack.pop() == 0 || tempStack.pop() == null) {

			throw new IndexOutOfBoundsException(); } else {

				double op1 = tempStack.pop();

			        double op2 = tempStack.pop();

				double temp = op1 - op2;

				return temp;

			}

	}


   

   

   

   

   

   

   

    private void evaluateCurrentOperation()

    {

	

       

        	 	

	



	while( expressionStack.peek().getClass().getName().equals("java.lang.Double") ) {

    		tempStack.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 funtion evaluates Lisp expression in inputExpr

     * It return result of the expression 

     *

     * The algorithm:  

     *

     * Step 1   Scan the tokens in the expression string.

     * Step 2		If you see an operand, push operand object onto the expressionStack

     * Step 3  	    	If you see "(", next token should be an operator

     * Step 4  		If you see an operator, push operator object onto the expressionStack

     * Step 5		If you see ")"  // steps in evaluateCurrentOperation() :

     * Step 6			Pop operands and push them onto tempStack 

     * 					until you find an operator

     * Step 7			Apply the operator to the operands on tempStack

     * Step 8			Push the result into expressionStack

     * Step 9    If you run out of tokens, the value on the top of expressionStack is

     *           is the result of the expression.

     */

    public double evaluate()

    {

	// only outline is given...

	// you need to add statements

	// 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 expressionStack

            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)

                {

     		    // Step 3: If you see "(", next token should be an operator

			case '(':

				nextToken = inputExprScanner.next();

				nextItem = nextToken.charAt(0);

     		    // Step 4: If you see an operator, push operator object onto the expressionStack

			if (nextItem == '+') {

                            expressionStack.push(nextItem);

                        } else if (nextItem == '-') {

                            expressionStack.push(nextItem);

                        } else if (nextItem == '*') {

                            expressionStack.push(nextItem);

                        } else {

                            expressionStack.push(nextItem);

                        }

                        

			


		    break;

     		    // Step 5: If you see ")"  // steps 6,7,8 in evaluateCurrentOperation() 

			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 evaluateExprt(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("-----------------------------");

    }


    // simple tests 

    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 ))))";

	evaluateExprt(test1, expr);

	evaluateExprt(test2, expr);

	evaluateExprt(test3, expr);

	evaluateExprt(test4, expr);

	evaluateExprt(test5, expr);

	evaluateExprt(test6, expr);

    }

}

thanks in advance, guys

#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others
I think this is your issue:
String dataString = inputExprScanner.findInLine("\\d+");
expressionStack.push(new Double(dataString));
This will find a digit somewhere in the line, and then attempt to convert the entire line to a decimal.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
777th

777th

    Newbie

  • Members
  • Pip
  • 2 posts
hi darkwing--

i realized that my step nine was trying to convert the whole input string into a double instead of retrieving the top of the expression stack--


 // 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);

was changed to
double result = (Double)expressionStack.pop();

also--i just realized that my evaluations by cases is limited to two numbers. can i get a hint as to how to extend it to the amount of numbers within the '(' and ')'

which allows the code to work, but i am getting these exceptions, now [ATTACH=CONFIG]4287[/ATTACH]

#4
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others
I've got a hunch you're approaching things wrong, but it's probably because of how you're thinking about this.

What I would do is create an expression stack each time you encounter a "(". I would note the operator and start pushing numbers on the stack until I found the matching ")". At that point, I would process all the numbers on the stack with the operator you noted and return the result to the caller. If you encounter a "(", I would call the processor recursively. You could probably do this purely recursively, without using stacks at all, just consuming the string and using recursion.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users