Question

In: Computer Science

Lisp In the language Lisp1 , each of the four basic arithmetic operators appears before an...

Lisp

In the language Lisp1 , 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. The minus operator must have at least one operand.

(* 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. The divide operator 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) (*) (- 2 3 1)))

This expression is evaluated successively as follows:

(+ (- 6) (* 2 3 4) (/ 3 1 -2))

(+ -6 24 -1.5)

16.5

Write a program that reads such expressions and demonstrates your algorithm. We have provided you some starter code, and you are asked to complete the rest.

LISPTOKEN

package hw5;

public class LispToken

{

private Character operator;

private Double operand;

private boolean isOperator;

/** Constructors for objects of class LispToken. */

public LispToken(Character anOperator)

{

operator = anOperator;

isOperator = true;

operand = 0.0;

}

public LispToken(Double value)

{

operand = value;

isOperator = false;

operator = ' ';

}

/** TODO: Applies this operator to two given operand values.

@param value1 The value of the first operand.

@param value2 The value of the second operand.

@return The real result of the operation.

TODO: You need to complete this method.

*/

public Double applyOperator(Double value1, Double value2)

{

}

/** Gets the identity value of this operator.

For example, x + 0 = x, so 0 is the identity for +

and will be the value associated with the expression (+).

@return The identity value of the operator. */

public Double getIdentity()

{

Double result = 0.0;

switch (operator)

{

case '+':

result = 0.0;

break;

case '-':

result = 0.0;

break;

case '*':

result = 1.0;

break;

case '/':

result = 1.0;

break;

}

return result;

}

/** Detects whether this operator returns a value when it has no operands.

@return True if the operator returns a value when it has no operands,

or false if not. */

public boolean takesZeroOperands()

{

boolean result = false;

switch (operator)

{

case '+':

result = true;

break;

case '-':

result = false;

break;

case '*':

result = true;

break;

case '/':

result = false;

break;

}

return result;

}

/** Gets the value of this operand.

@return The real value of the operand. */

public Double getValue()

{

return operand;

}

/** Returns true if the object is an operator.

@return True is this object is an operator. */

public boolean isOperator()

{

return isOperator;

}

public String toString()

{

String result = null;

if (isOperator)

result = operator.toString();

else

result = operand.toString();

return result;

}

}

LISPQUESTION

package hw5;

import java.util.Scanner;

import java.util.Stack;

public class LispQuestion

{

/** Evaluates a Lisp expression.

The algorithm:

Scan the tokens in the string.

If you see "(", push the next operator onto the stack.

If you see an operand, push it onto the stack.

If you see ")",

Pop operands and push them onto a second stack

until you find an operator.

Apply the operator to the operands on the second stack.

Push the result on the stack.

If you run out of tokens, the value on the top of the stack is

the value of the expression.

@param lispExp A string that is a valid lisp expression.

@return A double that is the value of the expression.

@TODO: You need to complete this method. This method must call the applyOperator from LispToken class.

*/

public static double evaluate(String lispExp)

{

}

public static void main (String args[])

{

Double result;

String test1 = "(+ (- 6) (* 2 3 4) (/ (+ 3) (*) (- 2 3 1)))";

result = evaluate(test1);

System.out.println("Expression " + test1 + " evaluates to " + result);

String test2 = "(+ (- 632) (* 21 3 4) (/ (+ 32) (*) (- 21 3 1)))";

result = evaluate(test2);

System.out.println("Expression " + test2 + " evaluates to " + result);

String test3 = "(+ (/ 2) (* 2) (/ (+ 1) (+) (- 2 1 )))";

result = evaluate(test3);

System.out.println("Expression " + test3 + " evaluates to " + result);

}

}

/*

Expression (+ (- 6) (* 2 3 4) (/ (+ 3) (*) (- 2 3 1))) evaluates to 16.5

Expression (+ (- 632) (* 21 3 4) (/ (+ 32) (*) (- 21 3 1))) evaluates to -378.11764705882354

Expression (+ (/ 2) (* 2) (/ (+ 1) (+) (- 2 1 ))) evaluates to Infinity

*/

Solutions

Expert Solution

LispToken.java

==================================

package hw5;

public class LispToken {
   private Character operator;
   private Double operand;
   private boolean isOperator;
  
   /** Constructors for objects of class LispToken. */
   public LispToken(Character anOperator) {
       operator = anOperator;
       isOperator = true;
       operand = 0.0;
   }
   public LispToken(Double value) {
       operand = value;
       isOperator = false;
       operator = ' ';
   }
  
   /** Applies this operator to two given operand values.
   @param value1 The value of the first operand.
   @param value2 The value of the second operand.
   @return The real result of the operation.
   */
   public Double applyOperator(Double value1, Double value2) {
       // check for operator
       if(operator == '+') {
           return value1 + value2;
       }
       else if(operator == '-') {
           return value1 - value2;
       }
       else if(operator == '*') {
           return value1*value2;
       }
       else if(operator == '/') {
           return value1 / value2;
       }
       else {
           // throw exception if operator is not valid
           throw new IllegalArgumentException();
       }
   }
      
   /** Gets the identity value of this operator.
   For example, x + 0 = x, so 0 is the identity for +
   and will be the value associated with the expression (+).
   @return The identity value of the operator. */
   public Double getIdentity()   {
       Double result = 0.0;
       switch (operator) {
           case '+':
               result = 0.0;
               break;
           case '-':
               result = 0.0;
               break;
           case '*':
               result = 1.0;
               break;
           case '/':
               result = 1.0;
               break;
       }
       return result;
   }
      
   /** Detects whether this operator returns a value when it has no operands.
   @return True if the operator returns a value when it has no operands,
   or false if not. */
   public boolean takesZeroOperands() {
       boolean result = false;
       switch (operator) {
           case '+':
               result = true;
               break;
           case '-':
               result = false;
               break;
           case '*':
               result = true;
               break;
           case '/':
               result = false;
               break;
       }
       return result;
   }
  
   /** Gets the value of this operand.
   @return The real value of the operand. */
   public Double getValue() {
       return operand;
   }

   /** Returns true if the object is an operator.
   @return True is this object is an operator. */
   public boolean isOperator()   {
       return isOperator;
   }
  
   public String toString() {
       String result = null;
       if (isOperator)
           result = operator.toString();
       else
           result = operand.toString();
       return result;
   }
}

====================================

LispQuestion.java

====================================

package hw5;

import java.util.Stack;

public class LispQuestion {
  
   /** Evaluates a Lisp expression.
   The algorithm:
   Scan the tokens in the string.
   If you see "(", push the next operator onto the stack.
   If you see an operand, push it onto the stack.
   If you see ")",
   Pop operands and push them onto a second stack
   until you find an operator.
   Apply the operator to the operands on the second stack.
   Push the result on the stack.
   If you run out of tokens, the value on the top of the stack is
   the value of the expression.
   @param lispExp A string that is a valid lisp expression.
   @return A double that is the value of the expression.
   @TODO: You need to complete this method. This method must call the applyOperator from LispToken class.
   */
   public static double evaluate(String lispExp) {
       // create a stack to hold data
       Stack<LispToken> operators = new Stack<LispToken>();
       Stack<Stack<Double>> stack = new Stack<Stack<Double>>();
       Stack<Double> operands = new Stack<Double>();
       boolean isNextOperator = false;
       String digits = "";
       // read each character from lispExp
       char c = 0;
       for(int i=0;i<lispExp.length();i++) {
           c = lispExp.charAt(i);
           // ignore white space
           if(c == ' ') {
               // parse digits of string to double
               if(digits.length()>0) {
                   double number = Double.parseDouble(digits);
                   // add number to operands
                   operands.add(number);
               }
               // reset digits
               digits = "";
           }
           else {
               // check for open parenthesis
               if(c == '(') {
                   // set flag to true as next char is operator
                   isNextOperator = true;
                   // check operator size
                   if(operators.size()>0) {
                       // put operands to stack
                       stack.add(operands);
                       operands = new Stack<Double>();
                   }
               }
               else if(c == ')') {
                   // parse digits of string to double
                   if(digits.length()>0) {
                       double number = Double.parseDouble(digits);
                       // add number to operands
                       operands.add(number);
                   }
                   // reset digits
                   digits = "";
                   // check for close parenthesis
                   // get the operator
                   LispToken operator = operators.pop();
                   double value = 0.0;
                   // check for operand size
                   if(operands.size()==0) {
                       // check if operator takes zero operand
                       if(operator.takesZeroOperands()) {
                           value = operator.getIdentity();
                       }
                       else {
                           // invalid expression
                           // throw exception
                           throw new IllegalArgumentException();
                       }
                   }
                   else if(operands.size() == 1) {
                       // calculate value for one operand
                       value = operator.applyOperator(operator.getIdentity(), operands.pop());  
                   }
                   else {
                       // apply operator to each operand in stack
                       int size = operands.size();
                       value = operands.elementAt(0);
                       for(int j=1;j<size;j++) {
                           double operand = operands.elementAt(j);
                           value = operator.applyOperator(value, operand);
                       }
                       operands.clear();
                   }
                   // set new operands
                   if(operators.size()>0) {
                       operands = stack.pop();
                   }
                   // add value to new operands
                   operands.add(value);
               }
               else {
                   // check if current char is operator
                   if(isNextOperator) {
                       // push operator to stack
                       operators.add(new LispToken(c));
                       // set flag to false
                       isNextOperator = false;
                   }
                   else {
                       // push operand to stack
                       digits = digits + c;
                   }
               }
           }
       }
       return operands.pop();
   }
  
   public static void main (String args[]) {
       Double result;
       String test1 = "(+ (- 6) (* 2 3 4) (/ (+ 3) (*) (- 2 3 1)))";
       result = evaluate(test1);
       System.out.println("Expression " + test1 + " evaluates to " + result);
       String test2 = "(+ (- 632) (* 21 3 4) (/ (+ 32) (*) (- 21 3 1)))";
       result = evaluate(test2);
       System.out.println("Expression " + test2 + " evaluates to " + result);
       String test3 = "(+ (/ 2) (* 2) (/ (+ 1) (+) (- 2 1 )))";
       result = evaluate(test3);
       System.out.println("Expression " + test3 + " evaluates to " + result);
   }
}

/*
Expression (+ (- 6) (* 2 3 4) (/ (+ 3) (*) (- 2 3 1))) evaluates to 16.5
Expression (+ (- 632) (* 21 3 4) (/ (+ 32) (*) (- 21 3 1))) evaluates to -378.11764705882354
Expression (+ (/ 2) (* 2) (/ (+ 1) (+) (- 2 1 ))) evaluates to Infinity
*/

let me know if you have any doubts or problem.


Related Solutions

LISP Programming Language Write a Bubble Sort program in the LISP Programming Language called “sort” that...
LISP Programming Language Write a Bubble Sort program in the LISP Programming Language called “sort” that sorts the array below in ascending order.  LISP is a recursive language so the program will use recursion to sort. Since there will be no loops, you will not need the variables i, j, and temp, but still use the variable name array for the array to be sorted.             Array to be sorted is 34, 56, 4, 10, 77, 51, 93, 30, 5, 52 The...
Scheme is a dialect of a programming language called Lisp, which was developed at MIT in...
Scheme is a dialect of a programming language called Lisp, which was developed at MIT in 1959. Alice 1.0 was released in 2006 from CMU, and Python in 1994. Based on what you know of the Scheme language, describe the major differences between how it works and how Alice or Python works. What advantages might Scheme have over Alice/Python? What advantages might Alice/Python have over Scheme?
what is the basic language development, including the basic properties of language and theories of language...
what is the basic language development, including the basic properties of language and theories of language found in infants/toddlers
USING C++: Consider the precedence levels of the relational, logical, and arithmetic operators of the PySub...
USING C++: Consider the precedence levels of the relational, logical, and arithmetic operators of the PySub language to be as follows (NOTE: 5 has highest precedence and 0 lowest): 5 *, /, % 4 +, - 3 <, <=, >, >=, !=, == 2 not 1 and 0 or 1.  Infix-Postfix Conversion and Evaluation with Logical and Relational operators – Convert the following infix expression to a postfix expression and evaluate the result (assume that true=1 and false=0). Provide both the...
Using the descriptions below, write a scanner for numbers, symbols, comments, arithmetic operators, and parenthesis in...
Using the descriptions below, write a scanner for numbers, symbols, comments, arithmetic operators, and parenthesis in Racket or scheme. - a number is one or more digits | zero of more digits followed by a decimal point followed by one or more digits | one or more digits followed by a decimal point followed by zero or more digits - a symbol is      one or more characters from the set [_A-Za-z] followed by zero or more characters from the...
C++ OOP Make a program to evaluate infix arithmetic expressions containing integer operands and the operators...
C++ OOP Make a program to evaluate infix arithmetic expressions containing integer operands and the operators + (addition), - (subtraction), * (multiplication), / (division) and pairs of parentheses, properly nested. Use the following two-stack algorithm (by E. W. Dijkstra): If the next token in the expression is an integer, push the integer onto the value stack. If the next token in the expression is an operator, If the operator stack is empty or the priority of the operator is greater...
using python without external libaries Using integer arithmetic operators '+' and '-', print all combinations that...
using python without external libaries Using integer arithmetic operators '+' and '-', print all combinations that sum up to 'sum' by inserting the operators between digits in 'number'. example for 'number=123456789' and 'sum = 0' Print the output using the terminal: Output should be exactly like this from 1 - 22 1 : +1+2-34-56+78+9=0 2 : +1-2-34+5+6+7+8+9=0 3 : +1-23-4-56-7+89=0 ... 12 : -1+2+34-5-6-7-8-9=0 13 : -1+23+4+56+7-89=0 14 : -1-2+34+56-78-9=0 ... 22 : -12-34+56+7-8-9=0
CODE USING LISP... No other language please trim-to (symbol list) Write a function named trim-to that...
CODE USING LISP... No other language please trim-to (symbol list) Write a function named trim-to that takes a symbol and list as parameters. Return a new list starting from the first occurrence of the input symbol in the input list. If there is no occurrence of the symbol, return nil. For example: (trim-to ‘c ‘(a b c d e)) This should return the following list: ‘(c d e) ackermann (number number) Write a function named ackermann that takes two integers....
Briefly discuss each of the four basic aspects of the marketing mix and how each interfaces...
Briefly discuss each of the four basic aspects of the marketing mix and how each interfaces with the logistics function. In your opinion, which component of the marketing mix represents the most important interface with logistics? Why?
Discussion Topic: In a program written in a high level language, if an arithmetic error occurs...
Discussion Topic: In a program written in a high level language, if an arithmetic error occurs the program aborts and produces an error message that usually has the phrase "Arithmetic Overflow Error". This can happen in different circumstances such as: an illegal calculation was performed, such as trying to divide a number by zero the result of a calculation is a number that is too large or two small for the computer to store and in other circumstances as well....
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT