まず、私は私が知っていることを知っています。この質問は以前にも何度か聞かれたことがありますが、他のトピックに関する回答のほとんどは、私の質問に部分的にしか答えていません。
Cのような式を解析できる何かをやっています。これには、たとえば次のような式が含まれます(いくつかの例)
1) struct1.struct2.structarray[283].shd->_var
2) *((*array_dptr)[2][1] + 5)
3) struct1.struct2.struct3.var + b * c / 3 % 5
問題は...私はこれを速くする必要があります。コードが醜くなったとしても、可能な限り最速 - 明らかに、速度の向上は具体的なものでなければなりません。その理由は、解釈されているからです。それは速くする必要があります...
質問がたくさんありますが、あなたの回答によっては、さらに質問するかもしれません。でもとにかく...
まず、「オペレーターの優先順位」を認識しています。たとえば、C コンパイラに実装されたアルゴリズムは、演算子に優先順位番号を割り当て、それに基づいて式を評価します。この表を参照しました: http://en.wikipedia.org/wiki/Operators_in_C_and_C++#Operator_precedence
さて、これはクールですが...いくつか疑問があります。私の主な質問は...どのようにこれを実装して、可能な限り最速にしますか?
たとえば、次のことを考えました... (私が話しているプログラムは、これらの式を含むファイルを実際に解析することに注意してください。すべての C 演算子がサポートされるわけではありません)
1) 式文字列を配列にストックし、各演算子の位置を配列内に格納してから、優先度の最も高い演算子から始めて、このがらくたすべてを解析し始めます。たとえば、str = "2*1+3" があった場合、存在するすべての演算子をチェックした後、str[1] の位置をチェックし、左右のチェックを行い、演算を実行します (ここでは乗算)。次に、式を結果に置き換えて、再度評価します。
私が見る問題は... exprの2つの演算子が同じ優先度であると言います
例: var1 * var2 / var3 / var4
* と / はどちらも優先順位が同じなので、解析を開始する位置を知るにはどうすればよいでしょうか? もちろん、この例はかなり直感的ですが、巨大な式で問題が大きくなる可能性があります。
2)これは非再帰的に行うことさえ可能ですか? 通常、再帰的とは、複数の関数呼び出しが独自のスタック フレームを設定したり、再初期化したりするなどの理由で遅くなることを意味します。
3) 単項演算子と非単項演算子を区別する方法は?
例: 2 + *a + b * c
逆参照演算と乗算演算があります。直感的にどうすればいいかは思いつきますが、よくわかりません。私はむしろこれについてあなたのアドバイスをしたいと思います(私は思う:右または左のメンバーの1つが演算子であるかどうかを確認します。そうであれば、それは単項ですか?)
4) 式が右から左に評価されません。どうも不自然なようです。それが何を意味するのか、私には理解できません。例を示していただけますか?どうしてそんなことを!?
5) 頭の中でより良いアルゴリズムを持っていますか? それを達成するためのより良いアイデアはありますか?
今のところ、それは私が考えていることのほとんどを要約しています。ちなみにこれは宿題ではありません。実用的なものです。
ありがとう!