2010-02-18 7 views
9

Ich schreibe eine Anwendung, die es einem Benutzer erlaubt, einen booleschen Ausdruck einzugeben. Ich brauche die Fähigkeit, den eingegebenen booleschen Ausdruck zur Laufzeit auszuwerten und suche nach einem Parser und einem Expressoin-Validator.Boolescher und mathematischer Ausdruck Parser

Parser
Der Parser braucht einen Booleschen Ausdruck als String zu nehmen und wahr/falsch zurück.

Beispiel:

 
string expression = "(1 == 1) && (1 > 0)"; 
Parser parser = new Parser(); 
boolean result = parser.parse(expression); // Result should be True. 

Neben Booleschen Ausdrücken Handhabung Ich brauche es auch Mathe zu behandeln.

 
expression = "((1 + 1 * 2) == 1)"; 
result = parser.parse(expression); // Result should be False. 

Validate
Damit ich den Benutzer sagen kann, ob es ein Problem mit dem Ausdruck wird eingegeben Ich brauche auch eine Möglichkeit, die Syntax zu validieren.

Ich arbeite in C# mit dem .NET Compact Framework, aber wenn Sie etwas in einer anderen Sprache geschrieben wissen, die hilfreich sein kann.

Vielen Dank für Ihre Hilfe. Tom

Antwort

3

http://www.antlr.org

Antlr Grammatiken können so gestaltet werden, sowohl für das Parsen und Auswertung zu ermöglichen.

Hier ist ein Beispiel: http://www.antlr.org/wiki/display/ANTLR3/Expression+evaluator

+0

+1 für ANTLR. Wenn du dir das ansiehst und es ablehnst, denkst du, dass das zu viel Ärger ist, dann überdenk dich bitte. Ich empfehle Ihnen, ANTLRworks als Grammatik-Entwicklungstool zu verwenden und seine Lexer- und Parser-Klassen in Ihre Visual Studio-Projektstruktur auszugeben. Es ist relativ nahtlos und es ist einfach, Ihre Grammatik iterativ zu optimieren und die Auswirkungen in Ihrer .NET-Welt schnell zu sehen. –

+0

Mit "Sie" oben meine ich Thomas der OP. –

+0

@Chris Farmer: Dies ist Ziel C# Compact Framework ... könnte ein bisschen schwer dafür sein ... – t0mm13b

0

Ich kenne keine Bibliotheken, um dies zu erleichtern, aber Sie haben wirklich nur zwei Teilprobleme hier. Sie müssen einen Infix zum Postfix-Konverter erstellen und dann einen Basisrechner für die booleschen und mathematischen Operationen schreiben.

Sobald Sie Ihren booleschen Baum/Stack erstellt haben, beginnen Sie, Operationen auszuführen. Wenn Sie etwas haben, das keine Zahl ist, bewerten Sie es, indem Sie die Zeichenfolge/den Ausdruck an den arithmetischen Rechner senden, der die Infix-> Postfix-Konvertierung durchführt und dann einen Wert zurückgibt.

Wenn Sie google "Infix zu Postfix" und "stapeln RPN-Rechner", können Sie wahrscheinlich mehr Ressourcen finden.

+2

Wenn Sie jedoch mit "eval" eine Sprache auswählen können, ist das Problem gelöst. Du suchst nach wahr oder falsch und für alles andere weißt du, dass du ungültig bist. –

+0

Ich denke, "Eval" ist völlig falsch. Es ist potentiell einfach, aber es ist riskant, dass Leute Code schreiben, der in Ihrer Sprache legal ist. Es ist besser, IMHO, eine bestimmte und begrenzte Grammatik zu haben, die für diese Ausdrücke verfügbar ist. –

0

Möglicherweise können Sie dazu die Bibliothek dotMath verwenden.

0

Hier ist eine ausgezeichnete Bewertung Parser auf Codeproject, dass die eval-Methode verwendet und beruht nicht auf CodeDOM oder so etwas. Hier ist ein ausgezeichneter Artikel über den Aufbau einer expression evaluator mit Antlr, auch auf dem gleichen Gelände ..

hoffe, das hilft, Mit freundlichen Grüßen, Tom.

0

Diese Art von Sache ist F # 's Brot und Butter. Du könntest es versuchen. Verwenden Sie für das Parsing rekursive Abstieg, dann können Sie über den Baum, der sich ergibt. Wenn Sie die Eingabesprache beherrschen, können Sie mit einer Angebotsoperation auskommen.

2

Angenommen, Sie Ihre Syntax etwas ändern können, lassen Sie eine eingebettete Datenbank wie dieses T-SQL mit einer Abfrage die Arbeit für Sie tun:

select case when <Expression> then 1 else 0 end as Result 

Ihrem Beispiel verwenden:

select case when ((1 = 1) and (1 > 0)) then 1 else 0 end as Result 
select case when ((1 + 1 * 2) = 1) then 1 else 0 end as Result 
+1

Laut der Frage wird der Ausdruck tatsächlich vom Benutzer eingegeben. Daher ist Ihre Lösung anfällig für SQL-Injektion. –

6

Unser Projekt verwendet NCalc (mit ANTLR darunter für Lexing/Parsing) und wir sind sehr glücklich damit.

NCalc ist eine mathematische Ausdrücke Evaluator in .NET. NCalc kann jeden beliebigen Ausdruck parsen und das Ergebnis einschließlich statischer oder dynamischer Parameter und benutzerdefinierter Funktionen auswerten.

Unsere Anwendung erfordert, dass sie für vollständige und kompakte Frameworks kompiliert wird. Mit relativ einfachen Optimierungen konnten wir sowohl NCalc als auch ANTLR für beide Framework-Varianten verwenden.