[antlr-interest] rooting a parser rule rather than a token
Eric Mahurin
eric_mahurin at yahoo.com
Wed Aug 11 11:59:06 PDT 2004
I'm not sure why, but antlr doesn't currently allow you to make a call
to a rule from another rule an AST root. So, you can't do something
like this:
binary_expression : primary (binary_operator^ primary)* ;
I haven't yet dove into the antlr code generation to completely fix
this issue, but you can get around this issue with these changes:
1. Instead of using "^" to root the rule, discard it using "!" and
then put in this action: {astFactory.makeASTRoot(currentAST,
returnAST);}. For example, the above rule would become:
binary_expression : primary (
binary_operator! {astFactory.makeASTRoot(currentAST, returnAST);}
primary
)* ;
2. If your rule you want to root contains more than one token and it
can be at the beginning of the rule calling it, there is a bug in the
routine makeASTRoot in ASTFactory.java. Change "currentAST.child =
currentAST.root;" to "currentAST.child = root.getFirstChild();" to fix
the problem. I did this in a copy of ASTFactory.java in my local
antlr directory instead of changing the source.
3. This simple fix doesn't handle the case where the the rule you want
to root is a list of 2 or more tokens (i.e. has 2 or more tokens and
is unrooted). I can't think of a case where you'd want to root such a
rule, but if you did want to do this, make these changes in
ASTFactory.java:
a. In addASTChild, change "currentAST.root.setFirstChild(child);" to:
currentAST.child = currentAST.root;
currentAST.advanceChildToEnd();
currentAST.child.setFirstChild(child);
b. In makeASTRoot, change "currentAST.child = currentAST.root;" to:
currentAST.child = root;
currentAST.advanceChildToEnd();
currentAST.child = currentAST.child.getFirstChild();
These changes *should* be backwards compatible. It also allows you to
make AST's that have separate left and right/normal children pointers
to preserve token order.
Anybody want to figure out how to antlr code generation do the right
thing for using "^" with a rule instead of a token? It's probably
trivial.
I have more AST suggestions, so expect another message...
Eric
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/antlr-interest/
<*> To unsubscribe from this group, send an email to:
antlr-interest-unsubscribe at yahoogroups.com
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
More information about the antlr-interest
mailing list