[antlr-interest] Capturing Line numbers

Thiago Arrais thiago.arrais at gmail.com
Sun Jan 29 09:23:43 PST 2006


Vijay,

2006/1/28, Vijay K. Ganesan <vijay at mindspring.com>:
> I'd like to invoke getLine() on the AST nodes to return the line number corresponding to
> the AST root's token. Currently it returns 0 always.

That should mean you are using the default AST node class, which is
CommonAST. Take a look at the getLine and getColumn methods (inherited
from BaseAST):

    public int getLine() {
        return 0;
    }

    public int getColumn() {
        return 0;
    }

> I believe I need to create my own
> AST class that extends BaseAST/CommonAST?

Yep. From the above code excerpt, we can see that using BaseAST and
CommonAST for node classes won't do. We'll need to have a subclass of
them that records the location info and properly informs it when
asked.

Maybe there is some other standard way to do that (maybe antlr already
has a class that does that), but you can achieve it by creating your
own, say, MyAST class and using the parser's setASTNodeClass method.
By the way, the docs say to use the setASTNodeType method, but it is
currently deprecated (meaning its use is discouraged).

That MyAST class will need to override the initialize, getLine and
setLine methods. Initialize is where things get recorded. You can
write something like:

	public void initialize(Token tok) {
		super.initialize(tok);
		setLocation(tok.getLine(), tok.getColumn());
	}

And setup the get methods accordingly.

After this, you'll need to tell the parser to use the new MyAST class,
instead of CommonAST, when creating the nodes. I have done this by
calling the setASTNodeClass method just after the creation of the
parser and before the call to the grammar root method. Code looked a
lot like this:

        MyParser parser = new MyParser(...);
        parser.setASTNodeClass("org.example.antlr.ast");
        parser.expr();
        AST root = parser.getAST();

Maybe there is a more elegant way to do that (for example, by
injecting the call to the method inside the parser or even setting a
parser option on the grammar file to do the trick). But, being a antlr
newbie, that's the way I got around it.

Hope this helps.

Cheers,

Thiago Arrais


More information about the antlr-interest mailing list