Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Parser für Bedingungen
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2143

Themenstarter:

Parser für Bedingungen

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5992
Herkunft: Leipzig

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4193

beantworten | zitieren | melden

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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am .
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2143

Themenstarter:

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4193

beantworten | zitieren | melden

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').
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am .
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10084

beantworten | zitieren | melden

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#
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von FZelle am .
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2143

Themenstarter:

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4193

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
ismirschlecht
myCSharp.de - Member



Dabei seit:
Beiträge: 47

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
malignate
myCSharp.de - Member

Avatar #avatar-3206.png


Dabei seit:
Beiträge: 751

beantworten | zitieren | melden

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/

2. 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.
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2143

Themenstarter:

beantworten | zitieren | melden

Zitat von ismirschlecht
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.
private Nachricht | Beiträge des Benutzers