CS 453 Programming Assignment #4 — Parsing
Due Wednesday, March 26th (by 11:59pm)
late policy
Preliminary Subversion Log
Due Friday, February 29th (by 6:00pm)
see below
Introduction
For your last assignment, you created a description of the MiniJava tokens
and had JLex generate a lexer for them. For this
assignment you will write a description of MiniJava's
grammar for JavaCUP and have JavaCUP build a parser for the language.
Your goal is to describe a parser that constructs an abstract syntax
tree (AST) for the given MiniJava program. You will do this by first
specifying the grammar to JavaCUP and then associating actions to
each of the grammar productions so as to construct an AST. The AST data structure
will be provided.
Getting Started
As a starting point, download
MJParseToASTStart.tar.
MJParseToASTStart.tar provides you with the start of a MiniJava parser that is
capable of parsing and generating the AST for a limited set of expressions.
The directory structure is as follows:
MJParseToASTStart/
src/
ast/
analysis/
DepthFirstAdapter.java // depth-first traversal over ast nodes
...
node/
CallExp.java
IdExp.java
IExp.java
PlusExp.java
...
ast_visitors/
ParserDot.java // visitor that creates .dot file from AST
exceptions/
...
mjparser/
minijava.cup // grammar specification and actions
ParseDriver.java // driver that generates AST
TestCases/
exp1.test
exp2.test
Run ParseDriver on exp1.test and exp2.test. Visualize the generated .dot
files by using the program dot, which is explained in the
class setup notes.
The Assignment
Specify the full MiniJava grammar in minijava.cup. After the grammar has been
specified and tested to make sure it accepts any syntactically legal MiniJava program and rejects illegal programs, add actions in minijava.cup that
generate an ast. The
ast.nodes package contains all of the ast node implementations along with
appropriate constructors.
The .dot file generated by your parser will be compared to the one generated
by the reference parser, MJParseToAST.jar.
MJParseToAST.jar may be run in the usual way:
% java -classpath java-cup-11a-runtime.jar -jar MJParseToAST.jar AllTypes.java
Step 1: Specify the MiniJava Grammar
The grammar for MiniJava is online
here. It would be nice if you could just translate this into
something that JavaCUP can understand and be done with it.
Unfortunately, the grammar will need some modifications before it
adequately describes the language.
- The extended BNF operators '?' and '*' are not supported by JavaCUP. Therefore, you will have to modify the grammar so that it is equivalent, but only uses '|' and epsilon productions.
- Specify precedence and associativity for expressions by either rewriting the grammar
or by using the JavaCUP precedence construct.
For expressions,
use the following precedence, which is listed from lowest to highest
with operators and tokens listed on the same line having equal precedence:
- Exp && Exp
- Exp < Exp
- Exp + Exp, Exp - Exp
- Exp * Exp
- ! Exp
- Exp [ Exp ], Exp . length, Exp . id ( ExpList )
- INTEGER_LITERAL, false, true, this, id, new id (), new int [ Exp ], ( Exp )
Of the above operators, only the not(!) operator has right-to-left associativity.
It is possible to specify subsets of the full MiniJava grammar so as to
incrementally develop the grammar specification for JavaCUP.
For example, the MJParseToASTStart project includes a minijava.cup file
with a subset of possible expressions. The TestCases/ subdirectory includes
two test cases for this restricted grammar: exp1.test and exp2.test.
Step 2: Generating the AST
After the parser being generated accepts syntactically legal MiniJava programs,
it is time to add actions to the grammar for the construction of an abstract syntax tree. The AST is similar to the implicit parse tree, however it
does not keep tokens around unless the tokens contain useful information
(e.g. IDs and NUMBERS). See the minijava.cup file in MJParseToASTStart/src/mjparser/ to see some examples of how to generate an AST.
We will also be discussing AST construction in class.
References
Some JavaCUP Pitfalls
Here are some issues that you might run into with JavaCUP:
- The %prec directive appears to only be relevant when the same token
has different precedence in different context (e.g. unary minus).
When used in a more general fashion, it did not work. Fortunately, for the
MiniJava grammar, you won't have to use the %prec directive at all.
Submitting:
Preliminary Subversion Log
Assignment
-
Make sure you test your parser thoroughly — ensure that it
recognizes all syntactically legal MiniJava programs, and that it rejects syntactically illegal MiniJava programs.
You may either use your own Yylex.java file or the one provided.
You should test your finished parser on many sample programs and some files
with MiniJava programs that have type problems, but no syntactic problems.
- Create a jar file that contains all the source code, the .class files, the minijava.cup file, a README file, and a subversion.txt file. We should be able to use the jar file to run the ParseDriver class.
- Create a mainClass.txt file in MJParser-groupname/src/ with the following contents (make sure there is an newline after the second line in the file):
Main-Class: ParseDriver
Class-Path: java-cup-11a-runtime.jar
- Also put the subversion.txt and README files into the src/ subdirectory.
- While in the src/ subdirectory, do the following commands:
% javac -classpath .:mjparser/java-cup-11a-runtime.jar ParseDriver.java
% jar cmf mainClass.txt MJParser-groupname.jar *.class */*.class */*/*.class mjparser/minijava.* README subversion.txt
-
The README file should include your username(s), emails(s), and any
information you want the TA to have before grading your assignment.
e.g., this part is not working due to..., a favorite quote or joke
to amuse the TA, etc.
-
The subversion.txt file should include output from the following:
svn log
svn info
svnlook tree REPOSITORY_PATH svnlook must be issued on a department machine
Submit assignment using checkin utility
~cs453/bin/checkin PA4 MJParser-groupname.jar
Sanity Check (procedure TA will use to run your assignment):
% java -classpath java-cup-11a-runtime.jar -jar MJParser-groupname.jar filename.java
% mkdir MJParser-groupname/src/
% cd MJLexer-groupname/src/
% cp ../../MJParser-groupname.jar .
% jar xf MJParser-groupname.jar
Note that you need to have a copy of the java-cup-11a-runtime.jar file in the same directory as the MJParser-groupname.jar file. We will provide our own copy of the runtime jar file for testing. We will be running your parser on multiple test files. Also, the TA will be looking at the source files and possibly running JavaCUP on the minijava.cup file.
Late Policy:
Late assignments will be accepted up to 24 hours past the due date for a deduction of
20% and will not accepted past this period.
mstrout@cs.colostate.edu
.... February 24, 2008
Originally written by Brad Richards 2006,
modified with permission by Michelle Strout 2007.
Significantly rewritten and borrowed some from Sam Guyer's writeup of a similar assignment Michelle Strout 2008.