私は単純な数式パーサーを持っており、自分で AST を構築したいと考えています (ast パーサーがないことを意味します)。ただし、すべてのノードは 2 つのオペランドしか保持できません。したがって、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
)?
;
しかし、これにより再帰エラーが発生します。何か案は?