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:

The Assignment

This assignment consists of several steps:
  1. You'll need your Stack class from earlier assignments.
  2. Build a class for BinaryTree (expression trees, not binary search trees). You can use the code from the slides.
  3. 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.)
  4. Recode the inorder traversal to add parentheses around subexpressions (but not leaf values).
  5. Use the code for evaluating a BinaryTree representing your expression (code is in the slides).
  6. Write a compiler for your expression language into a simple stack-based machine target language. The target language consists of the following operations:


    push valval is an integer literal, push val onto the stack
    addpop 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.
  7. 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).
  8. 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:
    1. generate a parse tree for the expression;
    2. print the expression from the parse tree using your inorder traversal with parentheses;
    3. evaluate the parse tree and print the result;
    4. compile the tree into an instruction list for our simple stack machine and print the instruction list;
    5. execute the instruction list using your interpreter and print the value left on top of the evaluation stack;
    6. 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