[antlr-interest] Composite Tree Grammars are things of beauty, but ...

Gary Miller miller.garym at gmail.com
Tue Mar 8 19:57:14 PST 2011


Hi All,

First a bit of background.
I've been use AntLR for about the last year and the majority of that
has been "using it in anger".

A big thanks to Terrance and everyone else involved.

Hopefully I can help in my small way.
The application we are building used Google Web Toolkit and out of the
box AntLR 3.2 Java runtime is not GWT compatible.
This is a GWT issue, (for those of you who know GWT) a properly
constructed module definition file and some super-src are all that is
needed.
I have packaged this up at http://code.google.com/p/gwtified/,
hopefully this can make it way back into the AntLR source.

If anyone is interested in an example of what can be achieved with GWT
and AntLR, have a http://www.sumwise.com/templates.
AntLR to Java, then Java to JS via GWT is probably a better option
then AntLR to JS.


Now onto the beauty of Composite Tree Grammars.

Currently we use AntLR in a limited way and I'm hoping to refactor it
into more of our code.
To that end I have been playing with AntLR, to try understand THE BOOK
(ala Paul Erdös quote) way of using AntLR.
Also I have had people say to me "why don't you just program some
examples in Haskell or X" so the semantics are clear.
My feeling has been that I could get more clarity if I have a pure
tree grammar, one without actions.
The problem is that I did want to maintain multiple walker with the
only difference being the actions.
Here is where imports / composition comes to the rescue (well almost).

By way of example. I have a tree grammar called PureTreeWalker that
imo is pretty close to a perfect representation of a tree (if that not
request for comment I don't know what is).
Now I want to have a print walker that output a syntax representation,
The PureTreePrintWalker.g imports PureTreeWalker and adds actions
where necessary.

Here is the but ...
What would be even nicer would be if PureTreePrintWalker could call
directly into PureTreeWalker. see PureTreePrintWalker.g+.
This is valid AntLR, but the Java it produces has compile errors. By
creating an PureTreeWalkerEmpty.g that import PureTreeWalker but does
override any rules, I was able to merge and modify
PureTreePrintWalker_PureTreeWalker.java so that this works.

Any idea how hard it would be to add this "super calls" to the Java
target for Composite Tree Grammars?

Regards
Gary Miller


PureTreeWalker.g
================
/** This is the purist representation of the AST.
 * This tree grammar is imported (inherited) by the other
 * tree grammars that actually do the work. */
tree grammar PureTreeWalker;

/** Top of a Tree */
        treestruct  : ^(TREE (treenode)+) ;
/** Abstract node of a tree, either a subtree or a leaf */
treenode  : subtree   | leaf;
/** Subtree, has a root tree node and tree node children */  subtree
: ^(NODE root (treenode)+) ;
/** The root of a subtree */
     root  : ^(ROOT id);
/** Leaf, has no children */
     leaf  : ^(LEAF id);
/** An id */
            id  : ID ;


PureTreePrintWalker.g
================
tree grammar PureTreePrintWalker;

options {  tokenVocab=PureTreeParser;  ASTLabelType=CommonTree; }

import PureTreeWalker;

@header {
package puretree;
}

@members {
  IMTWriter writer;
  void setWriter(IMTWriter writer) {
    this.writer = writer;
  }

  void inc() { writer.indent_inc(); }
  void dec() { writer.indent_dec(); }
  void append( String s ) { writer.append( s ); }
  void nl() {  writer.nl(); }
}

statement
     : {append("TREE");}   treestruct       {nl();}
     | {append("NODE");}   subtree          {nl();}
     | {append("LEAF");}   leaf             {nl();}
;
//treestruct see PureTreeWalker
treenode  : {inc();} subtree {dec();}  | {inc();} leaf    {dec();};
//subtree see PureTreeWalker
root   : {nl();} ^(ROOT id);
leaf   : {nl();} ^(LEAF id);
id     : ID {append($ID.text);};



PureTreePrintWalker.g+
================
tree grammar PureTreePrintWalker;

options {  tokenVocab=PureTreeParser;  ASTLabelType=CommonTree; }

import PureTreeWalker;

@header {package puretree}

@members {
  IMTWriter writer;
  void setWriter(IMTWriter writer) {
    this.writer = writer;
  }

  void inc() { writer.indent_inc(); }
  void dec() { writer.indent_dec(); }
  void append( String s ) { writer.append( s ); }
  void nl() {  writer.nl(); }
}

statement
     : {append("TREE");}   treestruct       {nl();}
     | {append("NODE");}   subtree          {nl();}
     | {append("LEAF");}   leaf             {nl();}
;

//treestruct see PureTreeWalker
treenode  : {inc();} PureTreeWalker.treenode {dec();};
//subtree see PureTreeWalker
root   : {nl();} PureTreeWalker.root;
leaf   : {nl();} PureTreeWalker.leaf;
id     : ID {append($ID.text);};


More information about the antlr-interest mailing list