Monday, November 13, 2017 Topics for today ode generation nalysis lgorithm 1: evaluation of postfix lgorithm 2: infix to postfix lgorithm 3: evaluation of infix lgorithm 4: infix to tree nalysis We are constructing a binary tree from an input expression. We lead up to the algorithm that does this (lgorithm 4) by looking at three simpler ones. omp 162 Notes Page 1 of 13 November 13, 2017
lgorithm 1: evaluation of a post-fix expression n infix expression is one where an operator is placed between its operands as in postfix expression is one where the operator follows its operands as in n advantage of a postfix expression is that it is parenthesis free and can be evaluated from left to right (using a stack) unlike an infix expression such as D The post-fix expression corresponding to this infix example is D Only two kinds of symbols appear in a post-fix expression: operators and operands. There are no parentheses. So all our algorithm has to do is define what action to take for each type of symbol. The algorithm uses a stack of operands. The actions for the two types of symbol are: Symbol operand put it on the stack ction operator apply it to the top two stack items and replace them by the result. onsider the postfix evaluation of 23 5 7 4 Here is what the stack looks like as the expression is read: Input 23 5 7 4 Stack 5 7 4 7 28 23 23 115 115 115 115 143 If the expression is well-formed there will be exactly one item on the stack after the last input symbol has been processed. t no time will we try to perform an operation with only one number on the stack. omp 162 Notes Page 2 of 13 November 13, 2017
lgorithm 2: conversion of an infix expression to postfix It would be handy to have an algorithm that reads an infix expression from left to right and outputs the corresponding post-fix. For example input: ( ) D / E output: D E / Features of the algorithm: has to process open and close parentheses the operands in the output are in the same order as in the input but the order of operators may be different reflecting the different operator priorities - multiplication has higher priority than addition for example the stack used by the algorithm is a stack of operators - we include "(" in this category. We just have to define what action to take for each of the 4 kinds of symbol that can appear in the input. Here are the actions. Symbol ction ( put it on the stack with lowest possible priority ) Unstack and output operators until "(" reached. Unstack but do not output the "(" operand output it operator end of input while ( priority(top-of-stack) priority(input)) unstack it and output it. push the input onto the stack If the stack is not empty, unstack and output the stacked operators one by one. Here is a trace of the example above Input ( ) D / E Stack / / ( ( ( ( Output D E / omp 162 Notes Page 3 of 13 November 13, 2017
lgorithm 3: Evaluate infix - a combination of algorithms 1 and 2. We can combine algorithms 1 and 2 to give us an algorithm that reads an infix expression and determines its value. It will use two stacks (an operand stack as in algorithm 1 and an operator stack as in algorithm 2). s in algorithm 1 it will leave the value of the expression as the only item on the operand stack. Here are the actions required for each of the four kinds of symbol: Symbol ction ( put it on the operator stack with lowest possible priority ) Unstack and apply operators until "(" reached. Unstack but do not apply the "(" operand put on operand stack operator while ( priority(top-of-operator-stack) priority(input) ) unstack and apply the top-of-operator-stack. push the input onto the operator stack end of input If the operator stack is not empty, unstack and apply the stacked operators one by one. "pply an operator" means apply it to the top 2 items on the operand stack and replace them by the result of the operation (like we did in algorithm 1). Here is a trace of the algorithm on ( 6 4 ) 3 16 / 2 Input ( 6 4 ) 3 16 / 2 Operator / / Stack ( ( ( ( Operand Stack 6 6 4 6 10 10 3 10 30 16 30 16 30 2 16 8 30 30 38 omp 162 Notes Page 4 of 13 November 13, 2017
lgorithm 4: building a tree from an infix expression This algorithm is a variation on lgorithm 3. Like lgorithm it uses two stacks but instead of a stack of operands it uses a stack of pointers to tree nodes. Here are the actions for the four types of symbol: Symbol ction ( put it on the operator stack with lowest possible priority ) Unstack and apply operators until "(" reached. Unstack but do not apply the "(" operand create a binary tree node with the operand as the data item and nil in the two pointer fields. Push a pointer to this node onto the operand stack operator while ( priority(top-of-operator-stack) priority(input) ) unstack and apply the top-of-operator-stack. push the input onto the operator stack End of input If the operator stack is not empty, unstack and apply the stacked operators one by one. t the end: unstack and apply any operators remaining on the operator stack What does "apply" an operator mean in this algorithm? It means create a binary tree node with the operator as the data item and left and right pointers containing the pointer values in the top items on the operand stack. Then pop those two items and push a pointer to the new node. For example, efore fter 9-1 9-1 Operator Operand Operator Operand omp 162 Notes Page 5 of 13 November 13, 2017
When the algorithm terminates we should get a binary expression tree pointed to from the only item left on the operand stack. Example: Expression D Input: <empty> Input: omp 162 Notes Page 6 of 13 November 13, 2017
Input: Input: omp 162 Notes Page 7 of 13 November 13, 2017
Input: Input: omp 162 Notes Page 8 of 13 November 13, 2017
Input: D D t the end of input we unstack and apply the operators on the operator stack resulting in first. omp 162 Notes Page 9 of 13 November 13, 2017
D and finally, <empty> D omp 162 Notes Page 10 of 13 November 13, 2017
Error checking Here are some simple error checks we can add to lgorithm 4 to make it more robust 1. llowable sequences of symbols in the input Previous Symbol urrent Symbol ( ) Operator Operand ( OK Error Error OK ) Error OK OK Error Operator OK Error Error OK Operand Error OK OK Error 2. Parentheses. We can maintain a counter, initially zero, that is incremented whenever we read an opening parenthesis and decremented when we read a closing one. The counter should never go negative and must be zero at the end of the input. 3. Operator. In general an operator requires n operands. In our case we just have n=2. There should be at least n items on the operand stack when we apply the operator. Next we will see how to generate Pep/9 assembly code from the binary tree and consider algorithms for improving the raw output. Reading We are looking at an alternative to section 7.4. omp 162 Notes Page 11 of 13 November 13, 2017
Review Questions 1. For each of the following postfix expressions (a) indicate if it is well-formed (b) If it is well-formed, determine the value of the expression (i) 6 6 6 (ii) 6 6 6 6 (iii) 6 6 (iv) 6 6 6 2. For each of the following infix expressions, give a corresponding postfix (i) ()(D) (ii) D (iii) ( D) (iv) ( ( D)) 3. For each of the following, draw an appropriate expression tree (i) ()(D) (ii) D (iii) ( D) (iv) ( ( D)) omp 162 Notes Page 12 of 13 November 13, 2017
Review nswers 1. (i) Yes, 72 (ii) No (iii) No (iv) Yes, 42 2. (i) D (ii) D (iii) D (iv) D 3. (i) D (ii) D (iii) D (iv) D omp 162 Notes Page 13 of 13 November 13, 2017