3

次のような式の論理式パーサーを作成しようとしています:((VariableA-> VariableB)AND NOT VariableC)パーサーは、変数の特定の値に対して結果がtrueかfalseかに関係なく、返すことができるはずです。

基本的に、式には変数、論理演算子(または、含意、等価、否定、括弧)のみが含まれます。

この種のパーサーを実装するための最良の方法は何ですか(ASTツリーまたは逆ポーランド記法を使用)?それとも、その仕事をすることができるいくつかのオープンソースパーサーがすでに存在しているのでしょうか?

4

6 に答える 6

2

どの言語をターゲットにしていますか?

パーサーを作成したい場合は、ANTLRがそのトリックをやってくれるかもしれません。もともとはJavaベースですが、さまざまな言語用のジェネレーターがあり(たとえば、C#パーサーの生成に使用します)、ピックアップするのはそれほど難しくありません。文法をテストできる素晴らしいエディタ(ANTLRWorks)があり、これは素晴らしいプラスです。

于 2009-05-05T20:27:05.807 に答える
1

私があなたならRPNを使います。これにより、構文解析の際の苦痛を軽減できます。また、アルゴリズムは、演算子が入ってくるときに値のスタックをプッシュおよびポップするのと同じくらい単純である必要があります。括弧を騙す必要もありません。これにより、作業が楽になります。唯一の本当の欠点は、ほとんどの人がpostfix(AKA RPN)表記に慣れていないことです。

スタックは、おそらくツリーよりも操作しやすいでしょう。

ちょうど私の2¢:)

于 2009-05-05T20:23:05.833 に答える
0

http://ncalc.codeplex.comを見たことがありますか?

拡張可能で高速 (独自のキャッシュがあるなど) であるため、EvaluateFunction/EvaluateParameter イベントを処理することにより、実行時にカスタム関数と変数を提供できます。解析できる式の例:

式 e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");

e.Parameters["Pi2"] = new Expression("Pi * Pi"); e.Parameters["X"] = 10;

e.EvaluateParameter += delegate(string name, ParameterArgs args) { if (name == "Pi") args.Result = 3.14; };

Debug.Assert(117.07 == e.Evaluate()); また、Unicode と多くのデータ型をネイティブに処理します。グラマーを変更したい場合は、antler ファイルが付属しています。新しい関数をロードするために MEF をサポートするフォークもあります。

于 2010-12-09T09:40:31.467 に答える
0

これを行うツール (論理評価) は既にあると思いますが、見つかりませんでした。Bison (YACC、C 用) やANTLR (多くの言語を生成しますが、Java を使用)などのツールを使用する場合、構文解析についてあまり心配する必要はありません。Coco/Rは、さまざまな言語を生成できるもう 1 つのパーサー ジェネレーターです。ただし、自分でやりたい場合は、RPNまたはプレフィックス表記を使用します(RPNよりも簡単だと思います)。これにより、解析がはるかに簡単になりますが、ユーザーを悩ませます。

于 2009-05-05T20:30:52.850 に答える
0

宿題のようですね :-)

まず、言語を再帰的に定義する必要があります。

変数は整形式 (WFF) です

X が WFF の場合、X は WFF ではありません

X と Y が WFF の場合、(X -> Y) は WFF です

X と Y が WFF の場合、(X AND Y は) WFF です

文法が定義されたら、LEX や Flex を使用するか、Java に相当するものを使用するか、自明なスキャナーを作成するための好みの言語を使用します。

子孫再帰パーサーを作成するには、YACC または Bison または同等のものを使用します。

後で再帰的な方法で評価したい式の評価を取得するために、文法に属性を追加します。

于 2009-05-05T20:35:22.747 に答える
0

Python で作業している場合は、 pyparsingを使用して記述されたこの式 parser/ evaluatorを開始点として試してください。

于 2010-08-27T09:22:19.983 に答える