Hi all,
I'm trying to make an AST for a large and complex SQL grammar.
I've only done this before for simpler stuff as a learning experience, and that's not helping the with grammar I'm working with now.
The ANTLR book suggests three ways, of using an expression stack for evaluation (which I used instead to build an AST rather than directly evaluation), and using a listener to walk to parse tree and build the AST from that.
Using a listener with an expression stack method is fine for simple stuff but for the complexity of SQL, it gets pretty bad rather rapidly.
Using a listener with the annotation method is also not much fun because it divorces the code from the grammar and it becomes very easy to make mistakes (see <
https://groups.google.com/forum/?oldui=1#!topic/antlr-discussion/-jVVxzyVul4>).
The alternative, which I haven't tried, is to embed code into the grammar. It may not be elegant but it's certainly starting to look attractive. Does anyone have any experience with this, and any suggestions for or against it, for large and complex grammars?
Tangentially related question, I have a grammar that looks like this:
constant :
…
|
integer_const
|
decimal_const
…
;
But to get the correct node in the alternatives I have to do this:
public override void ExitConstant(LDBParser.ConstantContext cxt) {
if (cxt.integer_const() != null) {
var e = cxt.integer_const().eGet();
cxt.eSet(e);
} else if (cxt.decimal_const() != null) {
var e = cxt.decimal_const().eGet();
cxt.eSet(e);
} else ...
....
....
} else { assert(false, "failing in ExitConstant!!"); }
}
Perhaps I'm missing something, I can't see a way round this but it really looks awful, am I doing this the wrong way? (I can perhaps clean this up with lambdas and whatnot but I’m still fundamentally having to check each alt for nullness then extract from the non-null one, it’s just mucky)..
thanks
jan