CS313E Assignment 8--Trees and Languages (10 points)
Due: by Wednesday, 11/30/11
Your program listing should have the following information.
# File: Assignment6.py
#
# Description:
#
# Student's Name:
#
# Student's UT EID:
#
# Course Name: CS 313E
#
# Date Created:
#
# Date Last Modified:
- You must submit your .py files.
- Your .py file should have the header with the proper documentation.
- You should be submitting your .py file through the web based
turnin program. We will not accept files e-mailed to us.
- Your code must compile before submission.
The Assignment
This assignment consists of several steps:
- You'll need your Stack class from earlier assignments.
- Build a class for BinaryTree (expression trees, not binary search
trees). You can use the code from the slides.
- Use the algorithm for parsing a postfix expression into a
BinaryTree. You can assume that the expressions contain only integer
literals at the leaves and the operators *, +, -. You should
handle negative integers, but need not handle unary minus (i.e., it's
OK to have "-7" at a leaf, but you won't have "( - 7 )" as a subtree.
(Don't worry about handling division. We'd have to decide whether it
should be real division or integer division, and I don't want to
bother with that complication.)
- Recode the inorder traversal to add parentheses around
subexpressions (but not leaf values).
- Use the code for evaluating a BinaryTree representing your
expression (code is in the slides).
- Write a compiler for your expression language into a simple
stack-based machine target language. The target language consists of
the following operations:
| push val | val is an integer literal, push
val onto the stack
|
| add | pop two values from stack, add them and
push the result
|
| mult | like add, but multiply
|
| div | like add, but divide
|
| sub | like add, but subtract
|
The compilation of a tree should return the list of instructions for
this stack machine that will evaluate the tree and leave the result on
top of the stack. For example, if the tree contains only the leaf
with root value "7" you should return the list [ "push 7" ].
Otherwise, say the root of the tree contains "+". Then you'd return
the append of the three lists: compileExpr(tree.left()),
compileExpr(tree.right()), [ "add" ] . Instructions are not case
sensitive.
- Write an interpreter for the stack-based assembly
language. An interpreter takes a list of instructions and a state (in
this case an evaluation stack), and returns the result of executing
the instructions on the state. I'd suggest having an auxiliary method
step(inst, evalStack) that performs a single instruction. Your
interpreter function should be: execute(instList, evalStack).
- Finally, write a main program that repeatedly prompts the user to
input an postfix expression (using spaces to separate
tokens). With this expression, you should do the following:
- generate a parse tree for the expression;
- print the expression from the parse tree using your
inorder traversal with parentheses;
- evaluate the parse tree and print the result;
- compile the tree into an instruction list for our simple stack
machine and print the instruction list;
- execute the instruction list using your interpreter and print the
value left on top of the evaluation stack;
- exit the loop if the user enters "stop".
The values from step c. and from step e. should be the
same.
For heaven's sake, don't do it all before you run the program.
Test the pieces incrementally.
Sample Output
Enter a legal postfix expression with integers and
operators (+, +, -). Use blanks to separate tokens:
--> 2 3 4 +
Ill-formed expression
Enter a legal postfix expression with integers and
operators (+, +, -). Use blanks to separate tokens:
--> 2
You entered: 2
This expression has value: 2
This generates the following instructions:
['push 2']
Now running this instruction list,
which leaves the following value on the stack:
2
Enter a legal postfix expression with integers and
operators (+, +, -). Use blanks to separate tokens:
--> 2 3 +
You entered: ( 2 + 3 )
This expression has value: 5
This generates the following instructions:
['push 2', 'push 3', 'add']
Now running this instruction list,
which leaves the following value on the stack:
5
Enter a legal postfix expression with integers and
operators (+, +, -). Use blanks to separate tokens:
--> 2 3 * 4 5 * +
You entered: ( ( 2 * 3 ) + ( 4 * 5 ) )
This expression has value: 26
This generates the following instructions:
['push 2', 'push 3', 'mult', 'push 4', 'push 5', 'mult', 'add']
Now running this instruction list,
which leaves the following value on the stack:
26
Enter a legal postfix expression with integers and
operators (+, +, -). Use blanks to separate tokens:
--> 2 +
Ill-formed expression
Enter a legal postfix expression with integers and
operators (+, +, -). Use blanks to separate tokens:
--> +
Ill-formed expression
Enter a legal postfix expression with integers and
operators (+, +, -). Use blanks to separate tokens:
--> stop