[antlr-interest] Own Tree Class
Bart Kiers
bkiers at gmail.com
Mon Feb 14 12:07:20 PST 2011
On Mon, Feb 14, 2011 at 6:50 PM, Filip Habr <habr.filip at seznam.cz> wrote:
> Hello, can you help me somebody? I wrote ExpressionParser in ANTLR, which
> parse
> math expression to a tree. I was using CommonTree class as a target. Now I
> need
> to create my own tree class, because I have to create additional methods.
> Is
> there any way to create own tree class, which could be used by ANTLR
> grammar as
> a target tree class.
>
> options {
> language=CSharp2;
> output=AST;
> ASTLabelType=MY_OWN_CLASS;
> }
>
> Best help for me would be an advice, how to write class like CommonTree,
> because
> the code of CommonTree methods is not visible of course. Every class, i
> have
> written doesn't work. Thanks a lot!!!!
On Mon, Feb 14, 2011 at 6:50 PM, Filip Habr <habr.filip at seznam.cz> wrote:
> Hello, can you help me somebody? I wrote ExpressionParser in ANTLR, which
> parse
> math expression to a tree. I was using CommonTree class as a target. Now I
> need
> to create my own tree class, because I have to create additional methods.
> Is
> there any way to create own tree class, which could be used by ANTLR
> grammar as
> a target tree class.
>
> options {
> language=CSharp2;
> output=AST;
> ASTLabelType=MY_OWN_CLASS;
> }
>
> Best help for me would be an advice, how to write class like CommonTree,
> because
> the code of CommonTree methods is not visible of course. Every class, i
> have
> written doesn't work. Thanks a lot!!!!
>
>
Besides writing your own CommonTree subclass and adding `` to your
`options{...}` section, you should write your own CommonTreeAdaptor that
actually creates instances of your custom tree(s).
A little demo. Specifically note the lines that have `// !!!` after them:
// file://BooleExp.g
grammar BoolExp;
options {
output=AST;
ASTLabelType=BoolExpTree; // !!!
}
parse
: exp EOF -> exp
;
exp
: orExp
;
orExp
: andExp (Or^ andExp)*
;
andExp
: atom (And^ atom)*
;
atom
: '(' exp ')' -> exp
| True
| False
;
Or : 'OR' | '||';
And : 'AND' | '&&';
True : 'true';
False : 'false';
Space : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;};
// file://Main.java
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
public class Main {
private static void walk(BoolExpTree tree, int depth) {
if(tree == null) {
return;
}
for(int i = 0; i < depth; i++) {
System.out.print(". ");
}
System.out.println(tree);
walk(tree.left(), depth + 1);
walk(tree.right(), depth + 1);
}
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("true AND (false ||
true && (true OR false))");
BoolExpLexer lexer = new BoolExpLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
BoolExpParser parser = new BoolExpParser(tokens);
parser.setTreeAdaptor(new BoolExpTreeAdaptor());
// !!!
BoolExpParser.parse_return returnValue = parser.parse();
CommonTree tree = (BoolExpTree)returnValue.getTree();
walk((BoolExpTree)tree, 0);
}
}
class BoolExpTree extends CommonTree {
public BoolExpTree(Token token) {
super(token);
}
public BoolExpTree left() {
return super.getChildCount() > 0 ? (BoolExpTree)super.getChild(0) :
null;
}
public BoolExpTree right() {
return super.getChildCount() > 1 ? (BoolExpTree)super.getChild(1) :
null;
}
@Override
public String toString() {
return "BoolExpTree[" + super.toString() + "]";
}
}
class BoolExpTreeAdaptor extends CommonTreeAdaptor {
@Override
public Object create(Token token) {
return new BoolExpTree(token);
}
}
When generating a lexer/parser, compiling all .java source files, and
running the main class:
java -cp antlr-3.2.jar org.antlr.Tool BoolExp.g
javac -cp .:antlr-3.2.jar *.java
java -cp .:antlr-3.2.jar Main
you will see the following output:
BoolExpTree[AND]
. BoolExpTree[true]
. BoolExpTree[||]
. . BoolExpTree[false]
. . BoolExpTree[&&]
. . . BoolExpTree[true]
. . . BoolExpTree[OR]
. . . . BoolExpTree[true]
. . . . BoolExpTree[false]
Regards,
Bart.
More information about the antlr-interest
mailing list