10

次のような式を評価するのが最善でした:
(A And B) Or (A And C) Or (Not B And C)
or
(A && B) || (A && C) || (!B && C)

実行時に、上記の式を次のように変換することを計画していました:
(True And False) Or (True And False) Or (Not False And True)
or
(True && False) || (真 && 偽) || (! 真偽)

条件: 1) 論理式は実行時まで不明です。2) number 変数とその値は、実行時までわかりません。3) 変数値が null になることはありません。

入力に基づいて実行時に生成するクラスとメソッドを使用して単純なアセンブルを作成できることはわかっていますが、より良い方法はありますか。私は前にこれをやったことがあります。文字列ビルダーを使用してコードを記述してから、コンパイラを呼び出します。その後、アセンブリを読み込み、メソッドを呼び出します。

提案?

ありがとう。

4

9 に答える 9

8

.NET3.5 を使用している場合は、テキストを解析し、Expression クラスを使用して抽象構文ツリーを作成できます。次に、適切な LambdaExpression インスタンスを作成し、それをデリゲートにコンパイルします。これを実行できます。

この種の非常に単純なグラマー用のパーサーと構文ツリー ビルダーを構築することは、非常に興味深い作業であり、コンパイラーを呼び出すよりもいくらか高速に実行されます (また、私の見解では、その方が優れています)。

.NET3.5 を使用していない場合は、解釈された抽象構文ツリーを自分で実装することも複雑ではありません。

于 2008-12-08T17:15:03.140 に答える
5

注意してください: あなたが話している 2 つの最後の条件は、必ずしも同等ではありません。C# の && 演算子は短絡評価を使用しますがAnd、VB の論理演算子は使用しません。ステートメントが同等であることを確認したい場合は、ユーザーを に変換し、ユーザーをAndに変換します。AndAlsoOrOrElse

単純な式の場合、おそらく違いに気付かないでしょう。ただし、条件によって副作用が発生する可能性がある場合、または 2 つのパフォーマンスの違いが懸念される場合は、これが重要になる可能性があります。

于 2008-12-08T17:16:29.380 に答える
3

https://github.com/mrazekv/logicalparserを使用できます

論理式を記述するための単純なライブラリ (優先順位テーブルで評価され、OR、NOT、AND 演算子、および >、>=、<=、< 整数変数で、および = 文字列変数で) を許可します)

于 2012-12-01T07:48:49.310 に答える
3

これは次の方法で簡単に実行できます。

  1. ブール式を入力として受け取り、中置リストを生成するパーサー ジェネレーター (前述の ANTLR など) と、
  2. 逆ポーランド記法スタックを評価するコード。

文法は次のようになります。

program: exprList ;

exprList: expr { Append($1); }
    | expr OR exprList { Append(OR); }
    | expr AND exprList { Append(AND); }
    | NOT exprList { Append(NOT); }
    | ( exprList ) { /* Do nothing */ }
    ;

expr: var { Append($1); }
    | TRUE { Append(True); }
    | FALSE { Append(False); }
    ;

評価するには、次のようにします。

for each item in list
    if item is symbol or truth value, push onto RPN stack
    else if item is AND, push (pop() AND pop())
    else if item is OR, push (pop() OR pop())
    else if item is NOT, push (NOT pop())

result = pop()

シンボルの場合、実行時に真理値を代入する必要があります。

于 2008-12-08T20:33:20.853 に答える
0

これは最良の答えではありませんが、私自身、この問題を少し前に抱えていました。

これが私の古いコードです: VB.Net - 保証は一切ありません!

https://cloud.downfight.de/index.php/s/w92i9Qq1Ia216XB

Dim BoolTermParseObjekt As New BoolTermParse
MsgBox(BoolTermParseObjekt.parseTerm("1 und (((0 oder 1 und (0 oder 4))) oder 2)").ToString)

このコードは、複数の '(', ')', 'and', 'or' と 'other things' を含む String を食べ、boolean 値に置き換えることで論理を boolean に分解します。したがって:

私が評価したい「その他のもの」は何でも、「'funktionen ausführen und zurückgeben, einzelwert!」というコメントに Function resolveTerm() を入れる必要がありました。2ページ目。今のところ唯一の評価は「If number is > 1」です。

ご挨拶

于 2016-04-25T16:48:06.480 に答える
0

1 つの解決策は、式を文字列としてアセンブルし、それを SQL Server または評価用のデータベースに送信することです。True と False の実際の変数をそれぞれ 1=1 または 0=1 に置き換えると、次のようなクエリになります。

SELECT 1 WHERE (1=1 かつ 0=1) または (1=1 かつ 1=1) または (0=1 かつ 1=1 ではない)

その後、クエリを実行すると、結果が true の場合に 1 が返されます。最もエレガントなソリューションではないかもしれませんが、うまくいきます。多くの人はおそらくこれに反対するでしょうが、私は可能な解決策としてそれを投げ出すつもりです.

于 2008-12-08T17:24:00.253 に答える
0

.NET 3.5 を使用している場合は、ラムダ式を作成できます。次に、それからデリゲートを作成し、標準のデリゲート/メソッドとして呼び出すことができます。インターネット上には、ラムダ式に関するサンプルがたくさんあります。

于 2008-12-08T17:18:21.823 に答える
0

簡単なインタープリター/パーサーを作成できます。ANTLRなどを使用して、既存の文法を再利用します。

于 2008-12-08T17:12:59.807 に答える