Dynamische logische Ausdruck Analyse/Bewertung in C# oder VB?
Was das beste war, um einen Ausdruck auszuwerten, wie die folgenden:
(A Und B) Oder (A Und C) Oder (Nicht B Und C)
oder
(A && B) || (A && C) || (!B && C)
Zur Laufzeit, ich war in der Planung die Umwandlung der obigen Ausdrücke die folgenden Schritte aus:
(Wahr Und Falsch) Oder (Wahr Und Falsch) Oder (Nicht False Und True)
oder
(True && False) || (True && False) || (! False && Wahr)
Bedingungen:
1) Der logische Ausdruck erst zur Laufzeit bekannt ist.
2) Die Anzahl Variablen und deren Werte erst zur Laufzeit bekannt.
3) Variable Werte sind nie null.
Ich weiß, ich könnte das erstellen einer einfachen montieren mit einer Klasse und einer Methode, die ich zur Laufzeit generieren, basierend auf den Eingaben, aber gibt es einen besseren Weg.
Ich habe dies getan, bevor. Verwenden Sie ein string-generator den code zu schreiben, dann rufen Sie den compiler. Nach, dass Sie die assembly geladen und rufen Sie die Methode.
Vorschläge?
Dank.
- Was versuchen Sie zu erreichen? Können Sie teilen, wie Sie kommen, um die Vergleiche? Das sieht aus wie etwas, das vielleicht besser anders angegangen.
- Sieht aus wie eine Liste von Dingen zu vergleichen. Man könnte die Iteration der Liste aus, und brechen, wenn Sie finden, dass alle zwei wahr sind.
- Sie schreiben, könnte eine einfache Aussagenlogik Logik-parser... ich erinnere mich daran, dass zu einem lösen der Wumpus-Welt-problem.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie .NET3.5 Sie können dann analysieren Sie den text und erstellen Sie eine abstrakte sytax Baum mithilfe der Expression-Klassen. Dann erstellen Sie eine geeignete LambdaExpression Beispiel und kompilieren Sie es in eine zu delegieren, die Sie ausführen können.
Konstruktion einer parser und syntax tree builder für diese Art von relativ einfachen Grammatik ist durchaus eine interessante übung, die ausgeführt wird, etwas schneller als das aufrufen der compiler (und es ist übersichtlicher in meiner Ansicht).
Wenn Sie Sie nicht verwenden .NET3.5, dann ist es auch nicht kompliziert zum implementieren einer interpretierten abstract syntax tree selbst.
Seien Sie gewarnt: die letzten beiden Bedingungen, die du sprichst, sind nicht notwendigerweise äquivalent. Die && Operatoren in C# wird short-circuit Auswertung, während die logische
And
- operator in VB nicht. Wenn Sie sicherstellen möchten, dass die Aussagen äquivalent sind, übersetzen ein BenutzerAnd
zuAndAlso
und ein BenutzerOr
zuOrElse
.Für einfache expresssions Sie wahrscheinlich nicht einen Unterschied feststellen. Aber wenn die Bedingungen, die Nebenwirkungen haben können oder wenn der performance-Unterschied zwischen den beiden ist ein Anliegen, das wichtig sein kann.
Können Sie dies leicht tun mit:
Die Grammatik sieht wie folgt aus:
Bewerten, tun Sie dies:
Für Symbole, die Sie haben zu ersetzen, die dem Wahrheitswert zur Laufzeit.
Können Sie https://github.com/mrazekv/logicalparser
Einfach seine Bibliothek zu schreiben, die logischen Ausdruck (evaulated mit precenednce Tabelle erlaubt ODER NICHT, UND-operator und der >, >=, <=, < auf integer-Variablen und = auf string-Variablen)
Können Sie schreiben einen einfachen interpreter/parser. Verwenden Sie so etwas wie ANTLR und die Wiederverwendung der vorhandenen Grammatiken.
Wenn Sie mit .NET 3.5, die Sie erstellen können einen Lambda-Ausdruck. Dann erstellen Sie einen Delegaten aus und rufen Sie als standard-Delegierte/- Methode.
Auf dem internet ist eine Menge von Proben über Lambda-Ausdrücke.
Eine Lösung wäre, montieren Sie den Ausdruck als string, und dann schicken Sie es SQL Server, oder was auch immer Ihre Datenbank wird für die Auswertung. Ersetzen Sie die tatsächlichen Variablen mit 1=1 oder 0=1 für True und False sind, und Sie würden am Ende mit einer Abfrage wie diese:
SELECT 1 WHERE (1=1 Und 0=1) Oder (1=1 Und 1=1) Oder (Nicht 0=1 Und 1=1)
Dann, wenn Sie die Abfrage ausführen, erhalten Sie eine 1 zurück, wenn das Ergebnis wahr ist. Vielleicht nicht die eleganteste Lösung, aber es funktioniert. Eine Menge Leute werden wahrscheinlich abraten, aber ich bin einfach nur werfen es da draußen eine mögliche Lösung sowieso.
Wird dies nicht die beste Antwort, aber ich selbst hatte dieses problem vor einiger Zeit.
Hier ist mein Alter code:
VB.Net - keine Garantie!
https://cloud.downfight.de/index.php/s/w92i9Qq1Ia216XB
Dieser code isst einen String mit mehreren '(', ')', 'und', 'oder' plus 'anderem' und bricht die Logik, um einen boolean-durch den Austausch der Dinge, die mit booleschen Werten.
daher:
Was auch immer "anderen Dinge", die ich bewerten wollte, musste ich in der Funktion resolveTerm()
bei dem Kommentar "'funktionen ausführen und zurückgeben, einzelwert!"
auf Seite 2.
Es die einzige Bewertung rightnow ist ", Wenn die Zahl > 1"
Grüße
Werfen Sie einen Blick auf meine Bibliothek, Proviant. Es ist eine .NET-Standard-Bibliothek, die mit der Rangierbahnhof-Algorithmus zur Auswertung boolescher Ausdrücke.
Könnte es erzeugen auch eine Wahrheit-Tabelle für Ihre Ausdrücke.
Könnte man auch implementieren, Ihre eigene Grammatik.