鉴于语法,
parse : expr EOF -> ^(ROOT expr);
expr : atom ('|'^ atom)*;
atom : LITERAL | ('('! expr ')'!);
LITERAL : 'a'..'z';
WS : (' '|'\t'|'\r'|'\n'){Skip();};
输入,
a|b|c
我得到一棵看起来像的树,
http://graph.gafol.net/pic/dsqoQhzgs.png
虽然我想要一棵看起来像的树,
http://graph.gafol.net/pic/dsrGWVUfz.png
我如何在语法中表达这一点?
答案 0 :(得分:1)
这有点棘手。在匹配“OR-chain”之前,您可以使用syntactic predicate (LOOK-AHEAD-TOKENS-HERE)=>
来执行此操作:
expr
: (atom '|')=> atom ('|' atom)+ -> ^('|' atom+)
| atom
;
正确处理a|b|c
,a|b
和a
。
但您可能想要解释一下您实际尝试解析的语言:可能有更好(更优雅?)的表达方式。
为什么你不想在第一张图中有AST?当根(操作数)只有两个孩子时,评估表达式很容易,对吗?
答案 1 :(得分:0)
parse : expr EOF -> ^(ROOT expr);
expr : atom ('|'^ atom)* -> atom+;
atom : LITERAL | ('('! expr ')'!);
LITERAL : 'a'..'z';
WS : (' '|'\t'|'\r'|'\n'){Skip();};
我认为这会通过添加重写规则来实现,但我现在没有antlrworks,所以我不能确定。但是它很接近,所以如果有必要,可以试一试并修改重写语法。