130 likes | 218 Views
Homework 8 Functional Visitors in DJ. Use functional visitors to write a program that stores at each node in the abstract syntax tree the set of free variables . //Program.cd Program = NodeList .
E N D
Use functional visitors to write a program that stores at each node in the abstract syntax tree the set of free variables. • //Program.cd • Program = NodeList . • Node : lookahead (@ 2 @) AppNode | LetNode | lookahead (@ 2 @) AssignNode | look ahead (@ 2 @) AddNode| Term | ProcNode . • LetNode = "let" Bindings "in" NodeList . • AddNode = <a> Term "+" <b> Term . • Term : VarNode | LitNode . • VarNode = Ident . • LitNode = <v> int . • ProcNode = "proc" "(" [ FormalParameters ] ")" NodeList . • AppNode = Ident "(" [ ActualParameters ] ")" . • AssignNode = Ident "=" Node .
Bindings = List(Binding) . • Binding = Ident "=" Node . • FormalParameters = NList(FormalParameter) . • FormalParameter = Ident . • ActualParameters = NList(ActualParameter) . • ActualParameter = Node . • NodeList = "begin" List(Statement) "end" . • Statement = Node ";" . • NList(S) ~ S {"," S} . • List(S) ~ {S} .
begin //a let x = 1 y = 2 //a in begin proc(x,y) begin x+y; end; let h=3 //a, x, y in begin h = a(x,y); end; end; ll = 1; end
Functional Visitors • Enable functional-style computation combinations, which are desirable for a lot of recursive computation scenarios. • Object combine(Object[] values)specify the desired computation combination. • Enable the flexibility of users to control the traversal according to the computation of Visitor itself. • Object apply(String label) go down to the edge labeled as label and return the value from the sub traversal;
LetNode let h=3 in begin h = a(x,y); end; {h, a, x, y} – {h} + {} = {a, x, y} bindings nodelist Bindings NodeList * Binding Ident Node FreeVariables(LetNode) = (FreeVariables(NodeList) – Idents) + FreeVariables(Nodes)
Solution one /proj/demeter/com3362/w02/students/wupc] 1: dehg fine around method to class LetNode, Ident, LitNode, Binding, ProcNode, FormalParameter . 2. Use List to store free variables, and HashMap to store bindings
Solution two /proj/demeter/com3362/w02/students/lbenitez 1. Use a stack to store the nodes visited in the traversal, and a stack to store the bindings. 2. Define around method to class NodeList to compute free variables of the nodes in the node stack. 3. Define before and after methods to class LetNode, ProcNode to add a new binding field to the binding stack 4. Define before method to class Binding and FormalParameter to add a new binding to the current binding field 5. Define before method to subclasses of class Node to store the free variables of this node into the node stack.
Solution three • /proj/demeter/com3362/w02/students/qianyi • 1: define around methods to node classes, same as the solution one. Some are not necessary. • 2. Use HashSet store free variables and bindings
Test example begin let x = 1 y = 2 in begin proc(x,y) begin x+y; end; let h=3 in begin h = a(x,y); end; end; ll = 1; end
LitNode@60d49() • LitNode@5251a3() • VarNode@75d386(x) • VarNode@121f1d(y) • AddNode@38e059(x,y,) • NodeList@110040(x,y,) • ProcNode@2786c3(x,y,) • LitNode@88c0() • VarNode@122221(x) • VarNode@64f6cd(y) • AppNode@2bb514(x,a,y,) • AssignNode@7d5d2a(x,a,y,) • NodeList@6fa474(x,a,y,) • LetNode@15c083(x,a,y,) //2 • NodeList@11d8c1(x,a,y,) • LetNode@2d9c06(a,) //1 • LitNode@7b6889() • AssignNode@c2ff5() • NodeList@39240e(a,)
Caching aspect • Parent • Chind • Caching • Back • MyCaching • MyBack • FreeVariableCaching
Caching aspect • pointcut caching(Parent c): call(void universal_trv0(..)) && target(c); //?? • Question: When we use a functional visitor in a traversal, which method is called of every node visited by this visitor.