私はfunのための言語のようなjavascriptのためのコンパイラを書いています。別名私は車輪について学んでいるので、私は自分のために1つを作って、すべてを見つけようとしていますが、今は詰まってしまいました。メソッド呼び出しを後置記法に変換するには?
シンプルインミックス式を解析するとき、シャンティングヤードアルゴリズムは素晴らしいものです。私は接頭辞と接尾辞演算子に対してもこのアルゴリズムを拡張する方法を理解することができましたし、単純な関数を解析することもできました。例えば
:2+3*a(3,5)+b(3,5)
は2 3 <G> 3 5 a() * + <G> 3 5 b() +
になる(<G>
がスタックにプッシュされたガード・トークンであることは、リターンアドレスを格納するなど()
は、スタックの一番上の関数を呼び出す呼び出しコマンドであります引数の必要な量がポップアウトされ、返されたときに結果をプッシュバックします)。
関数名がただ1つのトークンであれば、その直後にかっこが付いていれば関数記号としてマークすることができます。プロセス中に関数シンボルが出たら、演算子スタックにプッシュし、パラメータの変換が終わったらポップアウトします。
これまでのところこれが動作しています。
ただし、メンバー関数を持つオプションを追加すると、.
演算子が使用されます。物事はもっとトリッキーです。例えば、a.b.c(12)+d.e.f(34)
を変換したいのですが、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)
。
これらのトリッキーな状況を簡単に処理する方法はありますか?
'.'は' + 'と同じように1つのトークンの演算子です。 – delnan
@delnanが正しいです。通常の演算子のようにドットを扱う必要があります。 – mahdix