Computer Programming II
Lab Project #3b - Infix to Postfix with the Boxcar Algorithm
(Original version of the project by Prof. J. Saraille, CSUS)
PROBLEM:
You are to write a program in C++ that converts expressions written in
infix notation to postfix (known as RPN).
This project must use the stack and queue ADT code that you developed
for project 3a. Include this code as
two separate files, stack.h and queue.h using the #include preprocessor
directive.
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:
Infix: $ ( T + Q / H - U * K ) - ( T - B ) / L * A
$
Postfix: T Q H / + U K
* - T B - L / A * -
Infix: $ ( A + B ) / ( C - D ) $
Postfix: A B + C D - /
Infix: $ B * B - F * A * C / ( T + A ) $
Postfix: B B * F A * C
* T A + / -
Infix: $ X * ( X ) + R - F / G $
Postfix: X X * R + F G
/ -
Infix: $ X * ( X + R - F / G $
Postfix: Bad
Expression.
In addition to the above, the program should also print out the rules
table defined at the end of this specification just for your own debugging
purposes. The program reads an infix
expression from an input text file and writes it to an output text file. 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.
DESIGN
You must hand in a design detailing your data structures used to
implement a stack and a queue. You
don't need to write algorithms for the functions that manipulate the stacks and
the queues. Your DETAILED documentation
for the main portion of the project must be handed in as comments at the top of
your program.
IMPLEMENTATION
Make sure you use typedefs of structs for your stack and queue elements.
Build your code well and make it flexible with error-checking and full use of
typedefs and #define macros.
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 ')'. All other characters must be treated as 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. See the sample input above, and create some
good test input files for your own use
in verifying that your program works.
THE BOXCAR ALGORITHM
The method the program will use to translate infix formulas is called the
boxcar algorithm and is credited to E.W. Dijkstra. 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 fairly simple, but
to write working code requires the talent of visualizing the abstractions of
stacks and queues clearly in one's mind.
The program employs a stack and queue. Before starting to translate each expression
the program makes sure that both the stack and the queue exist and are empty. A translation always begins by reading the
initial '$' and pushing it onto the
stack. During translation, any
variable read from the input is
immediately enqueued.
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 rule numbers.
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.
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
DELIVERABLES
The required design can be handed in separately from your source
code. The source file and sample runs
should be on hardcopy and should follow our class coding and testing standards.