Logik-expression parser
Ich versuche zu schaffen, ein Logik-Ausdruck parser für Ausdrücke wie:
((VariableA -> VariableB) UND NICHT VariableC)
Der parser soll in der Lage sein, um zurückzukehren, ob das Ergebnis true oder false für gegebene Werte der Variablen.
Grundsätzlich die Ausdrücke werden nur Variablen enthalten, die logischen Operatoren (oder, und, Implikation, äquivalenz, negation und Klammern).
Ich würde gerne Fragen, was ist der beste Weg zur Umsetzung dieser Art von parser (mit AST -, Baum -, oder Umgekehrte polnische Notation)? Oder vielleicht gibt es bereits einige open-source-Parser, die den job tun können?
- Implementieren Sie einen recursive-descent-parser. Logik-Ausdrücke sind sehr einfach und leicht analysiert diese Weise. Die parsing-Aktionen auswerten können, die Variablen, push/pop Zwischenwerte aus einem Stapel. Dies sollte ~~ 50 Zeilen C-code.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Welcher Sprache sind Sie targeting?
Wenn Sie möchten, erstellen Sie einen parser, vielleicht ANTLR wird der trick für Sie. Es ist ursprünglich java-basiert, aber es hat Generatoren für eine Vielzahl von Sprachen (ich benutze es zum erstellen einer C# - parser zum Beispiel) und ist nicht allzu schwer zu pick-up.
Es hat einen schönen editor (ANTLRWorks), ermöglicht die Prüfung der Grammatik, das ist ein nettes plus.
Ich würde Sie verwenden RPN, wenn ich du wäre. Das speichern, sollten Sie einige Trauer, wenn analysiert wird, und der Algorithmus sollte so einfach wie das drücken und knallen einen stack von Werten wie der Betreiber kommen. Sie nicht haben, zu täuschen, mit Klammern, das sollte das Leben leichter machen. Der einzige wirkliche Nachteil ist, dass die meisten Menschen nicht vertraut sind mit postfix (AKA RPN) Schreibweise.
Einem stack ist es wahrscheinlich einfacher, mit zu arbeiten, als ein Baum als gut.
Nur meine 2¢ 🙂
Ich bin sicher, es gibt bereits tools, die dies tun (Logik-Auswertung), aber ich konnte Sie nicht finden. Wenn Sie ein tool wie Bison (YACC, C) oder ANTLR (erzeugt eine Reihe von Sprachen, verwendet aber Java) Sie müssen nicht zu viel sorgen machen über das Parsen. Coco/R ist ein weiterer parser-generator erzeugen können viele verschiedene Sprachen. Wenn Sie möchten es selbst tun, aber ich würde RPN-oder Präfix-notation (was ich denke ist einfacher als RPN). Dadurch wird es viel einfacher zu analysieren, sondern verärgern Ihre Nutzer.
Es klingt wie eine Hausaufgabe 🙂
Zuerst müssen Sie definieren Ihre Sprache rekursiv.
Einer Variablen ist wohlgeformt form (WFF)
wenn X eine WFF, dann nicht X ist eine WFF
wenn X und Y WFF dann (X -> Y) ist ein WFF
wenn X und Y WFF dann (X UND Y) eine WFF
Einmal die Grammatik definiert ist, verwenden Sie LEX oder Flex, oder das äquivalent für Java
oder Ihre bevorzugte Sprache für das schreiben eines trivial-scanner.
Verwenden YACC oder Bison, oder das äquivalent für das schreiben der Nachkomme rekursive parser.
Später Attribute hinzufügen, um die Grammatik, um die Bewertung der Ausdruck, den Sie auswerten wollen, in der ein Nachkomme rekursive Weise.
Wenn Sie in Python, versuchen dieser Ausdruck parser/evaluator, geschrieben mit pyparsing, als Ausgangspunkt.
Haben Sie gesehen,http://ncalc.codeplex.com ?
Es ist erweiterbar, schnell (z.B. hat seinen eigenen cache) ermöglicht Ihnen das bereitstellen von benutzerdefinierten Funktionen und varaibles zur Laufzeit durch den Umgang EvaluateFunction/EvaluateParameter Veranstaltungen. Beispiel Ausdrücken kann analysieren:
Ausdruck e = new Ausdruck("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameter["Pi2"] = new Ausdruck("Pi * Pi");
e.Parameter["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Ergebnis = 3.14;
};
Debuggen.Assert(117.07 == e.Evaluate());
Es kann auch mit unicode & viele Daten-Typ nativ. Es kommt mit einem geweih-Datei, wenn Sie möchten, ändern Sie die Grammatik. Es gibt auch eine Gabel, die unterstützt MEF laden Sie neue Funktionen.