我有一个简单的数学表达式解析器,我想自己构建 AST(意味着没有 ast 解析器)。但是每个节点只能保存两个操作数。所以 2+3+4 会产生这样的树:
+
/ \
2 +
/ \
3 4
问题是,我无法让我的语法师进行递归,这里只是“添加”部分:
add returns [Expression e]
: op1=multiply { $e = $op1.e; Print.ln($op1.text); }
( '+' op2=multiply { $e = new AddOperator($op1.e, $op2.e); Print.ln($op1.e.getClass(), $op1.text, "+", $op2.e.getClass(), $op2.text); }
| '-' op2=multiply { $e = null; } // new MinusOperator
)*
;
但在一天结束时,这将产生一棵树,如:
+
/ \
2 4
我知道问题出在哪里,这是因为“添加”可能永远不会或无限地发生(*),但我不知道如何解决这个问题。我想到了类似的东西:
“添加”部分:
add returns [Expression e]
: op1=multiply { $e = $op1.e; Print.ln($op1.text); }
( '+' op2=(multiply|add) { $e = new AddOperator($op1.e, $op2.e); Print.ln($op1.e.getClass(), $op1.text, "+", $op2.e.getClass(), $op2.text); }
| '-' op2=multiply { $e = null; } // new MinusOperator
)?
;
但这会给我一个递归错误。有任何想法吗?