2012-04-02 12 views
14

Cで簡単な数式表現パーサーを作るにはどうすればいいですか?数学関数を文字列から評価する

ユーザーは文字列に数学関数を入力し、文字列からはCで関数を作成します。 例: x + sin(2*x)

- 事前に>return x + sin(2x);

感謝。

+0

Bisonのドキュメントを見ると、あなたを導く[examples](http://www.gnu.org/software/bison/manual/html_node/Infix-Calc.html#Infix-Calc)があります。 –

+0

可能な複製http://stackoverflow.com/questions/1151127/evaluating-mathematical-expressions、[高速CまたはObjective-C数学パーサーとは何ですか?](http://stackoverflow.com/questions/4892152/what -is-a-fast-cまたはobjective-c-math-parser)、http://stackoverflow.com/questions/5115872/what-is-the-best-way-to-evaluate-mathematical-expression- in-c/5117028#5117028、http://stackoverflow.com/questions/4071456/opensouce-cc-math-expression-parser-library/4071701#4071701などがあります。 – lhf

+0

[TinyExpr](https://github.com/codeplea/tinyexpr)をお試しください。これは、単一のCソースコードファイルとヘッダーにあります。 – 131

答えて

6

"Shunting-Yard Algorithm" http://en.wikipedia.org/wiki/Shunting-yard_algorithmに基づいて式を解析できます。

+0

+1シャントヤードです。これは、処理できる解析タスクの正しいアプローチ(アルゴリズムの単純さ、スタックオーバーフローのリスクなし)です。 –

1

これを行う1つの方法は、式に逆ポーランド表記法を、オペランドにスタックを使用することです。 いくつかのクイックコード:

if element is operand 
    push in stack 
else if element is operation 
    pop last 2 elements 
    perform operation 
    push result in stack 

式の終わりまで繰り返します。最終結果はスタック内の唯一の要素です。

3

これはまったく簡単なことではありません。顔では難しいことです。あらかじめ定義された定数/関数(sinlogpiなど)と組み合わせて、完全な文法パーサーが必要です。

これまでの経験はあまりありませんでしたが、実際にこのようにしたいと思っているのであれば、これを行う最も簡単な方法はrecursive descent parsingです(逆研磨表記法)。

最後に、のC関数をユーザー生成入力から作成するとします。これはほとんど常に間違ったことです。ユーザー入力からコードを生成するのではなく、最も簡単なアプローチは、効率的に実行できる中間表現を作成するための前処理です。

+0

私はあなたが[BNF(Backus-Naur Form)](http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)を勉強しなければならないということになります。 – Eregrith

+0

簡単なことです。それは恐ろしいことではない、実際には非常にエレガントですが、決して簡単ではありません。再帰的なディーセントは最も簡単な方法です。演算子の優先順位は洗練されていますが、かなり複雑なものになります。 –

0

式パーサと評価関数を書くことは、ディスパーザパーサーがテクニックを書くときに使用される通常の例の1つです。 たとえば、flex/bisonやlex/yaccのドキュメントを見ることができます。これには、パーサ/式の評価者を構築する例があります。