I need to parse complex expresion from string to bool.
It can only contain:
* boolean values (true/false),
* parenthesis,
* AND/OR operands (&&, ||)
Eg:
bool.Parse("((true || false) && (false || false)) || (true || false)"
Any idea how to achieve this?
From stackoverflow
-
The standard method is to:
- tokenize the string
- build a tree putting an operator in every node and an operand in every leaf
- visiting the tree evaluating the expression
-
Here's a cunning evaluator class that gives you the JScript.NET Eval function within C# code:
static public class Evaluator { private const string _jscriptSource = @"package Evaluator { class Evaluator { public function Eval(expr : String) : String { return eval(expr); } } }"; static private object _evaluator; static private Type _evaluatorType; [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Can't be done inline - too complex")] static Evaluator() { InstantiateInternalEvaluator(); } static private void InstantiateInternalEvaluator() { JScriptCodeProvider compiler = new JScriptCodeProvider(); CompilerParameters parameters; parameters = new CompilerParameters(); parameters.GenerateInMemory = true; CompilerResults results; results = compiler.CompileAssemblyFromSource(parameters, _jscriptSource); Assembly assembly = results.CompiledAssembly; _evaluatorType = assembly.GetType("Evaluator.Evaluator"); _evaluator = Activator.CreateInstance(_evaluatorType); } static public int EvaluateToInteger(string statement) { string s = EvaluateToString(statement); return int.Parse(s); } static public double EvaluateToDouble(string statement) { string s = EvaluateToString(statement); return double.Parse(s); } static public decimal ForceEvaluateToDecimal(string statement) { decimal result; bool s = Decimal.TryParse(statement, out result); return result; } static public decimal EvaluateToDecimal(string statement) { string s = EvaluateToString(statement); return decimal.Parse(s); } static public string EvaluateToString(string statement) { object o = EvaluateToObject(statement); return o.ToString(); } static public bool EvaluateToBool(string statement) { object o = EvaluateToObject(statement); return (bool)o; } static public object EvaluateToObject(string statement) { try { return _evaluatorType.InvokeMember( "Eval", BindingFlags.InvokeMethod, null, _evaluator, new object[] {statement} ); } catch (Exception) { InstantiateInternalEvaluator(); return null; } } }You just then call Evaluator.EvaluateToBool(string). Lifted from an existing project, so you may want to tweak!
Maciej : awesome! PS EvaluateToBool shall has bool returnMaciej : BTW How about performance? Do you think this can be an issue?David M : "Maciej (first comment) - schoolboy copy, paste and fail to edit properly error. Will edit. Thanks. -
The string you described is valid C# code, so if you can interpret it at runtime you're done. In many languages this is a built in function. In C# it is not, but you can use a 3rd party library such as this runtime C# interpreter
Maciej : Runtime C# Expression Evaluator you mentioned looks interesting but download link seems be broken- do you have source ?Maciej : Sorry - started working now
0 comments:
Post a Comment