/* ParseInfix.java */ import java.lang.*; import java.io.*; import DataStructures.*; import Exceptions.*; /** * The ParseInfix class is a very simple demonstration of the use of stacks * to process an infix expression. * * The only allowable operations are +, -, *, and ^ (exponential). Each * operand must be a single (base 36) digit between zero and 'Z'. The * expression must appear as the first command-line argument, and must * alternate between digit and operator. Parentheses are ignored, as are * uninterpretable characters. For example, * * java ParseInfix '7+2*3^2^2+5' * * prints "174". The quotes are recommended to prevent the shell from * expanding asterisks (or interpreting any whitespace as the start of * a separate command line argument). * * +, -, and * are left-associative; ^ is right-associative. * * Error handling is nonexistent. This example is compact so that it can * be easily presented in a single lecture, but is no example of robust code. * * @author Jonathan Shewchuk */ public class ParseInfix { public static void operate(Stack numStack, Stack opStack) throws Underflow { // Retrieve the operator and operands from the stacks. char operator = ((Character) opStack.top()).charValue(); opStack.pop(); int operand2 = ((Integer) numStack.top()).intValue(); numStack.pop(); int operand1 = ((Integer) numStack.top()).intValue(); numStack.pop(); System.out.print(operator + " "); // Perform the operation and push the result on the number stack. if (operator == '+') { // Addition numStack.push(new Integer(operand1 + operand2)); } else if (operator == '-') { // Subtraction numStack.push(new Integer(operand1 - operand2)); } else if (operator == '*') { // Multiplication numStack.push(new Integer(operand1 * operand2)); } else if (operator == '^') { // Exponentiation int result = 1; for (int i = 0; i < operand2; i++) { result = result * operand1; } numStack.push(new Integer(result)); } } public static int precedence(char operator) { switch (operator) { case '^': return 3; case '*': case '/': return 2; case '+': case '-': return 1; default: return 0; } } public static void main(String[] args) throws Underflow { StackLi numStack = new StackLi(); // Create a number stack StackLi opStack = new StackLi(); // Create an operand stack // Process each character of the first command-line argument. for (int i = 0; i < args[0].length(); i++) { char c = args[0].charAt(i); if (Character.isDigit(c)) { // Print each digit; push each digit on number stack. System.out.print(c + " "); numStack.push(new Integer(Character.digit(c, 36))); } else if ((c == '+') || (c == '-') || (c == '*') || (c == '^')) { // Before pushing an operator onto the operand stack, check if // operators currently atop the stack have greater precedence. while (!opStack.isEmpty() && (c != '^') && (precedence(((Character) opStack.top()).charValue()) >= precedence(c))) { // Perform the operation atop the operand stack. operate(numStack, opStack); } opStack.push(new Character(c)); // Push new operation on operand stack } } while (!opStack.isEmpty()) { operate(numStack, opStack); } System.out.println(" result:" + ((Integer) numStack.top()).intValue()); } }