[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