Programming Assignment 2

Expression Evaluation

In this assignment you will implement a program to evaluate an arithmetic expression

Worth 80 points

Due July 14 11:00pm (Eastern Time) (WARNING!! NO GRACE PERIOD)




Expressions

Here are some sample expressions of the kind your program will evaluate:
   3
   Xyz
   3-4*5
   a-(b+A[B[2]])*d+3
   A[2*(a+b)]
   (varx + vary*varz[(vara+varb[(a+b)*33])])/55
The expressions will be restricted to the following components: Note the following:


Implementation and Grading

Download the attached expression_project.zip file to your computer. DO NOT unzip it. Instead, follow the instructions on the Eclipse page under the section "Importing a Zipped Project into Eclipse" to get the entire project into your Eclipse workspace.

You will see a project called Expression Evaluation with the following classes in package app:

You are also given the following class in package structures:

Do not add any other classes. In particular, if you wish to use stacks in your evaluation implementation do NOT use your own stack class, ONLY use the one you are given. The reason is, we will be using this same Stack class when we test your implementation.

 

Notes on tokenizing the expression

You will need to separate out ("tokenize") the components of the expression in makeVariableLists and evaluate. Tokens include operands (variables and constants), operators ('+','-','*','/'), parentheses and square brackets.

It may be helpful (but you are not required) to use java.util.StringTokenizer to tokenize the expression. The delims field in the Expression class may be used in the tokenizing process.

The documentation of the StringTokenizer class says this:

For the purpose of this assignment, you may use StringTokenizer without issue. Alternatively, you may use the split method of the String class, or the Pattern and Matcher classes in the package java.util.regex.

Or, you may simply parse the expression by scanning it a character at a time.

IMPORTANT!!! - Rules of implementation:

 

Guidelines and recommendations for implementing evaluate

 

Correctness of expression and input files

So you don't need to do any checking for correctness of inputs in any of the methods.


Running the evaluator

You can test your implementation by running the Evaluator driver on various expressions and input variable values file.

When creating your own variable values files for testing, make sure they are directly under the project folder, alongside etest1.txt and etest2.txt.

Since you are not going to turn in the Evaluator.java file, you may introduce debugging statements and other methods (such as printing out the variables or arrays array lists) as needed.

No variables

   Enter the expression, or hit return to quit => 3
   Enter variable values file name, or hit return if no variables => 
   Value of expression = 3.0

   Enter the expression, or hit return to quit => 3-4*5
   Enter variable values file name, or hit return if no variables => 
   Value of expression = -17.0

   Enter the expression, or hit return to quit => 
Neither of the expressions above have variables, so just hit return when asked for the variable values file name.

Variables, values loaded from file

  Enter the expression, or hit return to quit => a
  Enter variable values file name, or hit return if no variables => etest1.txt
  Value of expression = 3.0

  Enter the expression, or hit return to quit => 
Since the expression has a variable, a, the evaluator needs to be supplied with a file that has a value for it. Here's what etest1.txt looks like:
  a 3
  b 2
  A 5 (2,3) (4,5)
  B 3 (2,1)
  d 56
Each line of the file begins with a variable name. For simple variables, the name is followed by the variable's integer value. For arrays, the name is followed by the array's length, which is followed by a series of (index,integer value) pairs.

Note: The index and integer value pairs must be written with no spaces around the index or integer value.
So, for instance, (2, 3) or ( 2,3) or (2 ,3) are all incorrect.
Make sure you adhere to this requirement when you create your own input files for testing.

If the value at a particular array index is not explicitly listed, it is set to 0 by default.

So, in the example above, A = [0,0,3,0,5] and B = [0,0,1]

Note that the variable values file can have values for any number of variables, so that it can be used as input for several expressions that contain one or more of the variables in the file.

Here are a couple more evaluations of expressions for which the variable values are loaded from etest1.txt:

  Enter the expression, or hit return to quit => (a + A[a*2-b])
  Enter variable values file name, or hit return if no variables => etest1.txt
  Value of expression = 8.0

  Enter the expression, or hit return to quit => a - (b+A[B[2]])*d + 3
  Enter variable values file name, or hit return if no variables => etest1.txt
  Value of expression = -106.0

  Enter the expression, or hit return to quit =>
For a change of pace, here's etest2.txt, which has the following variables and values:
  varx 6
  vary 5
  arrayA 10 (3,5) (8,12) (9,1)
And here are evaluations using this file:
  
  Enter the expression, or hit return to quit => arrayA[arrayA[9]*(arrayA[3]+2)+1]-varx
  Enter variable values file name, or hit return if no variables => etest2.txt
  Value of expression = 6.0

  Enter the expression, or hit return to quit =>


Submission

Submit your Expression.java file ONLY.


Frequently Asked Questions

Q: Are array names all uppercase?

A: No. Arrays could have lower case letters in their names. You can tell if a variable is an array if it is followed by an opening square bracket. See, for example, the last example in the "Expression" section, in which varb and varz are arrays:

(varx + vary*varz[(vara+varb[(a+b)*33])])/55

Q: Can we delete spaces from the expression?

A: Sure.

Q: Will the expression contain negative numbers?

A: No. The expression will NOT have things like a*-3 or x+(-y). It will ONLY have the BINARY operators +, -, /, and *. In other words, each of these operators will need two values (operands) to work on. (The - in front of 3 in a*-3 is called a UNARY minus. UNARY operators will NOT appear in the input expression.)

However, it is possible that in the process of evaluating the expression, you come across negative values, either because they appear in the input file, or because they are the result of evaluation. For instance, when evaluating a+b, a=6 and b=-9 as input values, and a result of -3 is a perfectly legitimate scenario.

Q: What if an array index evaluates to a non-integer such as 5/2?

A: Truncate it and use the resulting integer as the index.

Q: Could an array index evaluate to a negative integer?

A: No, you will not be given any input expression or values that would result in a negative integer value for an array index. In other words, you will not need to account for this situation in your code.

Q: What should I do on divide by zero?

A: You don't need to check for this situation.

Q: Could an array name be the same as a simple variable?

A: No. All variable names, for both simple variables and arrays, are unique.

Q: Should the expression "()" be reported as an error?

A: You don't have to do any error checking on the legality of the expression in the makeVariableLists or evaluate methods. When these methods are called, you may assume that the expression is correctly constructed. Which means you will not encounter an expression without at least one constant or variable, and all parens and brackets will be correctly formatted.

Q: Can I convert the expression to postfix, then evaluate the postfix expression?

A: NO!!! You have to work with the given traditional/infix form of the expression.