私は楽しみのために言語のような JavaScript のコンパイラを書いています。別名、私はホイールについて学んでいるので、自分用にホイールを作成し、すべてを見つけようとしていますが、今は行き詰まっています.
単純な中置式を構文解析する場合、分路アルゴリズムが優れていることはわかっています。前置演算子と後置演算子についてもこのアルゴリズムを拡張する方法を理解することができ、単純な関数を解析することもできました。
例:2+3*a(3,5)+b(3,5)
に変わります2 3 <G> 3 5 a () * + <G> 3 5 b () +
(<G>
はスタックにプッシュされるガード トークンであり、戻りアドレスなどを格納します。()
必要な量の引数をポップアウトし、戻り時に結果をプッシュするスタックの一番上にある関数を呼び出す call コマンドです。)
関数名が 1 つのトークンにすぎない場合は、その直後に括弧を付ければ関数シンボルとして簡単にマークできます。プロセス中に関数シンボルに遭遇した場合は、それをオペレーター スタックにプッシュし、パラメーターの変換が終了したときにポップアウトします。
これはこれまでのところ機能しています。
しかし、メンバー関数を持つオプションを追加すると、.
演算子. 物事はよりトリッキーになります。たとえば、とは関数a.b.c(12)+d.e.f(34)
であるため、 I can't mark c と f を関数に変換したいとします。このような式でパーサーを開始すると、結果はどちらが明らかに間違っているかになります。私はそれが正しいように見えることを望みます。しかし、括弧をいくつか追加すると、事態をより複雑にすることができます。または、もう一度呼び出す関数を返す関数を作成します。a.b.c
d.e.f
a b . <G> 12 c () . d e . <G> 34 f () .
<G> 12 a b . c . () <G> 34 d e . f. ()
(a.b.c)()
f(a,b)(c,d)
これらのトリッキーな状況を処理する簡単な方法はありますか?