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

Terence Parr parrt at cs.usfca.edu
Wed Mar 9 16:39:24 PST 2011


Hi Gary,
Thanks for your excellent explanation of your issue. Turns out that you can in fact secretly use x.y to refer to rule y in grammar x in some cases. In this case, ANTLR optimized away the super rule.

treenode  :  PureTreeWalker.treenode ;

ANTLR technically doesn't expose x.y syntax to the user and so I didn't recognize the fact that you invoked the super rule.  It extracted only those rules from your super grammar that it needed. It does this so that you can fill up libraries of grammars with rules and then pick out which ones you want without bloating your generated code.

That said, I am adding an improvement request for consideration.

http://www.antlr.org/jira/browse/ANTLR-452

I'd like to retract or how ANTLR it handles imports anyway.

Ter

On Mar 8, 2011, at 7:57 PM, Gary Miller wrote:

> 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);};
> 
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address



More information about the antlr-interest mailing list