ANTLR:我如何制作一棵有两个以上孩子的树?

ANTLR:我如何制作一棵有两个以上孩子的树?,antlr,Antlr,根据语法 parse : expr EOF -> ^(ROOT expr); expr : atom ('|'^ atom)*; atom : LITERAL | ('('! expr ')'!); LITERAL : 'a'..'z'; WS : (' '|'\t'|'\r'|'\n'){Skip();}; 和投入, a|b|c 我有一棵树看起来像 而我想要一棵看起来像 我该如何用语法来表达呢 parse : expr EOF -> ^(RO

根据语法

parse   : expr EOF -> ^(ROOT expr);
expr    : atom ('|'^ atom)*;
atom    : LITERAL | ('('! expr ')'!);

LITERAL : 'a'..'z';
WS      : (' '|'\t'|'\r'|'\n'){Skip();};
和投入,

a|b|c
我有一棵树看起来像

而我想要一棵看起来像

我该如何用语法来表达呢

parse   : expr EOF -> ^(ROOT expr);
expr    : atom ('|'^ atom)* -> atom+;
atom    : LITERAL | ('('! expr ')'!);

LITERAL : 'a'..'z';
WS      : (' '|'\t'|'\r'|'\n'){Skip();};
我想这可以通过添加重写规则来实现,但我现在没有antlrworks,所以我不能确定。但是它很接近,所以给它一个机会,如果必要的话修改重写语法

我想这可以通过添加重写规则来实现,但我现在没有antlrworks,所以我不能确定。但它很接近,所以请尝试一下,必要时修改重写语法。

这有点棘手。您可以在匹配“或链”之前使用
(LOOK-AHEAD-TOKENS-HERE)=>

正确处理
a | b | c
a | b
a

但您可能想解释您实际要解析的语言:可能有更好(更优雅?)的表达方式

为什么您不想在第一个图表中使用AST?当根(操作数)只有两个子项时,计算表达式很容易,对吗?

这有点棘手。您可以在匹配“或链”之前使用
(LOOK-AHEAD-TOKENS-HERE)=>

正确处理
a | b | c
a | b
a

但您可能想解释您实际要解析的语言:可能有更好(更优雅?)的表达方式


为什么您不想在第一个图表中使用AST?当根(操作数)只有两个子项时,计算表达式很容易,对吗?

这不起作用:不能在规则中混合使用
^
->
。如果从
expr
中删除
^
,它将无法正确解析单个
文本。试试看,糟糕透了。。。我刚刚想到了类似的东西,
atom(“|”atom)*->^(“|”atom+|
时,code>工作得很好,但正如巴特所说,否则它会失败。这是行不通的:你不能把
^
->
混合在一条规则中。如果从
expr
中删除
^
,它将无法正确解析单个
文本。试试看,糟糕透了。。。我刚刚想到了类似的东西,
atom(“|”atom)*->^(“|”atom+|
时,code>工作得很好,但正如巴特所说,否则它就会失败。如果你把
*
改成
+
,你就不能不提前看一下吗?我正在解析正则表达式。我认为将所有备选方案作为兄弟姐妹会更容易,因为我想随机选择一个。如果它们像第一个AST一样嵌套在二叉树中,
c
将有50%的几率被选中,另外两个将有25%,而我希望每个都有33%。。。除非用户使用括号。对不起,
*
必须是
+
(编辑我的答案)。但不,那么在该规则中仍然有一个非LL(*)决定。试一试,如果你还没有这样做的话。我必须100%同意巴特的最后一段。第一个AST完全有意义,而你想用它做什么却没有意义。如果你把
*
改成
+
,你就不能不提前看一下吗?我正在解析正则表达式。我认为将所有备选方案作为兄弟姐妹会更容易,因为我想随机选择一个。如果它们像第一个AST一样嵌套在二叉树中,
c
将有50%的几率被选中,另外两个将有25%,而我希望每个都有33%。。。除非用户使用括号。对不起,
*
必须是
+
(编辑我的答案)。但不,那么在该规则中仍然有一个非LL(*)决定。试一试,如果你还没有这样做的话。我必须100%同意巴特的最后一段。第一个AST完全有意义,而你想用它做什么却没有意义。这也使得它更难理解。
expr
  :  (atom '|')=> atom ('|' atom)+ -> ^('|' atom+)
  |  atom
  ;