In class we've seen an interpreter for our language JayJay (Jay extended for extra control structures). But why waste all the work we've done already in writing a Jay interpreter? Since JayJay doesn't actually add any new functionality, we could write a JayJay interpreter merely by writing a translator from JayJay to Jay and slap it on top of the existing Jay interpreter. That's what you'll do in this project.
Once again I'm giving you the parser, syntax tree and abstract syntax tree classes,
and generic visitors for both the syntax trees and the abstract syntax trees.
What's different this time is that we have two
languages to deal with:
We have a parser for both Jay and JayJay, and similarly packages
jay
and jayjay
, each with their
syntaxtree
, visitor
, abssyntree
,
and astvisitor
subpackages.
You also get a lot of the tools we've developed earlier:
A ToASTVisitor
for each language (concrete syntax),
an InterpretingVisitor
for Jay (abstract syntax),
a PrettyPrintingVisitor
for Jay (abstract syntax),
a TypeCheckingVisitor
for Jay (abstract syntax),
and a PlainPrinter
(a visitor) for JayJay (abstract syntax).
(Sorry, not a JayJay pretty-printer; more of an ugly-printer--
I just didn't have time.)
All this is archived in a tar file. Copy the file from the class directory and untar it.
cp /cslab/class/cs365/proj5.tar . tar xvf proj5.tar
A driver program is also provided in Main.java
.
Once again you will have two options, but the one driver program
will handle both.
Your task is to write a visitor which, when applied to
a JayJay program represented as a jayjay.abssyn.Program
object, will produce an equivalent Jay program.
You will do this by finishing one of the skeleton classes,
jayjay.astvisitor.JayJay2JayVisitor1.java
or jayjay.astvisitor.JayJay2JayVisitor2.java
.
You have two options:
Option 1:
Finish writing jayjay.astvisitor.JayJay2JayVisitor1.java
,
which builds an object of type jay.abssyntree.Program
,
which it returns from the method getResult()
.
Option 2:
Finish writing jayjay.astvisitor.JayJay2JayVisitor1.java
,
which builds a String containing the equivalent Jay program as text,
which it returns from the method getResult()
.
So, the difference is, would you rather produce the abstract syntax, or the plain text of the resulting program? (The text option does not need to be pretty; it needs only to be parsable by the parser.) The reason I'm giving you two options is because I do not think one option is inherently harder than the other; they each have conveniences and inconveniences, and it's a matter of preference. Here are the pros and cons:
If you choose the text option, if will be easier to view your output for debugging purposes. If you choose the abstract syntax option, you still will be able to view your output because it can be processed by the Jay pretty-printer. However, this might be of limited help if your output causes the pretty-printer to crash.
If you choose the abstract syntax option, you will have to do a lot of package referencing and casting, just like you did in the concrete-to-abstract-syntax project. However, remember that those casts can be your friend, because it allows the compiler to catch many of your mistakes, and even wrong casts that are not detected until runtime will at least allow the VM to tell you what on what line you should start looking for the problem. In the text option, you won't have to make all those annoying casts, but your mistakes might be harder to trace.
As mentioned above, we have one driver program which handles both options. Use it with the following options:
--pjj
(Ugly-) print the JayJay program (this doesn't test anything
you wrote, but may help you understand how JayJay gets turned into abstract syntax)
--pj1
Use the Jay pretty-printer to print the
Jay abstract syntax you produce, if you choose option 1.
--pj2
Print the text you produce, if you choose option 2.
--i1
Interpret the resulting Jay program if you choose option 1.
What this really does is first sends the TypeCheckingVisitor over your Jay abstract syntax,
and if there are no type errors, it then sends the InterpretingVisitor over it.
--i2
Interpret the resulting Jay program if you choose option 2.
What this really does is feed your text output into the Jay parser to produce
a jay.syntaxtree
representation.
If it parses (which you probably won't get to happen on the first try), it will
then ToAST it, then type check it, and finally (if it type-checks correctly), interpret it.
I highly suggest that you implement the new language features one at a time and test them as you go. (If you haven't been writing your own test cases so far, you will certainly need to in this project; remember that sharing test cases with your classmates is encouraged.) More specifically, I suggest you first get for loops, do/while, and blocks-with-declarations working, since these have a lot in common and are relatively straight-forward. Then do switch statements, which are a little harder.
Extra credit.
The JayJay language grammar includes continue
statements
and general (in a loop, not a switch) break
statements.
They're pretty hard to implement.
They can be for extra credit.
Some details about the JayJay ToASTVisitor:
If a for loop has no initializer, then the equivalent instance variable
in
To turn in this project, please copy your
where "xxxxxx" is [andy|david|tyler|yelemis].
I will grade your project by running it against a collection of
test files.
DUE: Friday, Feb 29, 5:00 pm.jayjay.abssyntree.CountLoop
is null.
An empty guard is made into a boolean literal true
,
and an empty increment becomes a skip.
If a switch statement has no default case, then the
equivalent instance variable in jayajy.abssyntree.Switch
5. Turn in
JayJay2JayVisitor1.java
or JayJay2JayVisitor2.java
to the turn-in directory I will prepare for you:
/cslab/class/cs365/turnin/proj5/xxxxxx
Thomas VanDrunen
Last modified: Wed Feb 20 16:18:09 CST 2008