How to get a calculated value from a compiled LambdaExpression? - c#

I'm currently working on a project at work, and we are using the Telerik RadControls for Silverlight. In their Q1 2011 release, they added a new control called the Rad Expression Editor. In the Rad Expression Editor, you can pass in an object and create formulas (or expressions), and the editor window will give you a preview of the result of the expression. I've spoken with Telerik about this and they intentionally did not expose the result of this, but mentioned that I could use LambdaExpression.Compile(). I'm very new to Linq and using Lambda Expressions in general, but started looking into this.
As an example, lets say I have an object called Finances, and in that object, there are 4 nullable decimal fields (values): Debit (10), DebitYTD (100), Credit (20) and CreditYTD (200). In the formula, I want to do something like: Debit - Credit + DebitYTD - CreditYTD.
The Telerik Rad Expression Editor will give me the expression that is generated:
ExpressionEditor.Expression = {Param_0 => ((Param_0.Debit - Param_0.Credit + Param_0.DebitYTD - Param_0.CreditYTD}
The result of this expression should be -110. I need to be able to get the value that is calculate in the expression, but have not been able to figure out how to get this number. Can anyone please explain how this can be accomplished? Thanks.

You haven't really told us much about the API which it exposes, but it sounds like you could use:
var compiled = ExpressionEditor.Expression.Compile();
var result = compiled(input);
where input is an appropriate variable of type Finances.
EDIT: Okay, as the expression isn't exposed nicely:
var typeSafe = (Expression<Func<Finance, decimal?>>) ExpressionEditor.Expression;
var compiled = typeSafe.Compile();
var result = compiled(input);

I had very similar requirements. There was a need to compile expression and evaluate at runtime against different instances. However function compilation is not so trivial as you have to know the type of the result value during compile time and in most of the cases this will be impossible: user writes "1+1" and you get System.Int32, or user writes "(1+1).ToString()" and you get System.String. I'm sure this is the point where you experience (or will experience) difficulties.
In order to solve the expression compilation problem I would recommend jumping into DLR (Dynamic Language Runtime). You will need to reference "Microsoft.CSharp" assembly for your Silverlight project. As you need just access to "Compile" method for the expression (that is already in there), it will be fair enough doing that against "dynamic" object. Here's a short sample to demonstrate that:
dynamic dynamicExpression = expressionEditor.Expression;
dynamic compiledExpression = dynamicExpression.Compile();
object executionResult = compiledExpression(myInstance);
The "executionResult" variable will hold the result of expression evaluation. Now you can do whatever you need to do with the result.
Hope that helps

Related

solving a math expression

I want to evaluate a math expression which the user enters in a textbox. I have done this so far
string equation, finalString;
equation = textBox1.Text;
StringBuilder stringEvaluate = new StringBuilder(equation);
stringEvaluate.Replace("sin", "math.sin");
stringEvaluate.Replace("cos", "math.cos");
stringEvaluate.Replace("tan", "math.tan");
stringEvaluate.Replace("log", "math.log10");
stringEvaluate.Replace("e^", "math.exp");
finalString = stringEvaluate.ToString();
StringBuilder replaceI = new StringBuilder(finalString);
replaceI.Replace("x", "i");
double a;
for (int i = 0; i<5 ; i++)
{
a = double.Parse(finalStringI);
if(a<0)
break;
}
when I run this program it gives an error "Input string was not in a correct format." and highlights a=double.Parse(finalStringI);
I used a pre defined expression a=i*math.log10(i)-1.2 and it works, but when I enter the same thing in the textbox it doesn't.
I did some search and it came up with something to do with compiling the code at runtime.
any ideas how to do this?
i'm an absolute beginner.
thanks :)
The issue is within your stringEvaluate StringBuilder. When you're replacing "sin" with "math.sin", the content within stringEvaluate is still a string. You've got the right idea, but the error you're getting is because of that fact.
Math.sin is a method inside the Math class, thus it cannot be operated on as you are in your a = double.Parse(finalStringI); call.
It would be a pretty big undertaking to accomplish your goal, but I would go about it this way:
Create a class (perhaps call it Expression).
Members of the Expression class could include Lists of operators and operands, and perhaps a double called solution.
Pass this class the string at instantiation, and tear it apart using the StringBuilder class. For example, if you encounter a "sin", add Math.sin to the operator collection (of which I'd use type object).
Each operator and operand within said string should be placed within the two collections.
Create a method that evaluates the elements within the operator and operand collection accordingly. This could get sticky for complex calculations with more than 2 operators, as you would have to implement a PEMDAS-esque algorithm to re-order the collections to obey the order of operations (and thus achieve correct solutions).
Hope this helps :)
The .Parse methods (Int.Parse, double.Parse, etc) will only take a string such as "25" or "3.141" and convert it to the matching value type (int 25, or double 3.141). They will not evaluate math expressions!
You'll pretty much have to write your own text-parser and parse-tree evaluator, or explore run-time code-generation, or MSIL code-emission.
Neither topic can really be covered in the Q&A format of StackOverflow answers.
Take a look at this blog post:
http://www.c-sharpcorner.com/UploadFile/mgold/CodeDomCalculator08082005003253AM/CodeDomCalculator.aspx
It sounds like it does pretty much what you're trying to do. Evaluating math expressions is not as simple as just parsing a double (which is really only going to work for strings like "1.234", not "1 + 2.34"), but apparently it is possible.
You can use the eval function that the framework includes for JScript.NET code.
More details: http://odetocode.com/code/80.aspx
Or, if you're not scared to use classes marked "deprecated", it's really easy:
static string EvalExpression(string s)
{
return Microsoft.JScript.Eval.JScriptEvaluate(s, null, Microsoft.JScript.Vsa.VsaEngine.CreateEngine()).ToString();
}
For example, input "Math.cos(Math.PI / 3)" and the result is "0.5" (which is the correct cosine of 60 degrees)

evaluate an arithmetic expression stored in a string (C#)

I'm working on a application in C# in which I want to calculate an arithmetic expression that is given as a string.
So like I got a string:
string myExpr="4*(80+(5/2))+2";
And I want to calculate the outcome of the arithmetic expression.
While in a language such as Javascript, PHP etc. you could just use Eval to do the trick this doesnt seem to be an option in C#.
I suppose it is possible to write a code to devide it into countless simple expressions, calculate them and add them together but this would take quite some time and I'm likely to have lots of troubles in my attempt to do so.
So... my question, Is there any 'simple' way to do this?
There's a javascript library you can reference, then just do something like:
var engine = VsaEngine.CreateEngine();
Eval.JScriptEvaluate(mySum, engine);
Edit;
Library is Microsoft.JScript
You could just call the JScript.NET eval function. Any .NET language can call into any other.
Have you seen http://ncalc.codeplex.com ?
It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.
It also supports logical operators, date/time's strings and if statements.
I've used NCalc with great success. It's extremely flexible and allows for variables in your formulas. The formula you listed in your question could be evaluated this easily:
string myExpr = "4*(80+(5/2))+2";
decimal result = Convert.ToDecimal(new Expression(myExpr).Evaluate());
You need to implement an expression evaluator. It's fairly straightforward if you have the background, but it's not "simple". Eval in interpreted environments actually re-runs the language parser over the string; you need to emulate that operation, for the bits you care about, in your C# code.
Search for "expression evaluators" and "recursive descent parser" to get started.
If you have Bjarne Stroustrup's The C++ Programming Language, in Chapter 6 he explains step by step (in C++) how to do exactly what Chris Tavares suggests.
It's straightforward but a little heady if you're not familiar with the procedure.
I needed to do something similar for an undergrad projectand I found this
Reverse Polish Notation In C#
Tutorial and code to be extremely valuable.
It's pretty much just an implementation of converting the string to Reverse Polish Notation then evaluating it. It's extremely easy to use, understand and add new functions.
Source code is included.
Try something like this:
int mySum = 4*(80+(5/2))+2;
var myStringSum = mySum.toString();

Working with heterogenous data in a statically typed language (F#)

One of F#'s claims is that it allows for interactive scripting and data manipulation / exploration. I've been playing around with F# trying to get a sense for how it compares with Matlab and R for data analysis work. Obviously F# does not have all practical functionality of these ecosystems, but I am more interested in the general advantages / disadvantages of the underlying language.
For me the biggest change, even over the functional style, is that F# is statically typed. This has some appeal, but also often feels like a straightjacket. For instance, I have not found a convenient way to deal with heterogeneous rectangular data -- think dataframe in R. Assume I'm reading a CSV file with names (string) and weights (float). Typically I load data in, perform some transformations, add variables, etc, and then run analysis. In R, the first part might look like:
df <- read.csv('weights.csv')
df$logweight <- log(df$weight)
In F#, it's not clear what structure I should use to do this. As far as I can tell I have two options: 1) I can define a class first that is strongly typed (Expert F# 9.10) or 2) I can use a heterogeneous container such as ArrayList. A statically typed class doesn't seem feasible because I need to add variables in an ad-hoc manner (logweight) after loading the data. A heterogeneous container is also inconvenient because every time I access a variable I will need to unbox it. In F#:
let df = readCsv("weights.csv")
df.["logweight"] = log(double df.["weight"])
If this were once or twice, it might be okay, but specifying a type every time I use a variable doesn't seem reasonable. I often deal with surveys with 100s of variables that are added/dropped, split into new subsets and merged with other dataframes.
Am I missing some obvious third choice? Is there some fun and light way to interact and manipulate heterogeneous data? If I need to do data analysis on .Net, my current sense is that I should use IronPython for all the data exploration / transformation / interaction work, and only use F#/C# for numerically intensive parts. Is F# inherently the wrong tool for quick and dirty heterogeneous data work?
Is F# inherently the wrong tool for
quick and dirty heterogeneous data
work?
For completely ad hoc, exploratory data mining, I wouldn't recommend F# since the types would get in your way.
However, if your data is very well defined, then you can hold disparate data types in the same container by mapping all of your types to a common F# union:
> #r "FSharp.PowerPack";;
--> Referenced 'C:\Program Files\FSharp-1.9.6.16\bin\FSharp.PowerPack.dll'
> let rawData =
"Name: Juliet
Age: 23
Sex: F
Awesome: True"
type csv =
| Name of string
| Age of int
| Sex of char
| Awesome of bool
let parseData data =
String.split ['\n'] data
|> Seq.map (fun s ->
let parts = String.split [':'] s
match parts.[0].Trim(), parts.[1].Trim() with
| "Name", x -> Name(x)
| "Age", x -> Age(int x)
| "Sex", x -> Sex(x.[0])
| "Awesome", x -> Awesome(System.Convert.ToBoolean(x))
| data, _ -> failwithf "Unknown %s" data)
|> Seq.to_list;;
val rawData : string =
"Name: Juliet
Age: 23
Sex: F
Awesome: True"
type csv =
| Name of string
| Age of int
| Sex of char
| Awesome of bool
val parseData : string -> csv list
> parseData rawData;;
val it : csv list = [Name "Juliet"; Age 23; Sex 'F'; Awesome true]
csv list is strongly typed and you can pattern match over it, but you have to define all of your union constructors up front.
I personally prefer this approach, since is orders of magnitude better than working with an untyped ArrayList. However, I'm not really sure what you're requirements are, and I don't know a good way to represent ad-hoc variables (except maybe as a Map{string, obj}) so YMMV.
I think that there are a few other options.
(?) operator
As Brian mentioned, you can use the (?) operator:
type dict<'a,'b> = System.Collections.Generic.Dictionary<'a,'b>
let (?) (d:dict<_,_>) key = unbox d.[key]
let (?<-) (d:dict<_,_>) key value = d.[key] <- box value
let df = new dict<string,obj>()
df?weight <- 50.
df?logWeight <- log(df?weight)
This does use boxing/unboxing on each access, and at times you may need to add type annotations:
(* need annotation here, since we could try to unbox at any type *)
let fltVal = (df?logWeight : float)
Top level identifiers
Another possibility is that rather than dynamically defining properties on existing objects (which F# doesn't support particularly well), you can just use top level identifiers.
let dfLogWeight = log(dfWeight)
This has the advantage that you will almost never need to specify types, though it may clutter your top-level namespace.
Property objects
A final option which requires a bit more typing and uglier syntax is to create strongly typed "property objects":
type 'a property = System.Collections.Generic.Dictionary<obj,'a>
let createProp() : property<'a> = new property<'a>()
let getProp o (prop:property<'a>) : 'a = prop.[o]
let setProp o (prop:property<'a>) (value:'a) = prop.[o] <- value
let df = new obj()
let (weight : property<double>) = createProp()
let (logWeight : property<double>) = createProp()
setProp df weight 50.
setProp df logWeight (getProp df weight)
let fltVal = getProp df logWeight
This requires each property to be explicitly created (and requires a type annotation at that point), but no type annotations would be required after that. I find this much less readable than the other options, although perhaps defining an operator to replace getProp would alleviate that somewhat.
I am not sure if F# is a great tool here or not. But there is a third option - the question mark operator. I've been meaning to blog about this for a while now; Luca's recent PDC talk demo'd a CSV reader with C# 'dynamic', and I wanted to code a similar thing with F# using the (?) operator. See
F# operator "?"
for a short description. You can try to blaze ahead and play around with this on your own, or wait for me to blog about it. I have not tried it myself in earnest so I'm not sure exactly how well it will work out.
EDIT
I should add that Luca's talk shows how 'dynamic' in C# addresses at least a portion of this question for that language.
EDIT
See also
http://cs.hubfs.net/forums/thread/12622.aspx
where I post some basic starter CSV code.

Parser for query filter expression tree

I am looking for a parser that can operate on a query filter. However, I'm not quite sure of the terminology so it's proving hard work. I hope that someone can help me. I've read about 'Recursive descent parsers' but I wonder if these are for full-blown language parsers rather than the logical expression evaluation that I'm looking for.
Ideally, I am looking for .NET code (C#) but also a similar parser that works in T-SQL.
What I want is for something to parse e.g.:
((a=b)|(e=1))&(c<=d)
Ideally, the operators can be definable (e.g. '<' vs 'lt', '=' vs '==' vs 'eq', etc) and we can specify function-type labels (e.g. (left(x,1)='e')). The parser loads this, obeys order precedence (and ideally handles the lack of any brackets) and then calls-back to my code with expressions to evaluate to a boolean result - e.g. 'a=b'?). I wouldn't expect the parser to understand the custom functions in the expression (though some basic ones would be useful, like string splitting). Splitting the expression (into left- and right-hand parts) would be nice.
It is preferable that the parser asks the minimum number of questions to have to work out the final result - e.g. if one side of an AND is false, there is no point evaluating the other side, and to evaluate the easiest side first (i.e. in the above expression, 'c<=d' should be assumed to be quicker and thus evaluated first.
I can imagine that this is a lot of work to do, however, fairly common. Can anyone give me any pointers? If there aren't parsers that are as flexible as above, are there any basic parsers that I can use as a start?
Many Thanks
Lee
Take a look at this. ANTLR is a good parser generator and the linked-to article has working code which you may be able to adapt to your needs.
You could check out Irony. With it you define your grammar in C# code using a syntax which is not to far from bnf. They even have a simple example on their site (expression evaluator) which seems to be quite close to what you want to achieve.
Edit: There's been a talk about Irony at this year's Lang.Net symposium.
Hope this helps!
Try Vici.Parser: download it here (free) , it's the most flexible expression parser/evaluator I've found so far.
If it's possible for you, use .Net 3.5 expressions.
Compiler parses your expression for you and gives you expression tree that you can analyze and use as you need. Not very simple but doable (actually all implementations of IQueryable interface do exactly this).
You can use .NET expression trees for this. And the example is actually pretty simple.
Expression<Func<int, int, int, int, bool>> test = (int a, int b, int c, int d) => ((a == b) | (c == 1)) & (c <= d);
And then just look at "test" in the debugger. Everything is already parsed for you, you can just use it.
The only problem is that in .NET 3.5 you can have only up to 4 arguments in Func. So, I changed "e" to "c" in one place. In 4.0 this limit is changed to 16.

C#: How to parse arbitrary strings into expression trees?

In a project that I'm working on I have to work with a rather weird data source. I can give it a "query" and it will return me a DataTable. But the query is not a traditional string. It's more like... a set of method calls that define the criteria that I want. Something along these lines:
var tbl = MySource.GetObject("TheTable");
tbl.AddFilterRow(new FilterRow("Column1", 123, FilterRow.Expression.Equals));
tbl.AddFilterRow(new FilterRow("Column2", 456, FilterRow.Expression.LessThan));
var result = tbl.GetDataTable();
In essence, it supports all the standard stuff (boolean operators, parantheses, a few functions, etc.) but the syntax for writing it is quite verbose and uncomfortable for everyday use.
I wanted to make a little parser that would parse a given expression (like "Column1 = 123 AND Column2 < 456") and convert it to the above function calls. Also, it would be nice if I could add parameters there, so I would be protected against injection attacks. The last little piece of sugar on the top would be if it could cache the parse results and reuse them when the same query is to be re-executed on another object.
So I was wondering - are there any existing solutions that I could use for this, or will I have to roll out my own expression parser? It's not too complicated, but if I can save myself two or three days of coding and a heapload of bugs to fix, it would be worth it.
Try out Irony. Though the documentation is lacking, the samples will get you up and running very quickly. Irony is a project for parsing code and building abstract syntax trees, but you might have to write a little logic to create a form that suits your needs. The DLR may be the complement for this, since it can dynamically generate / execute code from abstract syntax trees (it's used for IronPython and IronRuby). The two should make a good pair.
Oh, and they're both first-class .NET solutions and open source.
Bison or JavaCC or the like will generate a parser from a grammar. You can then augment the nodes of the tree with your own code to transform the expression.
OP comments:
I really don't want to ship 3rd party executables with my soft. I want it to be compiled in my code.
Both tools generate source code, which you link with.
I wrote a parser for exaclty this usage and complexity level by hand. It took about 2 days. I'm glad I did it, but I wouldn't do it again. I'd use ANTLR or F#'s Fslex.

Categories