次のように、中置方程式から構文ツリーに移動するアルゴリズムを理解しようとしています。
_(1+3)*4+5
_
_ +
* 5
+ 4
1 3
_
ただし、演算子を処理するだけでなく、任意の引数番号を持つ関数も処理する必要があります。
max(1,3,7)*4+5
_ +
* 5
max 4
1 3 7
_
ここに私が思いついた一般的なアルゴリズムがあります:
null
の値を含むツリーのルートノードから始めます。式を解析するときにツリー内を移動するポインターがあり、ルートノードを指すようにします。
また、ツリーのいくつかの側面を明確にしておく必要があります。
A
にインデックス0で子B
があり、インデックス__でノードC
を注入すると、ノードA
には子C
があり、これに子B
があります。A
を持つノードB
があり、インデックス0でC
を使用して置き換える場合、ノードA
と子C
があります。さて、ここまでがアルゴリズムです。
インフィックス文字列のすべてのトークンについて:
すべてのトークンを通過したら、ルートノードの最初の子を返します。
これをチェックできる既存のアルゴリズムはありますか?これに明らかな問題はありますか?これを使用して接続し、動作するかどうかを確認できる、特に解析が難しい問題はありますか?
コンマを中置演算子として扱います。その後
max(1,3,7)*4+5
なる
+
/ \
* 5
/ \
max 4
|
,
/ \
, 7
/ \
1 3
コンマの優先順位は、計算演算子よりも低くなければなりません(+-* /など)。
追跡するものが多すぎて境界のケースが多すぎるため、ある時点で適切なパーサーに卒業する必要があります。 peg.jsへの関数呼び出しの追加 example grammar を取得します。
primary
= integer
/ "(" additive:additive ")" { return additive; }
/ function_call
function_call
= [a-z]+ "(" args ")"
args
= (additive ("," additive)*)?
これは、関数呼び出しや関数呼び出し内にネストされた式などの境界ケースを簡単に処理することに注意してください。
max(3+4,min(6,(1+2)*3))+2