Lab 3: Abstract Syntax Trees

Lab Assigned Lab Due
(Start of class)
20 Feb 19 Mar


Abstract: You will gain experience with bottom-up parsing and the structure of the Java programming language by constructing abstract syntax trees.

More so than usual, you are advised to begin this assignment right away. There are design decisions to be made as well as expertise to be developed in the grammar-development cycle. For many students, beginning early on this lab can improve their final grade in this course by a letter! In student reviews of this course, the advice of beginning assignments early is often given.


Preliminaries

  1. You need to save some jar files in a reliable place on your computer: Make sure the jar files are really saved as a jar file, and not as a zip file.
  2. Download the hw3 zip file into a temporary place, and import it as an existing project into eclipse, just as you did for Lab 2.
  3. The ant build.xml file is now distributed without reference to ant tasks for CUP or JFlex. For some of us, those tasks were not working properly. CUP and JFlex are now launched via their jar files, so the build file should work everywhere with the modifications described in the file's comments.
  4. When you open the project, be sure to do the following, just as you had to do for Lab 2:
    Make the appropriate modifications to the build file, and try building and running the project (see ant tasks' descriptions, below) as distributed, as soon as possible, to avoid any infrastructure issues.
  5. In this lab, you are given jmm.cup, which is a CUP grammar for a subset of the Java language jmm , which stands for "Java minus minus".
    Browse through the file and familiarize yourself with the structure of this grammar. It is the only file you should modify, and it is the only file you are allowed to turn in.

Lab notes


Specifics

  1. For the rules present in jmm.cup, you are asked to design and implement an abstract syntax tree (AST). It is suggested that you first think about your design and sketch some possible layouts on paper prior to working at the computer. You could also run the class solution to get ideas about how to structure your AST. To help you implement the tree, the following factory methods are provided in the jmm.cup file; each instantiates a subclass of AbstractNode.
    makeNode(Symbol) Constructs an AST node, labeled by the Symbol supplied as input.
    This is useful where you want to take a rule such as:
    SelStmt ::= IF:ifterm LP Expr RP Stmt 
    and make an AbstractNode out of it by:
    AbstractNode ifnode = makeNode(ifterm); 
    makeNode(String) This is the recommended way to put nodes in the AST to show us the structure you want. In future labs, you'll want more refined subclasses of AbstractNode so you can put in specialized code for each node type, but for now, this kind of node is very useful.
    makeSibling(AbstractNode) is a method for class AbstractNodethat appends one or more sibling nodes. For example
     AbstractNode n1 = makeNode("SomeKindofNode");
     AbstractNode n2 = makeNode("AnotherKindofNode");
     n1.makeSibling(n2);
    
    makes n2 a sibling of n1.

    In general, if n1 is a node in the middle of sibling list1, and n2 is a node in the middle of sibling list2, then the above code would have the effect of appending list2 to list1.

    This method returns the rightmost sibling in the resulting sibling list.

    adoptChildren(AbstractNode) is a method for class AbstractNodethat brings a set of siblings under a parent. For example
     AbstractNode n1 = makeNode("Sib 1");
     AbstractNode n2 = makeNode("Sib 2");
     AbstractNode p  = makeNode("Boss");
     p.adoptChildren(n1.makeSibling(n2));
    
    makes p the parent of the siblings n1 and n2.
  2. To turn in your work, send your jmm.cup file as an attachment via email to legrand@cs.wustl.edu
    Be sure to fill in the header of the jmm.cup file with your name and the email address from which you are submitting your work.