开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜