antlr3 - Antlr AST generating (possible) madness -


Is the following possible? I want to "reverse" the input given to the antialar and want to make each token one child of the last one.

Then, for input (assuming each token is separated by '.'):

  stack.Overflow.Horse  

I want my grammar to generate the following diameter:

  Horses | --- So far, I have reversed the nodes, but I am unable to make them children of each other:  
  
 

Code> Function: ID Period Task - & gt; Function ID | Id; ID: 'a' .. 'z' *;

I do not think there is an easy way to do this. You can create your own rule in this way:

  Function: ID Period Task - & gt; ^ (Function ID) | Id;  

But it only makes the nodes root and all other nodes their children, for example, the following source:

  abcde  < / Pre> 

will result in the following tree:

  e / / \ \ Dcba  

When you first see abcde , a , then the recurring call on id and bcde function

  abcde | + ----- + | | | `----- & gt; Function | `---------- & gt; ID  

is generated by the fact that b.c.d.e will have a as its child. Then when b becomes id , it is also added as a child next to a . In your case, one should be removed as a child and then added to the b children's list but AAAAAC, which is not possible in ANLTR (less than Less, not cleanly inside grammar).


Edit

Well, around the work, I had something beautiful in my mind, but it does not work as I expected Was expressed. Therefore, as a less elegant solution, you can match the last node as the root in the rewrite rule:

  function: (id '.') * Last = id - & gt; ^ ($ Final); All possible predecessor nodes ( children ) in a  list  using  

and then the + operator. Gather:

Function: (children + = id '.') * Last = id - & gt; ^ ($ Final);

And in the root of your tree (going from left to right in your children to a custom parser Use the Member-method> List !):

  Function: (children + = id '.') * Last = id {reverse ($ children, (CommonTree) $ Last.tree);} - & gt; ^ ($ Final);  

Little Demo:

  Grammar reversal; Option {output = AST; } Token {root; } @memberers {Private zero cancel (list nodes, common routing root) {if (node ​​== blank) returns; For (int i = nodes.size () - 1; i> = 0; i--) {commontree temp = (commontree) nodes. Gate (i); Root.addChild (temporary); Root = temporary; }}} Paras: Function + EOF - & gt; ^ (Root function +); Function: (children + = id '.') * Last = id = reverse ($ children, (commontree) $$ last.tree);} - & gt; ^ ($ Final); I did; ID: ('A' .. 'Z' | 'A' .. 'Z') +; Space: '' {skip ();};  

and a little test class:

  import org.antlr.runtime *; Import org.antlr.runtime.tree *; Import org.antlr.stringtemplate *; Public class main {public static zero principal (string [] args throws exceptions {ANTLRStringStream = new ANTLRStringStream ("a.b.c.d.e. Stack.Overflow.Horse singleNode"); Reverse tree laser laser = new reverse strilexer (in); Common Token Stream Token = New Common Token Stream (Lexer); Reverse tree parser parser = new reverse tree parser (token); Reverse tripper.from_refund return value = parser.parse (); Common Tree Tree = (CommonTree) Return Value.getTree (); DOTTreeGenerator gen = New DOTTreeGenerator (); String template cents = gntotot (tree); Println (cents); }}  

which will create an AST that looks:

  • (generated by using image)

For input string:

  "Abcde Stack.Overflow.Horse singleNode"  

Comments