Previous Up Next

Chapter 15  Using Gom generated structures

15.1  Extending Gom generated structures

Problem:
I want to use Gom to generate a data structures, but I also need to use my own hand made containers for this structure, and I do want to use strategies to traverse the resulting trees.

Solution:
You have to extend the BasicStrategy provided by Gom to add support for your own containers. Then, you will be able to build strategies traversing both Gom and your containers by combining visitors.

Example:
We define in Gom how to describe points and lines:


module Plan
imports int
abstract syntax
Point = Point(abs:int, ord:int)
Comp = Line(p1:Point,p2:point)
     | Triangle(p1:Point,p2:Point,p3:Point)
And we want to add a Carre class, composed of two Line, but without using Gom. This class must implement the jjtraveler.Visitable interface to allow the use of strategies:

import plan.types.*;
public class Carre implements jjtraveler.Visitable {
  public Line l1;
  public Line l2;
  Carre(Line l1, Line l2) {
    this.l1 = l1;
    this.l2 = l2;
  }
  /* implements the Visitable interface */
  public int getChildCount() { return 2; }
  public jjtraveler.Visitable getChildAt(int index) {
    switch(index) {
      case 0: return l1;
      case 1: return l2;
      default: throw new IndexOutOfBoundsException();
    }
  }
  public jjtraveler.Visitable setChildAt(int index, jjtraveler.Visitable v) {
    switch(index) {
      case 0: l1=(Line)v; return this;
      case 1: l2=(Line)v; return this;
      default: throw new IndexOutOfBoundsException();
    }
  }
}


The last step to be able to define strategies over both Carre and the Gom structure is to define a new BasicStrategy, extending the one generated by Gom.
public class CarreBasicStrategy extends plan.PlanBasicStrategy {
  public CarreBasicStrategy(jjtraveler.reflective.VisitableVisitor v) {
    super(v);
  }
  public jjtraveler.Visitable visit(jjtraveler.Visitable v)
                                      throws jjtraveler.VisitFailure {
    if (v instanceof Carre) {
      return this.visit_Carre((Carre)v);
    } else {
      return super.visit(v);
    }
  }
  public Carre visit_Carre(Carre arg) throws jjtraveler.VisitFailure {
    return (Carre) any.visit(arg);
  }
}


It is then possible to define a strategy over the composed structure by extending this CarreStrategy.

See the TestCarre.t file in the gom example from the Tom distribution for a running example.


Previous Up Next