Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

package edu.csc413.calculator.evaluator; import edu.csc413.calculator.exceptions.InvalidTokenException; import edu.csc413.calculator.operators.*; import java.util.Stack; import java.util.StringTokenizer; public class Evaluator { private Stack operandStack; private Stack operatorStack; private StringTokenizer expressionTokenizer; private final

image text in transcribedimage text in transcribed

package edu.csc413.calculator.evaluator; import edu.csc413.calculator.exceptions.InvalidTokenException; import edu.csc413.calculator.operators.*; import java.util.Stack; import java.util.StringTokenizer; public class Evaluator { private Stack operandStack; private Stack operatorStack; private StringTokenizer expressionTokenizer; private final String delimiters = " +/*-^"; public Evaluator() { operandStack = new Stack(); operatorStack = new Stack(); } public int evaluateExpression(String expression ) throws InvalidTokenException { String expressionToken; // The 3rd argument is true to indicate that the delimiters should be used // as tokens, too. But, we'll need to remember to filter out spaces. this.expressionTokenizer = new StringTokenizer( expression, this.delimiters, true ); // initialize operator stack - necessary with operator priority schema // the priority of any operator in the operator stack other than // the usual mathematical operators - "+-*/" - should be less than the priority // of the usual operators while ( this.expressionTokenizer.hasMoreTokens() ) { // filter out spaces if ( !( expressionToken = this.expressionTokenizer.nextToken() ).equals( " " )) { // check if token is an operand if ( Operand.check( expressionToken )) { operandStack.push( new Operand( expressionToken )); } else { if ( ! Operator.check( expressionToken )) { throw new InvalidTokenException(expressionToken); } // TODO Operator is abstract - these two lines will need to be fixed: // The Operator class should contain an instance of a HashMap, // and values will be instances of the Operators. See Operator class // skeleton for an example. Operator newOperator = new Operator(); while (operatorStack.peek().priority() >= newOperator.priority() ) { // note that when we eval the expression 1 - 2 we will // push the 1 then the 2 and then do the subtraction operation // This means that the first number to be popped is the // second operand, not the first operand - see the following code Operator operatorFromStack = operatorStack.pop(); Operand operandTwo = operandStack.pop(); Operand operandOne = operandStack.pop(); Operand result = operatorFromStack.execute( operandOne, operandTwo ); operandStack.push( result ); } operatorStack.push( newOperator ); } } } // Control gets here when we've picked up all of the tokens; you must add // code to complete the evaluation - consider how the code given here // will evaluate the expression 1+2*3 // When we have no more tokens to scan, the operand stack will contain 1 2 // and the operator stack will have + * with 2 and * on the top; // In order to complete the evaluation we must empty the stacks, // that is, we should keep evaluating the operator stack until it is empty; // Suggestion: create a method that processes the operator stack until empty. return 0; } }

package edu.csc413.calculator.evaluator; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class EvaluatorUI extends JFrame implements ActionListener { private TextField expressionTextField = new TextField(); private Panel buttonPanel = new Panel(); // total of 20 buttons on the calculator, // numbered from left to right, top to bottom // bText[] array contains the text for corresponding buttons private static final String[] buttonText = { "7", "8", "9", "+", "4", "5", "6", "- ", "1", "2", "3", "*", "0", "^", "=", "/", "(", ")", "C", "CE" }; /** * C is for clear, clears entire expression * CE is for clear expression, clears last entry up until the last operator. */ private Button[] buttons = new Button[buttonText.length]; public static void main(String argv[]) { new EvaluatorUI(); } public EvaluatorUI() { setLayout(new BorderLayout()); this.expressionTextField.setPreferredSize(new Dimension(600, 50)); this.expressionTextField.setFont(new Font("Courier", Font.BOLD, 28)); add(expressionTextField, BorderLayout.NORTH); expressionTextField.setEditable(false); add(buttonPanel, BorderLayout.CENTER); buttonPanel.setLayout(new GridLayout(5, 4)); //create 20 buttons with corresponding text in bText[] array Button tempButtonReference; for (int i = 0; i

package edu.csc413.calculator.evaluator; /** * Operand class used to represent an operand * in a valid mathematical expression. */ public class Operand { /** * construct operand from string token. */ public Operand(String token) { } /** * construct operand from integer */ public Operand(int value) { } /** * return value of operand */ public int getValue() { return 0; } /** * Check to see if given token is a valid * operand. */ public static boolean check(String token) { return false; } }

package edu.csc413.calculator.operators; import edu.csc413.calculator.evaluator.Operand; public abstract class Operator { // The Operator class should contain an instance of a HashMap // This map will use keys as the tokens we're interested in, // and values will be instances of the Operators. // ALL subclasses of operator MUST be in their own file. // Example: // Where does this declaration go? What should its access level be? // Class or instance variable? Is this the right declaration? // HashMap operators = new HashMap(); // operators.put( "+", new AdditionOperator() ); // operators.put( "-", new SubtractionOperator() ); /** * retrieve the priority of an Operator * @return priority of an Operator as an int */ public abstract int priority(); /** * Abstract method to execute an operator given two operands. * @param operandOne first operand of operator * @param operandTwo second operand of operator * @return an operand of the result of the operation. */ public abstract Operand execute(Operand operandOne, Operand operandTwo); /** * used to retrieve an operator from our HashMap. * This will act as out publicly facing function, * granting access to the Operator HashMap. * * @param token key of the operator we want to retrieve * @return reference to a Operator instance. */ public static Operator getOperator(String token) { return null; } /** * determines if a given token is a valid operator. * please do your best to avoid static checks * for example token.equals("+") and so on. * Think about what happens if we add more operators. */ public static boolean check(String token) { return false; } }

Requirements You will be provided with an almost complete version of the Evaluator class (Evaluator.java). You should program the utility classes it uses - Operand and Operator - and then follow the suggestions in the code to complete the implementation of the Evaluator class. The Evaluator implements a single public method, eval, that takes single String parameter that represents an infix mathematical expression, parses and evaluates the expression, and returns the integer result. An example expression is 2 + 3 * 4, which would be evaluated to 14. The expressions are composed of integer operands and operators drawn from the set +, -*.,^, and ). These operators have the following priority: Operator Priority +,- 1 2 3 The algorithm that is partially implemented in eval processes the tokens in the expression string using two Stacks; one for operators and one for operands (algorithm reproduced here from http://csis.pace.edu/-murthy/Programming Problems/16 Evaluation of infix expression s): If an operand token is scanned, an Operand object is created from the token, and pushed to the operand Stack If an operator token is scanned, and the operator Stack is empty, then an Operator object is created from the token, and pushed to the operator Stack If an operator token is scanned, and the operator Stack is not empty, and the operator's precedence is greater than the precedence of the Operator at the top of the Stack, then and Operator object is created from the token, and pushed to the If the token is (, and Operator object is created from the token, and pushed to the operator Stack If the token is ), the process Operators until the corresponding (is encountered. Pop the Operator. If none of the above cases apply, process an Operator. operator Stack Processing an Operator means to: Pop the operand Stack twice (for each operand - note the order!!) Pop the operator Stack Execute the Operator with the two Operands Push the result onto the operand Stack When all tokens are read, process Operators until the operator Stack is empty. Requirement 1: Implement the following class hierarchy Operator must be an abstract superclass. boolean check( String token ) - returns true if the specified token is an operator abstract int priority () - returns the precedence of the operator abstract Operand execute( Operand operandone, Operand operandTwo ) - performs a mathematical calculation dependent on its type This class should contain a HashMap with all the Operators stored as values, keyed by their token. An interface/public method should be created in Operator to allow the Evaluator (or other software components in our system) to look up Operators by token. Individual Operator classes must be sub classed from Operator to implement each of of the operations allowed our expressions Operand boolean check( String token) - returns true if the specified token is an operand Operand ( String token ) - Constructor Operand( double value ) - Constructor int getValue() - returns the integer value of this operand Requirement 2 Implement the above algorithm within the Evaluator class (this implementation need not be submitted, but it is strongly recommended that you begin with this version). Requirement 3: Reuse your Evaluator implementation in the provided GUI Calculator (EvaluatorUl.java). Requirement 4: Please make sure to that class members (static or not) have the correct access modifiers. You will be graded on correctly using the private, public, protected access modifiers. Class should not be directly accessing data-fields of another class. Additional Notes. Please use the following names for the operator classes. This will make the given unit tests work better. If not, then you must modify the unit tests. operatorame Operator For example: AddOperator Divide Operator MultiplyOperator Power Operator SubtractOperator

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Students also viewed these Databases questions

Question

2. What efforts are countries making to reverse the brain drain?

Answered: 1 week ago