// // COMP102 // Example 11: Evalution of Arithmetic Expressions // in Reverse Polish Notations Using // the Stack class. // // Paul E. Dunne 15/11/99 // import java.io.*; import Stack; public class RPN { public static InputStreamReader input = new InputStreamReader(System.in); public static BufferedReader keyboardInput = new BufferedReader(input); //******************************************************* // Strip out spaces and newlines between input items * // Return the first `non white space' char found. * //******************************************************* public static char IgnoreWhiteSpace( BufferedReader instream) throws IOException { char c=' '; while (Character.isWhitespace(c)) { c = (char)instream.read(); }; return c; } //*************************************************************** // Check if the character just read is an arithmetic operation * //*************************************************************** public static boolean OperatorSymbol( char c ) { return ( (c=='+')||(c=='-')||(c=='*')||(c=='/') ); } //*************************************************************** // Main method * //*************************************************************** public static void main( String[] args) throws IOException { Stack RPN_Expr; // The expression being evaluated. Integer Operand = new Integer(0); // Object sub-class to use when // placing integer values on Stack. // N.B. Wrapper class. int ValueLeft,ValueRight; // Used during evaluation of expression in // the form Left Right , so that // ValueLeft == V(Left); // ValueRight == V(Right); int FinalValue=0; char next_ch; // Characters read from input stream. String temp; // Will hold integer values under construction String Clearout; // Remove anything left on input line, // before prompting for continuation. boolean error_flag = false; // Set this to true if invalid expression detected. char YesNo='N'; // To indicate whether to continue. //*********************************************************************** System.out.println("Enter arithmetic expression in Reverse Polish Form"); System.out.println("use '@' symbol to end expression"); next_ch = IgnoreWhiteSpace(keyboardInput); // Find first `real' input char. RPN_Expr = new Stack(); // //*************************************************************** // Continue evalution until end of expression marker reached * // or an error has been found in the expression input form. * //*************************************************************** // while (!( (next_ch=='@')||(error_flag) )) { temp = new String(); // //******************************************** // If next item is an integer value; * // then it will start with a digit. * //******************************************** // if (Character.isDigit(next_ch)) { //************************************************* // and end at the character immediately preceding * // the next non-digit character read. * //************************************************* while (Character.isDigit(next_ch)) { temp = temp+next_ch; next_ch = (char)keyboardInput.read(); }; Operand = new Integer(temp); RPN_Expr.Push(Operand); // Put the value just read onto the Stack. //******************************************************************** // The non-digit character might be a space, or linebreak * // If it is, we want the next character inspected to be a digit * // or operation therefore we have to get rid of intermediate 'noise' * // characters (spaces, linebreaks, etc) * //******************************************************************** if (Character.isWhitespace(next_ch)) next_ch = IgnoreWhiteSpace(keyboardInput); } //******************************************************************** // next_ch cannot be a whitespace character, so if it's not a digit * // it could be an operator symbol. * //******************************************************************** // If the character is an operator then the top 2 items * // currently on the Stack, (V1, V2 say) can be replaced by * // the integer value V2 V1. * //******************************************************************** else if (OperatorSymbol(next_ch)) { // If the input expression is in a correct form then there // must be (at least) 2 values on the stack at this point. if (RPN_Expr.IsEmptyStack()) error_flag = true; else { // Find out the value of the `right-hand' operand. ValueRight = (Integer.valueOf(RPN_Expr.Peek().toString())).intValue(); RPN_Expr.Pop(); // and remove it from the Stack. // Find out the value of the `left-hand' operand. if (RPN_Expr.IsEmptyStack()) error_flag=true; else { ValueLeft = (Integer.valueOf(RPN_Expr.Peek().toString())).intValue(); RPN_Expr.Pop(); // and remove this from the Stack, switch (next_ch) // Now compute what should replace these values. { case '+': Operand = new Integer(ValueLeft+ValueRight); break; case '-': Operand = new Integer(ValueLeft-ValueRight); break; case '*': Operand = new Integer(ValueLeft*ValueRight); break; case '/': Operand = new Integer(ValueLeft/ValueRight); }; RPN_Expr.Push(Operand); // and save it onto the stack. next_ch = IgnoreWhiteSpace(keyboardInput); // Continue with the next // 'real' character. }; }; } //************************************************************** // The character read cannot be the terminating '@' symbol so * // If it was not a digit, and not an operator symbol, then the * // the the input expression is not in correct RPN. * // In this case, we can set the error flag to true and exit. * //************************************************************** else error_flag = true; }; //******************************************************* // On completion, there should be exactly one value on * // the Stack. * //******************************************************* if (RPN_Expr.IsEmptyStack()) error_flag=true; else { FinalValue = (Integer.valueOf(RPN_Expr.Peek().toString())).intValue(); RPN_Expr.Pop(); }; Clearout = keyboardInput.readLine(); //*********************************** // Now the Stack should be empty. * //*********************************** if (!(RPN_Expr.IsEmptyStack())) error_flag=true; // if (error_flag) System.out.println("Expression is not in correct form of Reverse Polish Notation"); else System.out.println("The value of this expression is "+ FinalValue); System.out.println(); System.out.print("Continue with another expression? (Y/y):"); YesNo = (keyboardInput.readLine()).charAt(0); if ((YesNo=='Y')||(YesNo=='y')) main(args); // Clumsy, but effective. } }