postfix tester

import java.util.Stack;
import java.util.Scanner;

/**
 * Main driver class for the Postfix Expression Evaluator.
 */
public class PostfixTester {
    public static void main(String[] args) {
        // Use try-with-resources to ensure the Scanner is closed automatically
        try (Scanner in = new Scanner(System.in)) {
            String again;
            System.out.println("========================================");
            System.out.println("   Postfix Expression Evaluator Pro");
            System.out.println("========================================");

            do {
                PostfixEvaluator evaluator = new PostfixEvaluator();
                System.out.println("\nEnter a valid postfix expression (Supports: + - * / ^ %):");
                System.out.println("Example: 5 4 + 3 2 ^ * (Calculates (5+4)*(3^2))");
                System.out.print("> ");

                String expression = in.nextLine();

                try {
                    int result = evaluator.evaluate(expression);
                    System.out.println("----------------------------------------");
                    System.out.println("Calculation Successful!");
                    System.out.println("Result: " + result);
                    System.out.println("----------------------------------------");
                } catch (Exception e) {
                    System.err.println("Error: Invalid expression or calculation fault (" + e.getMessage() + ")");
                }

                System.out.print("Evaluate another expression [Y/N]? ");
                again = in.nextLine();
            } while (again.equalsIgnoreCase("y"));

            System.out.println("\nProgram terminated. Thank you!");
        }
    }
}

/**
 * Handles the logic of evaluating postfix mathematical expressions using a
 * Stack.
 */
class PostfixEvaluator {
    private final static char ADD = '+', SUBTRACT = '-', MULTIPLY = '*', DIVIDE = '/', EXP = '^', MOD = '%';

    // Using Generics Stack<Integer> to ensure type safety
    private Stack<Integer> stack = new Stack<>();

    /**
     * Parses the string and performs stack-based evaluation.
     */
    public int evaluate(String expr) {
        // Nested try-with-resources for the string parser
        try (Scanner parser = new Scanner(expr)) {
            while (parser.hasNext()) {
                String token = parser.next();
                if (isOperator(token)) {
                    // Pop order: op2 is the second operand, op1 is the first
                    int op2 = stack.pop();
                    int op1 = stack.pop();
                    stack.push(evaluateSingleOperator(token.charAt(0), op1, op2));
                } else {
                    // Parse numeric tokens and push onto the stack
                    stack.push(Integer.parseInt(token));
                }
            }
        }
        // The final remaining value on the stack is the result
        return stack.pop();
    }

    private boolean isOperator(String token) {
        return (token.equals("+") || token.equals("-") || token.equals("*") ||
                token.equals("/") || token.equals("^") || token.equals("%"));
    }

    /**
     * Performs the specific arithmetic operation based on the operator.
     * Uses the modern Switch Expression with '->', blocks '{}', and 'yield'.
     */
    private int evaluateSingleOperator(char operation, int op1, int op2) {
        return switch (operation) {
            case ADD -> {
                yield op1 + op2;
            }
            case SUBTRACT -> {
                yield op1 - op2;
            }
            case MULTIPLY -> {
                yield op1 * op2;
            }
            case DIVIDE -> {
                if (op2 == 0)
                    throw new ArithmeticException("Division by zero");
                yield op1 / op2;
            }
            case EXP -> {
                // Calculate power and cast back to int
                yield (int) Math.pow(op1, op2);
            }
            case MOD -> {
                if (op2 == 0)
                    throw new ArithmeticException("Modulo by zero");
                yield op1 % op2;
            }
            default -> {
                throw new IllegalArgumentException("Unexpected operator: " + operation);
            }
        };
    }
}

 

Scroll to Top