Laden...

Parser für Bedingungen

Erstellt von chilic vor 8 Jahren Letzter Beitrag vor 8 Jahren 2.008 Views
C
chilic Themenstarter:in
2.121 Beiträge seit 2010
vor 8 Jahren
Parser für Bedingungen

Tagchen
Ich habe ein Projekt das verschiedene vordefinierte Variablennamen kennt. Diesen Variablen weist das Programm je nach Ablaufschritt Werte zu. Diese Werte werden in einer Konfigurationsdatei für jeden Ablaufschritt festgelegt.
Nun soll das erweitert werden. In der Konfiguration sollen Bedingungen angegeben werden, nur wenn eine Bedingung zutrifft soll der jeweilige Abschnitt berücksichtigt werden. Die Bedingung besteht aus verketteten Tests dieser Variablen. Kann so aussehen:
condition="variableA=wert1 & (variableB=wertX | variableC=wertY)"
Es sollen die Operatoren = und != vorkommen. Später vielleicht auch <, >, ≤, ≥.
Als Variablennamen soll jeder gültige Bezeichner vorkommen können, rechts vom Gleich/Ungleichzeichen später auch Zahlenwerte. Zusätzlich & und | sowie Klammerung.

Für das ganze suche ich einen Parser, mit dem ich solche Formeln auseinandernehmen kann und mir auf irgendeine Art einen Mechanismus zur Auswertung bauen kann.
Wer dazu eine solide Idee hat würde mir ziemlich helfen. Alles was mir bisher eingefallen ist macht noch keinen völlig durchdachten Eindruck.

5.657 Beiträge seit 2006
vor 8 Jahren

Hi chilic,

am einfachsten wär's, wenn du die Ausdrücke als C# interpretieren und zur Laufzeit einfach ausführen könntest.

Brauchbare Parser-Bibliotheken für solche Suchausdrücke sollte man eigentlich im Internet oder über die Forensuche finden. Ansonsten hilft dir evtl. dieser Artikel weiter: Parser für mathematische Formeln

Christian

Weeks of programming can save you hours of planning

4.931 Beiträge seit 2008
vor 8 Jahren

Den Link hätte ich sonst auch gepostet 😉

@chilic: Dafür kannst du den ConditionalParser als Vorlage benutzen. Dieser kriegt noch zwei Parameter: den Datentyp T für die Werte deiner Variablen und einen geeigneten Parser für die Auswertung der Terminalsysmbole, d.h. den Variablen und Werten.

Sofern deine Variablen einfach Ganzzahlen sind, kannst du folgendes benutzen:


var parser = new ConditionalParser<int, FctParser<int>>();

parser.Parse(condition, 0);

Um die Variablen (und jeweils dessen aktueller Wert) dem Parser bekannt zu machen, leitest du eine Klasse von FctParser<T> ab und gibst in der Constants-Liste diese an (als echte Variable unterstützt mein Parser bisher nur "x"). Nun übergibst du dann einfach dem ConditionalParser diese Klasse als 2. Typparameter.

Die Operatoren kannst du einfach in der "Operators"-Liste von Hand abändern (z.B. wenn du "=" anstatt "==" für den Vergleich benutzen möchtest) - und überflüssige löschen (bzw. auskommentieren).

PS: Falls du Probleme damit hast, beachte auch die letzten Beiträge bei meinem Artikel, z.B. Parser für mathematische Formeln

C
chilic Themenstarter:in
2.121 Beiträge seit 2010
vor 8 Jahren

ich schau es mir mal an. Das Thema geht ja nach dem Parsen weiter, ich muss die ganze Sache noch auswerten. Da bin ich mir inzwischen gar nicht mehr sicher ob sich der ganze Aufwand überhaupt lohnt. Aber vielen Dank schon mal für die Anregungen.

4.931 Beiträge seit 2008
vor 8 Jahren

Was meinst du genau mit auswerten?
Ich hatte aber oben noch den Rückgabewert vergessen:


int result = parser.Parse(condition, 0);
if (result != 0)
{
  // ...
}

Der ConditionalParser wertet die Ausdrücke anhand des übergebenen Datentyps T aus, d.h. bei einem int kann dann 0 als false und alles ungleich 0 als true angesehen werden (im ConditionalParser gibt es dafür die beiden Member 'True' und 'False').

F
10.010 Beiträge seit 2004
vor 8 Jahren

Wenn man mal nach "Business Rules Engine c#" sucht kommen interessante sachen.
How to implement a rule engine? wäre da etwas.

Das geht dann hier weiter
How to implement a rule engine in C#

C
chilic Themenstarter:in
2.121 Beiträge seit 2010
vor 8 Jahren

Mit auswerten meine ich, ich brauche die einzelnen Teile als Strings, dann muss ich den Vergleichsoperator auswerten, den linken Teil als Variable irgendwo suchen (wo genau weiß ich selbst noch nicht so recht), den rechten Teil ebenfalls als Variable oder festen Wert erkennen und auswerten. Dazu dann noch die Vergleichsoperatoren sowie & und | und wer weiß schon was noch alles dazu kommen wird.
Angefangen hat es ganz harmlos mit nur einer einzigen Bedingung die zwei Variablenwerte vergleicht. Jetzt bin ich bei geklammerten Ausdrücken mit und/oder, der nächste Gedanke wäre dass man die Variablen auch noch miteinander verrechnen könnte ... sollte da mal die Bremse ziehen 😃 und überlegen obs nicht doch für den Anfang bei einer ganz simplen Bedingung bleiben kann. Ist ja nicht so dass in dem Projekt sonst nichts anderes zu tun wäre.

Die Rule Engine sieht interessant aus, die werde ich mir mit etwas Ruhe ansehen.

4.931 Beiträge seit 2008
vor 8 Jahren

Aber genau das macht doch alles mein Parser. Zieh dir einfach mal die Sourcen aus meinem Artikel und probiere es aus - ist nicht viel Arbeit.

I
45 Beiträge seit 2012
vor 8 Jahren

Bist Du Dir sicher, daß Dein Programmdesign gut ist ?
Das hier läuft nämlich auf Scripting hinaus und lohnt sich nur, wenn die Bedingungen wirklich ganz wild von Tag zu Tag wechseln.
Wenn etliche, aber von ihrer Struktur immer gleiche Fälle zu unterscheiden sind würde ich in der INI
a) die vorkommenden Variablenwerte und
b) den konkreten Fall in Form einer Nummer hinterlegen.
Jede Nummer bedeutet eine konkrete Testformel,
Bsp: fall=0 => if A = B
fall= 1 0> if A = B and C = D
usw.
Auswertung erfolgt hardcodiert (und dem Nutzer verborgen) im Programm selbst.
Hätte auch den Vorteil, daß Du nicht Deine eigenen Syntaxfehler in der INI parsen mußt (und es werden welche passieren).

Kommt auch drauf an, wieviel Du von Deinem Gehirnschmalz (die Testformeln nämlich) für Dich behalten willt/mußt.

ism

742 Beiträge seit 2005
vor 8 Jahren

Ich gebe dir noch zwei Alternativen:

  1. ClearScript. Einbettung von Jscript in .NET. Das schöne ist, man kann sehr dynamisch Variablen zugreifen. Durch den beschränkten Scope ist das eigentlich sicher (afaik 😉).

https://clearscript.codeplex.com/

  1. Grammatica oder Antlr. Einfach eine Grammatik definieren und Parsen. Das ist relativ einfach. Ich habe eine angehängt, die ich mal genau für einen ähnlichen Fall geschrieben habe.
C
chilic Themenstarter:in
2.121 Beiträge seit 2010
vor 8 Jahren

Bist Du Dir sicher, daß Dein Programmdesign gut ist ?

Ehrlich gesagt immer weniger 😃
Aktuel kochen die Ideen und Erweiterungsmöglichkeiten etwas über. Es ist nicht sicher was überhaupt benötigt wird und was nicht. Deswegen würde ich es begrüßen wenn sich das ganze vorerst auf eine einzelne Bedingung reduziert, die recht einfach selbst geparst werden kann.

Trotzdem interessieren mich die Vorschläge und sehe ich mir eure Links an! Danke.