Question

Le mieux était d’évaluer une expression comme celle-ci:
(A et B) ou (A et C) ou (pas B et C)
ou
(A & Amp; & Amp; B) || (A & Amp; & Amp; C) || (! B & Amp; & Amp; C)

Au moment de l'exécution, je prévoyais de convertir les expressions ci-dessus en suivantes:
(Vrai et faux) ou (vrai et faux) ou (pas faux et vrai)
ou
(True & Amp; & Amp; False) || (True & Amp; & Amp; False) || (! False & Amp; & Amp; True)

Conditions: 1) L'expression logique n'est pas connue avant l'exécution. 2) La variable numérique et leurs valeurs ne sont pas connues avant l'exécution. 3) Les valeurs de variable ne sont jamais nulles.

Je sais que je pourrais créer un assemblage simple avec une classe et une méthode que je génère au moment de l'exécution en fonction des entrées, mais existe-t-il un meilleur moyen? Je l'ai fait avant. Utilisez un constructeur de chaînes pour écrire le code, puis appelez le compilateur. Après cela, vous chargez l'assembly et appelez la méthode.

Des suggestions?

Merci.

Était-ce utile?

La solution

Si vous utilisez .NET3.5, vous pouvez analyser le texte et créer un arbre de syntaxe abstrait à l'aide des classes Expression. Créez ensuite une instance LambdaExpression appropriée et compilez-la en un délégué que vous pourrez ensuite exécuter.

Construire un générateur d'analyseur syntaxique et de syntaxe pour ce type de grammeur assez simple est un exercice assez intéressant, qui s'exécutera un peu plus rapidement que d'appeler le compilateur (et, à mon avis, plus ordonné également).

Si vous n'utilisez pas .NET3.5, implémenter soi-même un arbre de syntaxe abstraite interprété n'est pas compliqué.

Autres conseils

Soyez averti: les deux conditions finales dont vous parlez ne sont pas nécessairement équivalentes. Le & Amp; & Amp; Les opérateurs en C # utiliseront l’évaluation par court-circuit, contrairement à l’opérateur logique And en VB. Si vous voulez vous assurer que les instructions sont équivalentes, traduisez un utilisateur AndAlso en Or et un utilisateur OrElse en <=>.

Pour les expressions simples, vous ne remarquerez probablement pas de différence. Mais si les conditions peuvent avoir des effets secondaires ou si la différence de performance entre les deux est une préoccupation, cela peut être important.

Vous pouvez le faire facilement avec:

  1. un générateur d'analyseur (comme ANTLR, mentionné ci-dessus) qui prend en entrée des expressions booléennes et produit une liste d'infixes et
  2. code permettant d'évaluer une pile de notation polonaise inversée.

La grammaire ressemble à quelque chose comme ceci:

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); }
    ;

Pour évaluer, procédez comme suit:

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()

Pour les symboles, vous devez substituer la valeur de vérité au moment de l'exécution.

Vous pouvez utiliser https://github.com/mrazekv/logicalparser

.

Il s'agit simplement d'une bibliothèque pour écrire une expression logique (avec une table de précérnance, permet à l'opérateur OR, NOT, AND et > ;, > =, < =, < sur les variables entières et = sur les variables chaîne)

Vous pouvez écrire un interpréteur / analyseur simple. Utilisez quelque chose comme ANTLR et réutilisez les grammaires existantes.

Si vous utilisez .NET 3.5, vous pouvez créer une expression Lambda. Vous pouvez ensuite créer un délégué et appeler en tant que délégué / méthode standard. Sur Internet, vous trouverez de nombreux exemples sur les expressions Lambda.

Une solution serait d’assembler l’expression sous forme de chaîne, puis de l’envoyer à SQL Server, ou à l’évaluation de votre base de données. Remplacez les variables réelles par 1 = 1 ou 0 = 1 pour True et False, respectivement, et vous obtiendrez une requête semblable à celle-ci:

CHOISISSEZ 1 WHERE (1 = 1 et 0 = 1) ou (1 = 1 et 1 = 1) ou (pas 0 = 1 et 1 = 1)

Ensuite, lorsque vous exécutez la requête, vous obtenez un 1 lorsque le résultat est vrai. Peut-être pas la solution la plus élégante, mais cela fonctionnera. Beaucoup de gens vont probablement déconseiller cela, mais je vais tout simplement en faire une solution possible.

Ce ne sera pas la meilleure réponse, mais j’ai moi-même eu ce problème il ya quelque temps.

Voici mon ancien code: VB.Net - pas de garantie du tout!

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

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

Ce code mange une chaîne avec plusieurs '(', ')', 'et', 'ou' plus 'autres choses' et décompose la logique en un booléen en remplaçant les choses par des valeurs booléennes. donc:

Peu importe ce que je voulais évaluer, je devais mettre dans function resolTerm () au commentaire & "; funktionen ausf & # 252; hren und zur & # 252; ckgeben, einzelwert! &"; en page 2. Là, la seule évaluation à présent est & Quot; Si nombre est & Gt; 1 & Quot;

Salutations

Consultez ma bibliothèque, Proviant . Il s’agit d’une bibliothèque .NET Standard utilisant l’ l’algorithme Shunting Yard pour évaluer les expressions booléennes.

Il pourrait également générer une table de vérité pour vos expressions.

Vous pouvez également implémenter votre propre grammaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top