C ++での式の評価
-
20-08-2019 - |
質問
宿題用に、Excelに似たC ++コンソールアプリを作成しています。 私のアプリは、そのセルの数式を受け入れることができるはずです。たとえば、次のように評価する必要があります。
Sum(tablename\fieldname[recordnumber], fieldname[recordnumber], ...)
tablename\fieldname[recordnumber] points to a cell in another table,
fieldname[recordnumber] points to a cell in current table
または
Sin(fieldname[recordnumber])
または
anotherfieldname[recordnumber]
または
"10" // (simply a number)
そのようなもの。 関数は、Sum、Ave、Sin、Cos、Tan、Cot、Mul、Div、Pow、Log(10)、Ln、Modです
それは哀れなことですが、私の宿題です: '(
だから、誰かがこのようなことを評価するためのトリックを知っていますか?
解決
さて、いい宿題の質問。
これは実際にどれだけ重くするかによって異なります。完全な式パーサーを作成できます(これは楽しいですが、時間がかかります)。
そのためには、完全な文法を記述し、フロントエンドを記述する必要があります(lexとyaccまたはflexxとbisonを見てください。
しかし、あなたの質問を見ていると、3つのサブケースに制限することができます:
- 単純な値
- ルックアップ(おそらく他のテーブルへ)
- 入力がルックアップである関数
少しのオブジェクト指向設計がここで役立つと思います。
リアルタイムの更新と循環依存チェックを処理する必要があるかどうかはわかりません。そうでなければ、彼らもトリッキーになる可能性があります。
他のヒント
解析については、再帰降下解析を検討します。次に、可能なすべての関数名を関数ポインターにマップするテーブルを用意します。
struct FunctionTableEntry {
string name;
double (*f)(double);
};
パーサーを作成する必要があります。パーサーは式、つまり各行を取得し、コマンドを識別して解析ツリーを構築する必要があります。これが最初のフェーズです。 2番目のフェーズでは、コマンドの各要素をデータに置き換えることでツリーを評価できます。
以前のレスポンダーは頭でそれを打ちました。セルの内容を解析し、それらを解釈する必要があります。
StackOverflowには、リソースへのポインターを見つけることができるコンパイラーおよびインターパーターの構築に関する多数の質問が既にあります。それらのいくつかは次のとおりです。
- コンパイラの書き方を学ぶ(#1669人!)
- パーサー、インタープリター、およびコンパイラに関するリソースの学習
- コンパイルに役立つリソースは何ですか
- C / C ++でインタープリターを実装するために必要な参照
- ...
など。
さておき、私はそれらをすべて結びつけるエネルギー、または包括的なリストを作成しようとさえしません。
yacc / lexなどを使用できないので、<!> quot; manually <!> quot ;:
を解析する必要があります
文字列を反復処理し、その部分に分割します。一部が何であるかは、文法(構文)に依存します。そうすれば、関数名とパラメーターを見つけることができます。これの難しさは、構文の複雑さに依存します。
字句解析について少し読んでください。