Question
readme.txt - You need to implement LispExprEvaluator.java which uses Java API Stack See project requirements in LispExprEvaluator.java - Use PJ2_Test.java to test correctness of your
readme.txt
- You need to implement LispExprEvaluator.java which uses Java API Stack
See project requirements in LispExprEvaluator.java
- Use PJ2_Test.java to test correctness of your program
- Compile programs (you are in directory containing Readme file):
javac PJ2/*.java
javac *.java
- Run programs (you are in directory containing Readme file):
// Run main() method tests in LispExprEvaluator class
java PJ2.LispExprEvaluator
// Run main test program
java PJ2_Test
-----------------------------------
LispExprEvaluator.java
/************************************************************************************
*
* Specification:
*
* Taken from Project 7, Chapter 5, Page 178
* I have modified specification and requirements of this project
*
* Ref: http://www.gigamonkeys.com/book/ (see chap. 10)
*
* In the language Lisp, each of the four basic arithmetic operators appears
* before an arbitrary number of operands, which are separated by spaces.
* The resulting expression is enclosed in parentheses. The operators behave
* as follows:
*
* (+ a b c ...) returns the sum of all the operands, and (+) returns 0.
*
* (- a b c ...) returns a - b - c - ..., and (- a) returns -a.
*
* (* a b c ...) returns the product of all the operands, and (*) returns 1.
*
* (/ a b c ...) returns a / b / c / ..., and (/ a) returns 1/a.
*
* Note: + * may have zero operand
* - / must have at least one operand
*
* You can form larger arithmetic expressions by combining these basic
* expressions using a fully parenthesized prefix notation.
* For example, the following is a valid Lisp expression:
*
* (+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)) (+))
*
* This expression is evaluated successively as follows:
*
* (+ (- 6) (* 2 3 4) (/ 3 1 -2) (+))
* (+ -6 24 -1.5 0.0)
* 16.5
*
* Requirements:
*
* - Design and implement an algorithm that uses Java API stacks to evaluate a
* Valid Lisp expression composed of the four basic operators and integer values.
* - Valid tokens in an expression are '(',')','+','-','*','/',and positive integers (>=0)
* - Display result as floting point number with at 2 decimal places
* - Negative number is not a valid "input" operand, e.g. (+ -2 3)
* However, you may create a negative number using parentheses, e.g. (+ (-2)3)
* - There may be any number of blank spaces, >= 0, in between tokens
* Thus, the following expressions are valid:
* (+ (-6)3)
* (/(+20 30))
*
* - Must use Java API Stack class in this project.
* Ref: http://docs.oracle.com/javase/7/docs/api/java/util/Stack.html
* - Must throw LispExprEvaluatorException to indicate errors
* - Must not add new or modify existing data fields
* - Must implement these methods :
*
* public LispExprEvaluator()
* public LispExprEvaluator(String currentExpression)
* public void reset(String currentExpression)
* public double evaluate()
* private void evaluateCurrentOperation()
*
* - You may add new private methods
*
*************************************************************************************/
package PJ2;
import java.util.*;
public class LispExprEvaluator
{
// Current input Lisp expression
private String currentExpr;
// Main expression stack & current operation stack, see algorithm in evaluate()
private Stack
private Stack
// default constructor
// set currentExpr to ""
// create stack objects
public LispExprEvaluator()
{
// add statements
}
// constructor with an input expression
// set currentExpr to currentExpression
// create stack objects
public LispExprEvaluator(String currentExpression)
{
// add statements
}
// set currentExpr to currentExpression
// clear stack objects
public void reset(String currentExpression)
{
// add statements
}
// This function evaluates current operator with its operands
// See complete algorithm in evaluate()
//
// Main Steps:
// Pop operands from exprStack and push them onto
// computeStack until you find an operator
// Apply the operator to the operands on computeStack
// Push the result into exprStack
//
private void evaluateCurrentOperation()
{
// add statements
}
/**
* This funtion evaluates current Lisp expression in currentExpr
* It return result of the expression
*
* The algorithm:
*
* Step 1 Scan the tokens in the string.
* Step 2 If you see an operand, push operand object onto the exprStack
* Step 3 If you see "(", next token should be an operator
* Step 4 If you see an operator, push operator object onto the exprStack
* Step 5 If you see ")" // steps in evaluateCurrentOperation() :
* Step 6 Pop operands and push them onto computeStack
* until you find an operator
* Step 7 Apply the operator to the operands on computeStack
* Step 8 Push the result into exprStack
* Step 9 If you run out of tokens, the value on the top of exprStack is
* is the result of the expression.
*/
public double evaluate()
{
// only outline is given...
// you need to add statements/local variables
// you may delete or modify any statements in this method
// use scanner to tokenize currentExpr
Scanner currentExprScanner = new Scanner(currentExpr);
// Use zero or more white space as delimiter,
// which breaks the string into single character tokens
currentExprScanner = currentExprScanner.useDelimiter("\\s*");
// Step 1: Scan the tokens in the string.
while (currentExprScanner.hasNext())
{
// Step 2: If you see an operand, push operand object onto the exprStack
if (currentExprScanner.hasNextInt())
{
// This force scanner to grab all of the digits
// Otherwise, it will just get one char
String dataString = currentExprScanner.findInLine("\\d+");
// more ...
}
else
{
// Get next token, only one char in string token
String aToken = currentExprScanner.next();
char item = aToken.charAt(0);
switch (item)
{
// Step 3: If you see "(", next token shoube an operator
// Step 4: If you see an operator, push operator object onto the exprStack
// Step 5: If you see ")" // steps in evaluateCurrentOperation() :
default: // error
throw new LispExprEvaluatorException(item + " is not a legal expression operator");
} // end switch
} // end else
} // end while
// Step 9: If you run out of tokens, the value on the top of exprStack is
// is the result of the expression.
//
// return result
return 0.0; // change this statement
}
//=============================================================
// DO NOT MODIFY ANY STATEMENTS BELOW
//=============================================================
// This static method is used by main() only
private static void evaluateExprTest(String s, LispExprEvaluator expr, String expect)
{
Double result;
System.out.println("Expression " + s);
System.out.printf("Expected result : %s ", expect);
expr.reset(s);
try {
result = expr.evaluate();
System.out.printf("Evaluated result : %.2f ", result);
}
catch (LispExprEvaluatorException e) {
System.out.println("Evaluated result : "+e);
}
System.out.println("-----------------------------");
}
// define few test cases, exception may happen
public static void main (String args[])
{
LispExprEvaluator expr= new LispExprEvaluator();
String test1 = "(+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)) (+))";
String test2 = "(+ (- 632) (* 21 3 4) (/ (+ 32) (* 1) (- 21 3 1)) (+))";
String test3 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 1) (- 2 1 ))(*))";
String test4 = "(+ (/2)(+))";
String test5 = "(+ (/2 3 0))";
String test6 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 3) (- 2 1 ))))";
String test7 = "(+ (/) )";
String test8 = "(+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (-)) (+1))";
evaluateExprTest(test1, expr, "16.50");
evaluateExprTest(test2, expr, "-378.12");
evaluateExprTest(test3, expr, "4.50");
evaluateExprTest(test4, expr, "0.50");
evaluateExprTest(test5, expr, "Infinity or LispExprEvaluatorException");
evaluateExprTest(test6, expr, "LispExprEvaluatorException");
evaluateExprTest(test7, expr, "LispExprEvaluatorException");
evaluateExprTest(test8, expr, "LispExprEvaluatorException");
}
}
---------------------------------
LispExprEvaluatorException.java
/************************************************************************************
*
* Do not modify this file.
*
* LispExprEvaluatorException class
*
* It is used by LispExpressionEvaluator
*
*************************************************************************************/
package PJ2;
public class LispExprEvaluatorException extends RuntimeException
{
public LispExprEvaluatorException()
{
this("");
}
public LispExprEvaluatorException(String errorMsg)
{
super(errorMsg);
}
}
-------------------------
PJ2_Test.java
import PJ2.*;
import java.util.*;
// Do not modify this file.
//
// Simple test program which allows user to input Lisp expr string
// To terminate: type "exit"
public class PJ2_Test
{
public static void main (String args[])
{
// create a LispExprEvaluator object
LispExprEvaluator expr= new LispExprEvaluator();
// scan input expr string
Scanner scanner;
// current expr string and its result
String inputExpr;
double result;
int i=0;
scanner = new Scanner( System.in ); // scanner for input
do
{
try
{
System.out.print( " input an expression string:" );
// scan next input line
inputExpr = scanner.nextLine();
if (inputExpr.equals("exit"))
break; // loop
i++;
System.out.println("Evaluate expression #"+ i+" :" + inputExpr);
expr.reset(inputExpr);
result = expr.evaluate();
System.out.printf("Result : %.2f ", result);
} // end try
catch ( LispExprEvaluatorException e )
{
System.err.printf( " Exception: %s ", e);
} // end catch exception here, continue to next loop
} while ( true ); // end do...while
} // end main
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started