[antlr-interest] add new support methods in BaseTree?

Terence Parr parrt at cs.usfca.edu
Wed Oct 22 17:17:48 PDT 2008


Ok, to TreeParser, I have added the methods below...want to try it  
out?  I tried this:

CREATE TREE FROM SOME INPUT

         String input =
             "x = 3+4\n" +
             "print x * [2, 3, 4]";

         VecMathLexer lex = new VecMathLexer(new  
ANTLRStringStream(input));
         CommonTokenStream tokens = new CommonTokenStream(lex);
         VecMathParser g = new VecMathParser(tokens);
         g.setTreeAdaptor(myadaptor);
	    VecMathParser.prog_return result = g.prog();
	    CommonTree tree = (CommonTree)result.tree;
         System.out.println(tree.toStringTree());

PRINTS

(= x (+ 3 4)) (print (* x (VEC 2 3 4)))

USE TREEWIZARD TO GRAB THE 3 NODE DOWN DEEP

         TreeAdaptor adaptor = new CommonTreeAdaptor();
         String[] tokenNames = g.getTokenNames();
         TreeWizard wiz = new TreeWizard(adaptor, tokenNames);
         Map labels = new HashMap();
         boolean valid = wiz.parse(tree.getChild(1), "(PRINT (MULT ID  
(VEC INT %x:INT INT)))", labels);
         System.out.println("labels: "+labels);

PRINTS

labels: {x=3}

CREATE DUMMY WALKER SO WE CAN USE inContext METHOD

         CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
         MyWalker p = new MyWalker(nodes);
         boolean ctx = p.inContext(labels.get("x"), "PRINT ...  
VEC ...");
         System.out.println("inContext: "+ctx);

PRINTS

inContext: true

So, in a grammar, you can say:

	{inContext("METHOD ... VARDECL")}? ID

which means "only match an ID if it's parent is VARDECL and there is a  
METHOD ancestor".  Cool, eh?

Ter

-------------------

     /** "METHOD ... VARDEF" "CLASS VARDEF"  */
     public boolean inContext(String context) {
         return inContext(input.LT(1), context);
     }

     public boolean inContext(Object t, String context) {
         String[] tokenNames = getTokenNames();
         String[] nodes = context.split("\\s");
         int ni = nodes.length-1;
         TreeAdaptor adaptor = input.getTreeAdaptor();
         t = adaptor.getParent(t);
         while ( ni>=0 && t!=null ) {
             if ( nodes[ni].equals("...") ) {
                 // walk upwards until we see nodes[ni-1] then  
continue walking
                 if ( ni==0 ) return true; // ... at start is no-op
                 String goal = nodes[ni-1];
                 Object ancestor = getAncestor(t, goal);
                 if ( ancestor==null ) return false;
                 t = ancestor;
                 ni--;
             }
             String name = tokenNames[adaptor.getType(t)];
             if ( !name.equals(nodes[ni]) ) {
                 //System.err.println("not matched: "+nodes[ni]+" at  
"+t);
                 return false;
             }
             // advance to parent and to previous element in context  
node list
             ni--;
             t = adaptor.getParent(t);
         }

         return true;
     }

     public Object getAncestor(Object t, String goal) {
         String[] tokenNames = getTokenNames();
         TreeAdaptor adaptor = input.getTreeAdaptor();
         while ( t!=null ) {
             String name = tokenNames[adaptor.getType(t)];
             if ( name.equals(goal) ) return t;
             // advance to parent and to previous element in context  
node list
             t = adaptor.getParent(t);
         }
         return null;
     }




More information about the antlr-interest mailing list