Computer Languages - Homework 3 |
---|
Deadline thursday february 11 at 9.00 a.m.. |
Purpose |
---|
These computer based exercises should help you understand when shift-reduce conflicts can arise and how to solve some of them. You should also be able to use jacc to better understand the consequences of a conflict. You will also learn how to implement abstract syntax trees and you will use jacc to generate abstract syntax. You will see a simple example of the visitor pattern.
Conflicts |
---|
Where we use jacc to describe grammars, generate the push-down automata and follow the workings of the parser. |
jacc -pt if.jacc -r a test fileSee to it that the test file (in the right format, with tokens!) contains the example we discussed in the lecture, where the conflict is apparent.
A x; B myB; x = exp; myB = exp; y = exp;The jacc specification methodDec.jacc is an implementation of the grammar for this kind of body in a method declaration.
jacc -pt methodDec.jacc
jacc -pt methodDec.jacc -r test.mdwith test.md. What happens? Explain! You might want to use the generated machine to see if you can get the example accepted by making other choices than the parser does. To generate the machine you have to do
jacc -h methodDec.jacc
Abstract Syntax |
---|
Where we use jacc to generate abstract syntax and we define a little visitor for calculating values boolean expressions. |
%{ import syntaxtree.*; %}at the beggining of your jacc specification.
package visitor; import syntaxtree.*; public interface Visitor < A, Env >{ A visit(BooleanLiteral x, Env e); A visit(Id x, Env e); A visit(And x, Env e); A visit(Or x, Env e); A visit(Not x, Env e); }(Notice: see to it that you use the names of YOUR abstract syntax classes in the arguments to the methods visit!)
The idea is that different operations on boolean expressions will be implemented by redefining these visit methods in new classes.
public < A, B > A accept(Visitor < A, B > v, B b){return v.visit(this,b);}and you will have to define an abstract variant of the method in your abstract class for the category of boolean expressions.
package visitor; import syntaxtree.*; public class Evaluator implements Visitor < Boolean,java.util.HashMap < String, Boolean > >{ public Boolean visit(BExp x, java.util.HashMap < String, Boolean > e){ return x.accept(this,e); } public Boolean visit(BooleanLiteral x, java.util.HashMap < String,Boolean > e){ return x.v; } public Boolean visit(Id x, java.util.HashMap < String,Boolean > e){ return e.get(x.id); } public Boolean visit(And x, java.util.HashMap < String,Boolean > e){ return x.left.accept(this,e) && x.right.accept(this,e); } public Boolean visit(Or x, java.util.HashMap < String,Boolean > e){ return x.left.accept(this,e) || x.right.accept(this,e); } public Boolean visit(Not x, java.util.HashMap < String,Boolean > e){ return !(x.bexp.accept(this,e)); } }Do you understand why we need the method accept defined the same way in all abstract syntax classes? Try instead to do the recursive calls using visit directly. What happens? Why?
Submission |
---|
Who should submit? What should be submitted? How to submit? When? |