CS 2500 Programming Assignment
Information Hiding, Stacks, and Queues


DUE DATES:

THE ASSIGNMENT:

I am giving you complete code for stack classes and queue classes, plus part of a main program. The main program file is infix.shell.cpp. You must add code to infix.shell.cpp. When finished, the program will use a stack and queue to translate infix expressions to postfix expressions.

Here is an example of an input file:

 $  (T + Q/H - U*K) - (T-B) /L*A    $
  $  (A + B ) / ( C - D) $


  $ B * B - F * A * C /(T + A ) $
$ X * (X) + R - F / G $

$ X * (X + R - F / G $


Here is the output file corresponding to the input above:
Rule Number Table

Row corresponds to stack top.
Column corresponds to current input character.

    $   +   -   *   /   (   )

$   4   1   1   1   1   1   5
+   2   2   2   1   1   1   2
-   2   2   2   1   1   1   2
*   2   2   2   2   2   1   2
/   2   2   2   2   2   1   2
(   5   1   1   1   1   1   3

$ ( T + Q / H - U * K ) - ( T - B ) / L * A $ 
T Q H / + U K * - T B - L / A * -

$ ( A + B ) / ( C - D ) $ 
A B + C D - / 

$ B * B - F * A * C / ( T + A ) $ 
B B * F A * C * T A + / - 

$ X * ( X ) + R - F / G $ 
X X * R + F G / - 

$ X * ( X + R - F / G $ 
Bad Expression.
As you can see, the program first prints a table. You will be told more about the table later. Next the program reads an infix expression and writes it on the output. The program then, if possible, writes the translation of the expression. If the infix expression contains an error, it is not possible to make a translation. In that case the program writes the message "Bad Expression". This continues until all the infix expressions have been processed.

THE PROGRAM SHELL

Save a couple of copies of infix.shell.cpp. Save one copy as an original for reference. You must add some code to the other copy, to transform it into the solution to this programming assignment. Please read through infix.shell.cpp. You will see comments that tell you where to add code.

SKIPPING OVER WHITE SPACE

infix.shell.cpp, contains a function called findBlackSpace. You can add calls to findBlackSpace to solve any problems you have with skipping over white space.

IMPLEMENTATION OF THE STACK AND QUEUE

The assignment directory contains code modules that implement several versions of a stack and queue. There are scripts in the assignment directory and #include directives in infix.shell.cpp that work together to make it easy to change the implementation of stack and queue that your program uses.

You must not make any modifications to any of the stack, queue, or list modules. You must change only your copy of infix.shell.cpp. The code you add to your copy of infix.shell.cpp must be implementation independent. It must be written in such a way that it will continue to work if the code implementing the stack or queue is changed. This is very important. It will be a big factor in determining your grade on the program.

If you follow the principles of information hiding and encapsulation of data structures properly, then your program will work, with absolutely no changes, when you switch from one implementation of a stack or queue to another. How do you "follow the principles of information hiding and encapsulation of data structures"? Well, in this case, it means that to use the stack and queue, you declare the appropriate variables in your program and use the public functions of the class to do all your operations on the stack or queue. You are not allowed to add stack or queue implementation code to your main program or to copies of the stack and queue modules.

When you send me your program, you send me only the main program file you have written. I compile your program using my copies of the stack and queue modules. If you wrote the program correctly, it will work as well for me as it worked for you.

INPUT AND OUTPUT OF THE PROGRAM

The program must read only from standard input and write only to standard output. When I test your program I will use a prepared input file and indirection in the following manner:

a.out < infix.in > infix.out

Assume that the input will contain a series of infix expressions. Each expression will be on a line all by itself. Each variable in each expression will be a single upper case letter. The other meaningful symbols in expressions will be '$', '+', '-', '*', '/', '(', and ')'. The only other characters possible will be white space. The dollar sign ('$') will be the first and last symbol in every expression. Those two dollar signs will be the ONLY dollar signs in any expression. Any amount of white space is permitted to appear at any location in the input. Blank lines are permitted anywhere. There are no other rules about how the input must appear. You have to write the code of your program so that the program works correctly on ANY input that conforms to the rules above. You can do this by writing code that always makes a call to findBlackSpace before attempting to read a black space character.

See the sample input above, and create some good test input files for your own use in verifying that your program works.

ACTIONS OF THE PROGRAM

The program begins by writing the table of rule numbers it is using. This is just a way of allowing the user to check that the correct rule numbers have been recorded.

The method the program will use to translate infix formulas is due to E.W. Dijkstra, and is reported in Andrew Tanenbaum's book, "Structured Computer Organization".

There are just a few action rules for doing translations. This tends to make translation rather easy. However, one must decide which action rule to apply, and when to apply it. Most of the logic required to make such decisions is already built into the program shell (infix.shell.cpp) that I am giving to you, but you will have to add some more code to make it work. Directions for this are in the program shell.

The program employs a stack and queue. Before starting to translate each expression the program must make sure that both the stack and the queue exist and are empty. (I've taken care of this detail in the set up of the program shell -- a new stack and queue are created each time a new translation is done.) A translation always begins by reading the initial '$' and pushing it onto the stack. During translation, any *variable* read from the input is immediately put on the queue.

Let's agree to use the name "current symbol" for the black space character most recently read from the input. When the current symbol is NOT the initial dollar-sign, and is NOT a variable, the program consults a table in order to get the number of a rule to apply. The rule tells what the program must do next in order to go forward with the translation. The rule number lies in the ROW of the table corresponding to the symbol on the top of the stack, and the COLUMN of the table corresponding to the current symbol. Although there is a large number of combinations of stack top symbol and current symbol, there are only 5 rules. Here are the rules:

RULE 1. Push the current symbol onto the stack and read another black space character from the input.

RULE 2. Pop the stack and enqueue the symbol that comes out. Do NOT read a new black space character from the input.

RULE 3. Pop the stack and read another black space character. Do NOT save any characters, or put anything in the queue at this time.

RULE 4. Stop. The symbols now on the queue represent the postfix translation of the infix expression.

RULE 5. Stop. An error in the input has been discovered.

Read through your copy of infix.shell.cpp until you understand it well. Then add segments of code to finish it. I will be discussing some aspects of the program in class. Be sure to spend time reading your copy of infix.shell.cpp, otherwise you probably will not get much out of the class discussion.

The remaining details of how you implement this program are left to you. However, it should be done according to the rules of good programming you have learned, and the items printed should be formatted attractively and clearly.