CS 2213/2211
 Advanced Programming
 Spring 2005

 Recitation 9:  Reverse Polish and
   translation using a struct

    Week 9: Mar 22-24
 Due (on time): 2005-03-29  23:59:59
 Due (late):        2005-04-03  23:59:59

Recitation 9 should be submitted following directions at: submissions with deadlines
  • 2005-03-29  23:59:59 (that's Tuesday, 29 March 2005, 11:59:59 pm) for full credit.
  • 2005-04-03  23:59:59 (that's Sunday, 3 April 2005, 11:59:59 pm) for 75% credit.


Introduction: This recitation works on areas:


Overview: For this assignment you will write a program translate that will translate an ordinary arithmetic expression into reverse Polish notation (RPN). This program should be used in conjunction with a program evaluate that will find the final value of an input RPN expression expression. (I am having you write the evaluate program first because it is easier.) Together the two programs will find the value of an input arithmetic expression. In fact, for the final runs after initial testing, you can pipe the output of translate in as input to evaluate, so that you use the command:

The input source will be made up of the following elements:

This assignment limits to single-digit integer constants in order to keep things simpler.

For example, here is sample input arithmetic expression, which calculates one root of the equation y = x2 + 3x + 2:

This will be translated into RPN::

and then evaluated to produce the answer (the root) of -1.000000

Notice that all whitespace (= space, newline, tab, etc.) should be ignored on input.


Reverse Polish Notation (RPN): This is a simple parenthesis free and unambiguous notation in which operators follow their operands. Thus instead of 5+7, one writes 57+. In the simple examples in this recitation, each single digit is a separate operand, but that would not be the case in general. An RPN string is evaluated left to right. Each operator takes the two previous operands, and the result becomes a new operand. Thus the arithmetic expression 3+4*5 is translated to RPN as: 345*+. In evaluating this, the * applies to 4 and 5, giving 20, a new operand. Then the + applies to the 3 and the 20, to get 23. Similarly, the arithmetic expression 3*4+5 is translated to RPN as: 34*5+, and evaluated to get 17. Notice that in evaluating the arithmetic expressions, one needs to know that* has precedence over +, but the value of the RPN does not rely on this.

It is easy and natural to use a stack to evaluate RPN. The RPN string is processed item-by-item from left to right. An operand has its value pushed on a stack. An operator (all assumed to be infix with two operands here) causes its two operands to be popped off the stack, the operator is applied to these two operands, and the result is pushed onto the stack. If there are not two operands for an operator, that is an error, and at the end there should be a single operand on the stack.


A. Evaluate an RPN String: Here are the requirements for this part:

Requirements for Part A
  • Evaluate the string as a double.
  • Use a stack of doubles for the evaluation. The stack should be implements as a separate file, with a header file. You could partly mimic the stack of char that was presented earlier: Stack, but you should check that you don't pop an empty stack or push onto a full stack.
  • Use getchar() to read the input as a sequence of chars. Ignore whitespace.
  • Given a digit, you should read the digit as a char. Then you need to convert this, call it ch, to an int with the value of the digit. This can be done with (ch - '0'). Finally cast to a double and push onto the stack.
  • The RPN string 85-$ should evaluate to 3, so you must subtract the top element of the stack from the next-to-the-top element, and similar for division.
  • Implement the ^ operator with the C function pow. You will need the header <math.h> and a -lm as part of the compile command.
  • Print the final value of the RPN string as a double.
  • Test your evaluate program with the data in the "Table of Test Runs" near the end of this recitation.


B. Translate an Arithmetic Expression to RPN: This part is considerably more challenging than Part A. We will discuss this in class, so what follows in only an outline.

Requirements for Part B
  • Read a sequence of single-character items representing an input arithmetic expression, made up of just the characters mentioned above.
  • Use a stack of chars to push operators during the translation. This stack must be completely separate from the stack of doubles used for evaluation, with even the names of functions, such as empty() distinct.
  • Use the information in the section below titled "Precedence of Operators and Translation Rules" to see how to handle this precedence and how to carry out the translation.
  • Print the final RPN string with the $ at the end.
  • Test your translate program with the data in the "Table of Test Runs" near the end of this recitation.


Precedence of Operators and Translation Rules: The following table gives the precedence of operators, with 4 the highest. Under "Associativity", an L means "left-to-right" associativity. The entries for ( and ) as if they were operators will be explained below.

Precedence and Associativity Table
Operator Precedence Associativity
^4R
*3L
/3L
+2L
-2L
(1R
)1R

In order to handle precedence and associativity in your program, you must use a C struct like the following. One such struct variable can hold the information for one operator.

You must write a function getprec with prototype: struct prec getprec(char );. Inside this function you must have a static array of structs declared and initialized using curley bracket notation so as to hold the information in the above table. (If you are having trouble with this initialization, here is some help: Struct initializtion.) Given an input character representing an operator, the function getprec should look the operator up in the array and return the struct entry with the given operator as its first field. Then this information must be used in the program that carries out the translation.

Here are rules for the translation process:

Rules for translation to RPN
  1. Always output an operand (a single digit).
  2. Always push a left parenthesis.
  3. Always push an operator if the stack is empty, if an operator of lower precedence is on top, or if an operator of equal precedence is on top and right-to-left associativity applies.
  4. Otherwise pop and output the stacktop, and try rule 3 again.
  5. A left and a right parenthsis (right above left) on the stack are always simply deleted.
  6. Depending on how you handle the parentheses, when you get a right parenthesis, you may need to explicitly pop operators off the stack and send them to output until you get to a left parenthesis. (And both parentheses must be deleted.)
  7. A $ character terminates the current input. Empty any remaining operators on the stack to output. Output a $ and terminate the program.


Test Runs Here are test runs for the two programs:

Table of Test Runs
Input arithmetic expression Output reverse Polish Final value
2+3*4$ 234*+$ 14.000000000000
3*4+5$ 34*5+$ 17.000000000000
(2+3)*4$ 23+4*$ 20.000000000000
1+2+3+4$ 12+3+4+$ 10.000000
3^2^2^2$ 3222^^^$ 43046721.000000000000
((1)+(((2))))*((((3))))$ 12+3*$ 9.000000000000
(3*(2+4)/(5+1))-2$ 324+*51+/2-$ 1.000000000000
(5+3)^(2+1)^2$ 53+21+2^^$ 134217728.000000000000
2+3*4^5*6+7$ 2345^*6*+7+$ 18441.000000000000
((3^2-4*1*2)^(1/2)-3)/(2*1)$ 32^41*2*-12/^3-21*/$ -1.000000000000
((2-3)^((4+1)*5)/6-(2-4)*7)-8$ 23-41+5*^6/24-7*-8-$ 5.833333333333


Test runs for both programs piped together Here are test runs for the two programs: More test runs.


What you should submit: Refer to the submissions directions and to deadlines at the top of this page. The text file that you submit should first have Your Name, the Course Number, and the Recitation Number. The rest of the file should have the following in it, in the order below, and clearly labeled, including at the beginning the appropriate item letters: a, b, c, etc.

 Contents of email submission for Recitation 9:

Last Name, First Name; Course Number; Recitation Number.

a. Program source code for Part A, including evaluate.c, source code for the stack, and the source for the header file that goes with the stack.

b. Results of runs of the input data from the second column of the table "Table of Test Runs" above. In each case the output should be the value given in the third column.

c. Program source code for Part B, including translate.c, source code for the stack, and the source for the header file that goes with the stack. (A separate stack from part A.)

d. Results of runs of the input data from the first column of the table "Table of Test Runs" above. In each case the output should be the value given in the second column.

e. Results of runs for the extra test data linked to above.

Beware: Since the stacks are array based, you may need to increase their size to handle the runs in part e above.


Revision date: 2005-03-20. (Please use ISO 8601, the International Standard.)
Copyright © 2011, Neal R. Wagner. Permission is granted to access, download, share, and distribute, as long as this notice remains.