Postfix Notation is a notation in which the operator follows its operands in the expression (e.g ).

Similar documents
Assignment 5. Introduction

Assignment 4 Publication date: 27/12/2015 Submission date: 17/01/ :59 People in-charge: R. Mairon and Y. Twitto

09 STACK APPLICATION DATA STRUCTURES AND ALGORITHMS REVERSE POLISH NOTATION

COMP-421 Compiler Design. Presented by Dr Ioanna Dionysiou

infix expressions (review)

Lecture 4: Stack Applications CS2504/CS4092 Algorithms and Linear Data Structures. Parentheses and Mathematical Expressions

Lab 7 1 Due Thu., 6 Apr. 2017

CSCI 200 Lab 4 Evaluating infix arithmetic expressions

A Simple Syntax-Directed Translator

Stacks. Chapter 5. Copyright 2012 by Pearson Education, Inc. All rights reserved

STACKS. A stack is defined in terms of its behavior. The common operations associated with a stack are as follows:

CS 211 Programming Practicum Spring 2017

SimpleCalc. which can be entered into a TI calculator, like the one on the right, like this:

Advanced Java Concepts Unit 3: Stacks and Queues

Chapter 3: CONTEXT-FREE GRAMMARS AND PARSING Part2 3.3 Parse Trees and Abstract Syntax Trees

Context-Free Grammar. Concepts Introduced in Chapter 2. Parse Trees. Example Grammar and Derivation

CPSC 211 Data Structures & Implementations (c) Texas A&M University [ 165] Postfix Expressions

CS 211 Programming Practicum Spring 2018

Collections Chapter 12. Instructor: Scott Kristjanson CMPT 125/125 SFU Burnaby, Fall 2013

-The Hacker's Dictionary. Friedrich L. Bauer German computer scientist who proposed "stack method of expression evaluation" in 1955.

1 Lexical Considerations

CS 211 Programming Practicum Fall 2018

Project 1: Implementation of the Stack ADT and Its Application

Stack Applications. Lecture 27 Sections Robb T. Koether. Hampden-Sydney College. Wed, Mar 29, 2017

Linear Data Structure

1. Stack Implementation Using 1D Array

CMPSCI 187 / Spring 2015 Postfix Expression Evaluator

Stacks. Chapter 5. Copyright 2012 by Pearson Education, Inc. All rights reserved

CSCI 204 Introduction to Computer Science II. Lab 6: Stack ADT

An Introduction to Trees

Stack and Its Implementation

This book is licensed under a Creative Commons Attribution 3.0 License

Special Section: Building Your Own Compiler

In this chapter you ll learn:

Stacks. stacks of dishes or trays in a cafeteria. Last In First Out discipline (LIFO)

Stack Abstract Data Type

Stacks and their Applications

CSC 222: Computer Programming II. Spring 2005

BBM 201 DATA STRUCTURES

Top of the Stack. Stack ADT

Lecture 4 Stack and Queue

Stacks, Queues and Hierarchical Collections

CSE P 501 Exam 8/5/04

Data Structure using C++ Lecture 04. Data Structures and algorithm analysis in C++ Chapter , 3.2, 3.2.1

2.2 Syntax Definition

Stacks Fall 2018 Margaret Reid-Miller

Jim Lambers ENERGY 211 / CME 211 Autumn Quarter Programming Project 4

March 13/2003 Jayakanth Srinivasan,

12 Abstract Data Types

Stacks, Queues and Hierarchical Collections. 2501ICT Logan

Some Applications of Stack. Spring Semester 2007 Programming and Data Structure 1

Data Structures and Algorithms

TDDD55 - Compilers and Interpreters Lesson 3

ADT Stack. Inserting and deleting elements occurs at the top of Stack S. top. bottom. Stack S

Formal Languages and Automata Theory, SS Project (due Week 14)

Examples of attributes: values of evaluated subtrees, type information, source file coordinates,

Stating the obvious, people and computers do not speak the same language.

CSIS 10B Lab 2 Bags and Stacks

BBM 201 DATA STRUCTURES

CS Introduction to Data Structures How to Parse Arithmetic Expressions

CSE au Final Exam Sample Solution

Le L c e t c ur u e e 2 To T p o i p c i s c t o o b e b e co c v o e v r e ed e Variables Operators

Stacks II. Adventures in Notation. stacks2 1

Stacks. Revised based on textbook author s notes.

CS251 Programming Languages Handout # 29 Prof. Lyn Turbak March 7, 2007 Wellesley College

Chapter 3. Describing Syntax and Semantics

Introduction to Computer Science II (ITI 1121) Midterm Examination

Decaf Language Reference

Points off Total off Net Score. CS 314 Final Exam Spring 2016

Lexical Considerations

CS 211. Project 5 Infix Expression Evaluation

Chapter 3: Describing Syntax and Semantics. Introduction Formal methods of describing syntax (BNF)

Lexical Considerations

CSE143 Exam with answers Problem numbering may differ from the test as given. Midterm #2 February 16, 2001

The SPL Programming Language Reference Manual

19 Much that I bound, I could not free; Much that I freed returned to me. Lee Wilson Dodd

Programming Languages Third Edition. Chapter 7 Basic Semantics

ADTS, GRAMMARS, PARSING, TREE TRAVERSALS

A simple syntax-directed

CS2110 Assignment 2 Lists, Induction, Recursion and Parsing, Summer

Comp 411 Principles of Programming Languages Lecture 3 Parsing. Corky Cartwright January 11, 2019

A programming language requires two major definitions A simple one pass compiler

Stack ADT. ! push(x) puts the element x on top of the stack! pop removes the topmost element from the stack.

Chapter 3. Describing Syntax and Semantics ISBN

Full file at

A Short Summary of Javali

CS 330 Homework Comma-Separated Expression

IPCoreL. Phillip Duane Douglas, Jr. 11/3/2010

Stacks. Access to other items in the stack is not allowed A LIFO (Last In First Out) data structure

EDAN65: Compilers, Lecture 04 Grammar transformations: Eliminating ambiguities, adapting to LL parsing. Görel Hedin Revised:

Review: Expressions, Variables, Loops, and more.

Java Primer 1: Types, Classes and Operators

n Data structures that reflect a temporal relationship q order of removal based on order of insertion n We will consider:

CSC 273 Data Structures

[CS302-Data Structures] Homework 2: Stacks

Introduction to Programming Using Java (98-388)

Introduction. Problem Solving on Computer. Data Structures (collection of data and relationships) Algorithms

Top of the Stack. Stack ADT

Chapter 3. Describing Syntax and Semantics

Lists are great, but. Stacks 2

Transcription:

Assignment 5 Introduction For this assignment, you will write classes to evaluate arithmetic expressions represented as text. For example, the string "1 2 ( * 4)" would evaluate to 15. This process will be similar to how Java, and other programming languages, compile human-written code into machine instructions. Compilation takes syntactic information (your code, essentially a long string of characters) and turns it into semantic information (that is, the operations you want the machine to perform). Infix and Postfix notations for arithmetic expressions: Arithmetic expressions are made of operators (, -, etc.) and operands (either numbers, variables or, recursively, smaller arithmetic expressions). The expressions can be written in a variety of notations. In this assignment, you will focus on two standard arithmetic expression notations: postfix and infix. Postfix Notation is a notation in which the operator follows its operands in the expression (e.g. 2 4 ). More formally, in this assignment a postfix expression is recursively defined as follows: 1. Any number is a postfix expression. 2. If P1 is a postfix expression, P2 is a postfix expression, and Op is an operator, then P1 P2 Op is a postfix expression. Infix notation is the common arithmetic and logical formula notation, in which an operator is written between the operands it acts on (e.g. 2 4). More formally, in this assignment an infix expression is recursively defined as follows: 1. Any number or variable is an infix expression. 2. If I1 is an infix expression, then ( I1 ) is an infix expression.. If I1 is an infix expression, I2 is an infix expression, and Op is and operator, then I1 Op I2 is an infix expressions. Using parentheses to resolve ambiguity. Note that the postfix expression representation does not require the use of parentheses- the order of operations is clear (no ambiguity) from the order of the operands and operators. However, such is not the case in infix notations, which naturally give rise to ambiguous interpretation. Due to this ambiguity, parentheses surrounding groups of operands and operators are necessary to indicate the intended order in which operations are to be performed. In the absence of parentheses, certain precedence rules determine the order of operations. For example, it is customary that the multiplication operation (*) has higher precedence than the addition operation (), and thus the infix expression 5*2 is interpreted as: first compute 5*2 and then add to the resulting product. This is equivalent to the postfix expression 52*. Parentheses can be applied to "override" the default (operatorprecedence based) order of operations: ( 5) * 2 is interpreted as: first compute 5 and then multiply the obtained sum by 2. This is equivalent to the postfix expression 52*. The table below demonstrates some infix expressions and their equivalent postfix expressions. 1

Infix expression Postfix expression 1 2 1 2 6 * 5 4 6 5 * 4 (7 2) * 4 7 2 4 * (4 ) - (2 * 7) 4 2 7 * - Note that, both in infix and postfix notation, the results of the application of some operations become the operands of other operations. For example, in the second example in the table above: 6*54, "6 5 *" is the first operand for the "" operator. Part 1 (Postfix Calculator) In this part of the assignment you will be asked to write a program that simulates a postfix calculator. More specifically, the program you write should take, as input, an expression in postfix notation, and return, as output, the computed value of the given expression. This involves various tasks, such as parsing the input text into tokens (i.e. small substrings, delimited by spaces ), creating a stack class, and then implementing an algorithm which uses the stack and the token parser to evaluate a given postfix expression. In the next section the suggested postfix evaluation algorithm is given. Note that, in this part of the assignment, it is ok to assume that the input expression is syntactically correct. A Postfix Expression Evaluation Algorithm There is a very simple algorithm for evaluating syntactically correct postfix expressions, which reads the expression left to right in chunks, or tokens. In this part of the assignment, the tokens are substrings delimited by spaces, and consist of numbers and/or operators. For example, the expression 6 will generate the series of three tokens: 6, and. The pseudo code for the postfix expression evaluation algorithm is given below. while tokens remain: read the next token. if the token is an operator: pop the top two elements of the stack. perform the operation on the elements. push the result of the operation onto the stack. else: push the token (which must be a number)onto the stack When there are no tokens left, the stack only contains one item: the final value of the expression. For an example with stack diagrams, see the Wikipedia page on postfix notation (http://en.wikipedia.org/wiki/postfix_notation#example) In the next section the classes that you need to implement for this part of the assignment are listed and described. 2

The classes you need to implement Class StackAsArray The Stack interface, similarly to the one taught in lecture is provided in the file Stack.java, which is part of the file supplied to you with this exercise. As a first stage, write a class called StackAsArray which implements the Stack interface using an array, as was taught in class. Token Classes You will provide the token classes, which are all subclasses of abstract class CalcToken (CalcToken.java is provided). For this part of the assignment, there are two types of tokens: 1. Tokens which represent a numerical value. You must create a class ValueToken with the following methods: o ValueToken(double val) where val is the number the token should represent(constructor). o double getvalue() returns the value of the token. o String tostring() which is inherited from the abstract parent class CalcToken. 2. Tokens which represent operators. These are described by the abstract class BinaryOp (because we are concerned with operations that require two operands). The file BinaryOp.java is provided. You must implement classes AddOp, SubtractOp, MultiplyOp, DivideOp, and PowOp, which represent addition, subtraction, multiplication, division, and power respectively. All subclasses of BinaryOp must have the following methods: o double operate(double left, double right) returns the result of the operation using its left and right operands (note that operand order can matter, depending on operator). o String tostring(), which is inherited from CalcToken. Class ExpTokenizer In order to convert a string into a series of tokens, you will have to provide class ExpTokenizer. Before you start implementing ExpTokenizer you must read carefully about the class StringTokenizer in the Java API (http://java.sun.com/j2se/1.4.2/docs/api/java/util/stringtokenizer.html). Understanding the API documentation of existing code is an important skill for a programmer. Reading the StringTokenizer API and extending it is an integral part of this assignment. You will implement the class ExpTokenizer, which extends the class StringTokenizer (this class is in java.util.*). The constructor for this class is given below: public class ExpTokenizer extends StringTokenizer{ public ExpTokenizer(String exp) { super(exp); } Note: you may assume that all the tokens are separated by the space character.

Next, you will override the StringTokenizer method nextelement(), as exemplified below. public Object nextelement(){ CalcToken resulttoken = null; String token = super.nexttoken(); if (token.equals("")) resulttoken = new AddOp(); else if (token.equals("*")) resulttoken = new MultiplyOp(); //Fill the rest of the token cases by yourself else resulttoken = new ValueToken(Double.parseDouble(token)); } return resulttoken; Note: you may assume that all the tokens in the input expression are either real, positive numbers or one of the five operators:, -, *, ^ and /. You will need to support only real positive numbers (e.g. 4 or 4.2). There is no need to support negative numbers (e.g. -4.2, -4). Class PostfixCalculator The primary class in the code, which you will implement for Part 1 of the assignment, is Class PostfixCalculator. In addition to its constructor, it has one public method: double evaluate(string expr), where expr is a String representing a correct postfix expression. This method evaluates (i.e. computes the numerical value of) expr, and returns its value. This method should use the algorithm described above, and should be implemented by using a StackAsArray object. Examples for some input postfix expressions, as well as the expected output value, are given below. Examples of Postfix Expressions and Their Values PostfixCalculator c1 = new PostfixCalculator(); c1.evaluate("2 "); //returns 5.0 c1.evaluate(" 5 -"); // returns -2.0 c1.evaluate("6 2 *");// returns 12.0 c1.evaluate("10 4 /");// returns 2.5 c1.evaluate("2 4 ^");// returns 16.0 c1.evaluate("2 4 2 - *"); // returns 10.0 c1.evaluate("2 ^ 4 2 * / 7 -");// returns -6.0 Note: You may assume, in Part 1 of the assignment, that the input expression is a valid postfix expression 4

Part 2 (Infix Calculator) For the second part of the assignment, you will write classes to evaluate expressions in regular infix notation. Note that even though we are more familiar with this format of writing expressions, these expressions are more difficult to evaluate. In this part of the assignment, you will need to take into account the predefined operator precedence definitions, the bracketing used to override precedence (e.g. "(45)*6") as well as possible errors in the expression. An Infix Expression Evaluation Algorithm The algorithm you will use for evaluating infix expressions (which, is not the algorithm used by compilers) is similar to the algorithm from Part 1 in the sense that it reads the expression left to right in chunks, or tokens. However, in addition to the previous tokens which were restricted to numbers and operators, the infix expression evaluator is extended to support bracket tokens as well, and to take into account operator precedence. The main operation used by the algorithm is called collapse because it replaces three items on the stack with one simpler but equivalent item. The pseudocode for the collapse operation, which takes as input a new token T and then iteratively peeks at the top three elements in the stack before deciding whether to collapse them or not is given below: Collapse(T) While not end collapse: Consider the new token T, in addition to E0, E1, and E2, which are the first three elements in the stack, in top-down order, and decide whether to apply Case 1, Case 2 or Case below. Case 1: E0 and E2 are Value Tokens and E1 is a Binary Operation and ((If T is a Binary Operation with lower or equal precedence than E1) or (T is not a Binary Operation)): pop E0, pop E1, pop E2 apply the binary operator E1 to operands E0 and E2 push the result Case 2: E0 and E2 are, correspondingly, close and open brackets, and E1 is a value: pop E0, pop E1, pop E2 push E1 Case : neither Case 1 nor Case 2 above apply: end collapse. Note that the collapse operation does not push the new token (i.e. T, above) onto the stack. Also note that multiple collapses are possible (the iterative while loop), if a collapse creates the criteria for a subsequent collapse (See the Infix Evaluation Example below). The table below summarizes the decisions taken by the collapse operation, given E0, E1, E2 and the new token T. (The pseudo code for this operation will follow.) 5

E0 E1 E2 Additional criteria Action ValueToken BinaryOp ValueToken CloseBracket Value OpenBracket - T is a BinaryOp and E1 has equal to or higher precedence than T or - T is not a BinaryOp - pop E0, E1, E2 - push the value of E1 with operands E2 and E0 - pop E0, E1, E2 - push E1 The pseudo code for the infix expression evaluation algorithm, which employs the collapse operation, is given below: while tokens remain: read the next token T. Collapse(T). push the token T onto the stack. When the above pseudo code completes, and there are no tokens left, the stack only contains one item: the final value of the given infix expression. In the next section an example to demonstrate the above algorithm for infix expression evaluation is given. An Infix Expression Evaluation Example Consider the string "(1 2) 4 * 5". The steps of evaluation are as follows: Stack Contents Next Token Empty ( ( 1 push ( push 1 Action Taken 1 ( 1 ( 2 1 ( 2 ) push push 2 collapse: o pop 2, pop, pop 1 o push [= 1 2] push ) 6

) ( collapse: o pop ), pop, pop ( o push push 4 * 4 5 * 4 20 4 * 5 none none push 4 push * (note: do not collapse since * has higher precedence than ) push 5 collapse: o pop 5, pop *, pop 4 o push 20 [= 4 * 5] collapse: o pop 20, pop, pop o push 2 [= 20] 2 none none - finished! In the next section the classes that you need to implement for this part of the assignment are listed and described. The classes you need to implement Class PeekableStackAsArray Because the task of evaluating infix expressions is more complex than that of evaluating postfix expressions, an augmented stack with some additional functionality is required. More specifically, you need to be able to "peek" into the stack and examine some of its elements without removing them from the stack. You are provided with the PeekableStack interface, which includes the following methods: since PeekableStack extends Stack, it includes all of the Stack methods (push(), pop() and isempty() ). Object peek(int i), which returns the i-th stack element from the top of the stack. There is no need to return a deep copy of the object. int size(), which maintains the current size of the stack. void clear(), which empties the stack. String stackcontents(), which returns a string representing the stack's contents. The purpose of this method is to help you in the process of debugging your code. 7

This interface must be implemented in a class called PeekableStackAsArray, which (predictably) uses an array to hold the stack items. You may not copy code from your StackAsArray class (use inheritance). More Token classes For this part of the assignment, you will be using the token classes which you previously created in Part 1. In addition, ExpTokenizer requires two more types of tokens: 1. Tokens which represent additional allowed symbols, such as brackets "(", ")" You must provide classes OpenBracket and CloseBracket, which are subclasses of CalcToken, and have no additional methods. 2. Create tokens which represent any substring that does not comply with the previously defined token categories, and thus should be recognized as and error. In this part you are required provide class ErrorToken (subclass of CalcToken), with the following methods: o ErrorToken(String text), a new constructor which accepts the text containing the error(e.g. for an expression "4 $ 5 " you should create new ErrorToken("$"); o String tostring(), which returns the String "SYNTAX ERROR: blah", where "blah" was the error text provided with the constructor. Operator Precedence This part of the assignment also uses the getprecedence() method of abstract class BinaryOp. You must modify your token classes from Part 1 to ensure that, for any two BinaryOp objects A and B, 1. A.getPrecedence() == B.getPrecedence() if the respective operations are of equal precedence. 2. A.getPrecedence() > B.getPrecedence() if A's operation occurs before B's operation (i.e. it is of higher precedence). Notes: Power ("^") precedence is higher than Multiplication ("*") precedence. Multiplication("*") has the same precedence as Division ("/"). Multiplication("*") precedence is higher than Addition("") precedence. Addition("") has the same precedence as Subtraction("-"). Class ExpTokenizer In this part you will need to update the method nextelement() in ExpTokenizer.java in order to deal with brackets tokens, such as "(",")". Update the method NextElement in ExpTokenizer.java in order deal with the error tokens which you have implemented, i.e. tokens which do not comply with any of the defined categories. Class InfixCalculator The primary class of this part of the assignment is InfixCalculator. In addition to its constructor, it has the following methods: 8

public boolean evaluate(string expr), processes expr using the above algorithm and a PeekableStackAsArray. Returns true if expr is a valid infix expression and has been evaluated, and false otherwise. public double getresult(), returns the result of the most recent successful evaluation (return -1 if no successful evaluation exists). private void collapse(calctoken token) collapses the stack until a collapse rule cannot be applied, given the next token. Examples for some input infix expressions, as well as the expected output value, are given below. Examples of Infix Expressions and the Corresponding Output InfixCalculator c1 = new InfixCalculator(); c1.evaluate( 5 2 ); //returns true c1.getresult(); returns 7.0 c1.evaluate( 4 ^ 2 * / 8 2 10 ); //returns true c1.getresult();// returns -2.0 c1.evaluate( 0.5 2 * ^ 2 ); //returns true c1.getresult();// returns 18.5 c1.evaluate( ( 4 ) ); //returns true c1.getresult(); //returns 4.0 c1.evaluate( ( ( 10 ^ 2 ) * ( 10 10.02 ) ) ); //returns true c1.getresult(); //returns -2.0 c1.evaluate( ( ( 10 /( 2 ^ 2 ) /.75 ) * ( 6 ) ) ^ ( 0.5 * ( ( ( 10.5-6.5 ) ) ) ) ); //returns true c1.getresult(); //returns 16.0 c1.evaluate( ); // returns false c1.getresult(); //returns 16.0 c1.evaluate( ( 7.0 ); //returns false c1.evaluate( 5 6 * ( 4.0 ) ); //returns false Note: You may not assume, in Part 2 of the assignment, that the input expression is a valid infix expression. 9

What is NOT allowed You may not use any classes from java.util (Except from StringTokenizer), which includes the Java Collections such as List. Testing hints You should test each public method, using extreme ("boundary") correct and incorrect values, where allowed by preconditions, as well as the obvious "middle of the road" values. Remember to choose efficient test cases. For example, testing PostfixCalculator.run() with strings "1 2 ", " 7 ", and "21 4 " is unnecessary, since they test the exact same thing - in this case, the addition of two numbers. Test basic methods before complicated ones. Test simple objects before objects that include or contain the simple objects. Don't test too many things in a single test case. What to submit for Assignment 5 StackAsArray.java, PeekableStackAsArray.java. The token classes, in files ValueToken.java, OpenBracket.java, CloseBracket.java, ErrorToken.java, AddOp.java, SubtractOp.java, MultiplyOp.java, DivideOp.java, and PowOp.java. ExpTokenizer.java. PostfixCalculator.java and InfixCalculator.java. Stack.java, PeekableStack.java, CalcToken.java and BinaryOp.java. Part 1 java files in bold. GOOD LUCK! 10