Visitor Checklist in JavaCC

Ken Beesley, Xerox Research Centre Europe

2005

  1. Try a very simple grammar/language to begin with, such as a very simple arithmetic-expression parser. Concentrate on getting Visitors working.
  2. You have to write your grammar as a .jjt file, with instructions that build an Abstract Syntax Tree as the rules parse the input. Study the JJT Examples provided, starting with examples/JJTreeExamples/eg1.jjt, eg2.jjt, eg3.jjt and then (especially) eg4.jjt, which uses a Visitor. But don't ignore the earlier examples. You will not succeed with Visitors unless you understand and are skilled in JJTree.
  3. If the top-level rule of the grammar is Start(), then it should pass back (to the calling code in the main() method) a handle to an ASTStart node, being the root of the Abstract Syntax Tree. Let that handle be called n. eg1.jjt shows how you can use the built-in dump() method (i.e. we aren't into Visitors yet) to see if your grammar really is passing back the kind of AST you expect.
    	n.dump("") ;
    
    Build your AST trees and dump() them, before trying to implement Visitors, to make sure that you really are building ASTs correctly.
  4. Once you know that your grammar is producing and passing back a handle to a valid AST (seen in the output of the call to dump()) then you can think about writing Visitors to walk the tree and do whatever-it-is-you-really-want. eg4.jjt uses a visitor to dump the tree.
  5. The eg4.jjt example is the key:
  6. You might have several different kinds of Visitor objects, each implementing the same interface, for walking your AST trees and doing different things with the trees, e.g. you might have Then your main() method would look something like:
     public static void main(String args[]) {
        System.out.println("Reading from standard input...");
        eg4 t = new eg4(System.in);
        try {
          ASTStart n = t.Start();   // get a handle (n) to the root of the AST
          
          // instantiate an eg4DumpVisitor object
          eg4Visitor v = new eg4DumpVisitor();
          // process the tree, from the root, using the eg4DumpVisitor
          n.jjtAccept(v, null);
          
          // instantiate an eg4OptimizeVisitor object
          eg4Visitor w = new eg4OptimizeVisitor() ;
          // process the tree, from the root, using the eg4OptimizeVisitor
          n.jjtAccept(w, null);
          
          
          // instantiate an eg4InterpreterVisitor object
          eg4Visitor x = new eg4InterpreterVisitor() ;
          // process the tree, from the root, using the eg4InterpreterVisitor
          n.jjtAccept(x, null);
          
          
          System.out.println("Thank you.");
        } catch (Exception e) {
          System.out.println("Oops.");
          System.out.println(e.getMessage());
          e.printStackTrace();
        }
      }
    
    Of course, you are completely responsible for writing yourlanguageDumpVisitor.java yourlanguageOptimizeVisitor.java yourlanguageInterpreterVisitor.java but each will need to implement yourlanguageVisitor.java, the automatically generated interface.

Comments and corrections to this document would be appreciated. ken.beesley@xrce.xerox.com