ANTLR: How do I produce a tree with more than 2 children?
Given the grammar,
parse : expr EOF -> ^(ROOT expr);
expr : atom ('|'^ atom)*;
atom : LITERAL | ('('! expr ')'!);
LITERAL : 'a'..'z';
WS : (' '|'\t'|'\r'|'\n'){Skip();};
And input,
a|b|c
I get a tree that looks like,
http://graph.gafol.net/pic/dsqoQhzgs.png
Whereas I'd like a tree that looks lik开发者_C百科e,
http://graph.gafol.net/pic/dsrGWVUfz.png
How would I express that in the grammar?
It's a bit tricky. You could do it by using a syntactic predicate (LOOK-AHEAD-TOKENS-HERE)=>
before matching an "OR-chain":
expr
: (atom '|')=> atom ('|' atom)+ -> ^('|' atom+)
| atom
;
which properly handles a|b|c
, a|b
and a
.
But you might want to explain what language you're actually trying to parse: there might be better (more elegant?) ways to express it.
Why wouldn't you want to have an AST as in your first diagram? Evaluating expressions is easy when the root (operand) has only two children, right?
parse : expr EOF -> ^(ROOT expr);
expr : atom ('|'^ atom)* -> atom+;
atom : LITERAL | ('('! expr ')'!);
LITERAL : 'a'..'z';
WS : (' '|'\t'|'\r'|'\n'){Skip();};
I think this will do it by adding a rewrite rule but I don't have antlrworks right now so I can't be sure. But it's close so give it a shot and modify the rewrite syntax if necessary.
精彩评论