6 Replies Latest reply on Mar 12, 2003 9:57 PM by 807541

    Help in evaluating expression

    807541
      Hi there -
      I was hoping that someone would be able to help me out a bit with my program. I am trying to take a fully parenthesed, correctly written boolean expression containing positive integers, evaluate it and return the result. I am using StringTokenizer to parse the expression (deliminated with spaces.)

      I seem have everything working logic-wise (dealing with the parentheses etc.) though I am really having trouble with the double operators (i.e.. >=, <=, ++, !=, &&, ||). For example, ( ( 5 * 4 ) > ( 6 * 4 ) ) evaluates false and ( ( 5 * 4 ) < ( 6 * 4 ) ) evaluates true. But, my program seems to be ignoring the second character on <= and >=. For example ( ( 5 * 4 ) >= ( 6 * 4 ) ) evaluates false, ( ( 5 * 4 ) <= ( 6 * 4 ) ) evaluates true, BUT ( ( 6 * 4 ) >= ( 6 * 4 ) ) evaluates false.

      On another note, for || and &&, I am getting an error. For example, when I try ( ( 6 < 4 ) && ( 2 > 4 ) ), I get the following error: java.lang.NumberFormatException: For input string: "true"
      ...
      at Evaluator.evaluate(Evaluator.java:123)

      I checked the discussion board but there weren't any hints for how to deal with these double operators.

      Thanks for your help! Here's my code so that you can see what I talking about...

      *********************************
      public class Evaluator {


      public static String evaluate(String expression){
      // Create ArrayStack objects for operators and operands
      ArrayStack operators = new ArrayStack(); // store operators
      ArrayStack operands = new ArrayStack(); // stores the operators

      int value; //numerical rep of operand
      char ch1, ch2; // current character being processed
      String op1, op2; //string rep of operands
      boolean opB1, opB2; //boolean rep of operands
      int operand1 = 0; //first integer operand
      int operand2 = 0; // second integer operand

      int result = 0; // result of arithmetic operation
      boolean test = false; // result of boolean operation

      String operation; //operator
      String testOperation; // check for left parenthesis
      Integer wrapValue; //used to push initial operand onto operand stack
      Integer wrapInteger; //used to push new operand (result) onto operand stack
      Boolean wrapBoolean; //used to push boolean operand onto operand stack

      String token; //String from StringTokenizer
      String answer; //String result returned to application

      StringTokenizer tokenizer = new StringTokenizer(expression);

      // process expression entered
      while (tokenizer.hasMoreTokens())
      {
      token = tokenizer.nextToken();
      if (!isRightParenthesis(token)) {
      if (isNotOperator(token)) // value is an operand
      {
      //process operands (integers)
      try
      {
      value = Integer.parseInt(token);
      wrapValue = new Integer(value);
      }
      catch (NumberFormatException badData)
      {
      throw new ArithmeticException("Illegal symbol: " + badData.getMessage());
      }

      if(operators.isFull())
      throw new ArithmeticException("Too many operators - stack overflow");

      operands.push(wrapValue); // add operand to stack
      }
      else
      // push operator if not a left parenthesis
      operators.push(new Character(token.charAt(0)));

      }
      else //process operators when token is right parenthesis
      { //pop and convert from stacks
      if (operators.isEmpty())
      throw new ArithmeticException(
      "Not enough operators - stack underflow");


      operation = (operators.top()).toString(); // pop operator and convert
      operators.pop();

      if (operands.isEmpty())
      throw new ArithmeticException(
      "Not enough operands - stack underflow");
      op2 = (operands.top()).toString(); // pop operand and convert
      operands.pop();

      if (operands.isEmpty())
      throw new ArithmeticException(
      "Not enough operands - stack underflow");
      op1 = (operands.top()).toString(); // pop operand and convert
      operands.pop();

      if (!isBoolean(operation)){
      //if operator is not boolean then evaluate integer arithmetic
      if (operation.equals("(")){ //do nothing
      operators.pop();
      }
      else
      operand1 = Integer.parseInt(op1);
      operand2 = Integer.parseInt(op2);
      result = Integer.parseInt(processInt(operation, operand1, operand2));
      wrapInteger = new Integer(result);
      operands.push(wrapInteger);
      testOperation = (operators.top()).toString();
      if (testOperation.equals("(")){
      operators.pop(); // remove "("
      }
      }
      else if (isBoolean(operation))
      { // operator is boolean, evaluate boolean
      if (operation.equals("||")){
      opB1 = Boolean.getBoolean(op1);
      opB2 = Boolean.getBoolean(op2);
      test = (opB1 || opB2);
      }
      else
      if (operation.equals("&&"))
      {
      opB1 = Boolean.getBoolean(op1);
      opB2 = Boolean.getBoolean(op2);
      test = (opB1 && opB2);
      }
      else {
      operand1 = Integer.parseInt(op1);
      operand2 = Integer.parseInt(op2);
      test = processBoolean(operation, operand1, operand2);
      }

      wrapBoolean = new Boolean(test);
      operands.push(wrapBoolean);
      testOperation = (operators.top()).toString();
      if (testOperation.equals("(")){
      operators.pop(); // remove "("
      }

      } // end boolean
      } // end process operator
      } // end of processing expression


      if (operands.isEmpty())
      throw new ArithmeticException("Not enough operands - stack underflow");
      answer = operands.top().toString(); // pop answer and convert
      operands.pop();

      //stack should now be empty
      if(!operands.isEmpty())
      throw new ArithmeticException("Too many operands - operands left over!");
      return answer;
      } //end evaluate

      private static boolean isNotOperator(String testThis)
      {
      if (testThis.equals("+") || testThis.equals("-") ||
      testThis.equals("*") || testThis.equals( "/") ||
      testThis.equals(">") || testThis.equals( "<") ||
      testThis.equals(">=") || testThis.equals( "<=") ||
      testThis.equals("==") || testThis.equals( "!=") ||
      testThis.equals("(") || testThis.equals( ")") ||
      testThis.equals("||") || testThis.equals("&&"))
      return false;
      else
      return true;
      }

      private static boolean isBoolean(String testThis) //test for boolean expressions
      {
      int index = 0;
      boolean testResult = false;
      while (index < testThis.length()){
      char current_ch = testThis.charAt(index); //get a charachter
      switch (current_ch){
      case '>':
      case '<':
      case '=':
      case '!':
      case '|':
      case '&':
      testResult = true;
      break;
      default:
      testResult = false;
      break;
      } //end of switch
      index++;
      } //end of while
      return testResult;
      }

      private static boolean isRightParenthesis(String testThis) //test for parenthesis
      {
      if (testThis.equals(")"))
      return true;
      else
      return false;
      }

      //process arithmetic operation
      private static String processInt(String operation, int operand1, int operand2)
      {
      int intResult = 0;
      if (operation.equals("/"))
      intResult = operand1 / operand2;
      else
      if (operation.equals("*"))
      intResult = operand1 * operand2;
      else
      if (operation.equals("+"))
      intResult = operand1 + operand2;
      else
      if (operation.equals("-"))
      intResult = operand1 - operand2;

      return Integer.toString(intResult);
      }

      //process boolean operation
      private static boolean processBoolean(String operation, int operand1, int operand2)
      {
      boolean boolTest = false;
      if (operation.equals("<"))
      boolTest = (operand1 < operand2);
      else
      if (operation.equals(">"))
      boolTest = (operand1 > operand2);
      else
      if (operation.equals("<="))
      boolTest = (operand1 <= operand2);
      else
      if (operation.equals(">="))
      boolTest = (operand1 >= operand2);
      else
      if (operation.equals("=="))
      boolTest = (operand1 == operand2);
      else
      if (operation.equals("!="))
      boolTest = (operand1 != operand2);

      return boolTest;
      }

      }
        • 1. Re: Help in evaluating expression
          807541
          boolean bWhat = (( 6 * 4 ) >= ( 6 * 4 ));
          System.out.println(bWhat);//prints TRUE for me
          • 2. Re: Help in evaluating expression
            807541
            Yes, of course it will print out true if evaluated by Java, but my code for evaluating and returning "true" doesn't. I believe that it is because I am not passing the argument correctly. I am passing a String ">=" that if matched, should evaluate (op1 >= op2) and return boolean result.

            When I try this in my program (I have a separate application that is used for receiving expression and displaying result...) the result doesn't change from the default boolean value of false.

            Should I be parsing the String to char before evaluating?

            hmm...
            • 3. Re: Help in evaluating expression
              807541
              this is my code for processing the boolean operation
              private static boolean processBoolean(String operation, int operand1, int operand2)
              {
              boolean boolTest = false;
              if (operation.equals("<"))
              boolTest = (operand1 < operand2);
              else
              if (operation.equals(">"))
              boolTest = (operand1 > operand2);
              else
              if (operation.equals("<="))
              boolTest = (operand1 <= operand2);
              else
              if (operation.equals(">="))
              boolTest = (operand1 >= operand2);
              else
              if (operation.equals("=="))
              boolTest = (operand1 == operand2);
              else
              if (operation.equals("!="))
              boolTest = (operand1 != operand2);

              return boolTest;
              }
              • 4. Re: Help in evaluating expression
                807541
                Why reinvent the wheel? Look around for JEP (Java Expression Parser)
                • 5. Re: Help in evaluating expression
                  807541
                  Why reinvent the wheel?
                  Because you want to pass your college course?
                  • 6. Re: Help in evaluating expression
                    807541
                    Yes, I'm trying to pass a class - BTW way, I found my error - I am only pushing the first character to the operator stack so when I pop it, I'm only popping half of the operator.

                    Thanks for the comments though! Next time I'll know about JEP!