From: http://blog.163.com/redtomato/blog/static/48648149200831202846410/
Sometimes expression operations are required, such
String strexpression = "-12*(-2.2 + 7.7)-44*2 ";
I used codedom for searching online. For details, see
Http://www.codeproject.com/csharp/runtime_eval.asp
Simplified:
System. codedom. compiler. icodecompiler comp = (new Microsoft. CSHARP. csharpcodeprovider (). createcompiler ());
System. codedom. compiler. compilerparameters CP = new system. codedom. compiler. compilerparameters ();
Object qswheval2 (string expression ){
Stringbuilder code = new stringbuilder ();
Code. append ("using system; \ n ");
Code. append ("namespace adoguy {\ n ");
Code. append ("public class _ evaluator {\ n ");
Code. append ("public object _ Foo ()");
Code. append ("{");
Code. appendformat ("Return ({0});", expression );
Code. append ("} \ n ");
Code. append ("}}");
System. codedom. compiler. compilerresults Cr = Comp. compileassemblyfromsource (CP, code. tostring ());
System. reflection. Assembly A = Cr. compiledassembly;
Object _ compiled = A. createinstance ("adoguy. _ evaluator ");
System. reflection. methodinfo MI = _ compiled. GetType (). getmethod ("_ foo ");
Return mi. Invoke (_ compiled, null );
}
However, it is very slow to use. After all, real-time compilation is required.
As a result, I wrote an algorithm based on the data structure book:
String precede (string P, string q ){
Switch (p ){
Case "+ ":
Case "-": Return ("*/(". indexof (q )! =-1 )? "<": "> ";
Case "*":
Case "/": Return (q = "(")? "<": "> ";
Case "(": Return (q = ")")? "=": "<";
Case ")": Return (q = "(")? "? ":"> ";
Case "#": Return (q = "#")? "=": "<";
}
Return "? ";
}
Double operate (double A, char o, double B)
{
Switch (o)
{
Case '+': Return A + B;
Case '-': Return A-B;
Case '*': return a * B;
Case '/': Return A/B;
}
Return 0;
}
Object qswheval1 (string expression ){
/************ (Qiushuiwuhen 2002-12-14 )****************/
Stack narr = new stack (), oarr = new stack ();
Int J = 0;
Double A = 0, B = 0;
String W = "";
Char O;
Matchcollection arr = RegEx. Matches (expression. Replace ("", "") + "#",@"(((? <= (^ | \())-)? \ D + (\. \ D + )? | \ D )");
Oarr. Push ('#');
W = convert. tostring (ARR [J ++]);
While (! (W = "#" & convert. tostring (oarr. Peek () = "#")){
If ("+-*/() #". indexof (w )! =-1 ){
Switch (precede (oarr. Peek (). tostring (), W )){
Case "<":
Oarr. Push (w );
W = convert. tostring (ARR [J ++]);
Break;
Case "= ":
Oarr. Pop ();
W = convert. tostring (ARR [J ++]);
Break;
Case "> ":
O = convert. tochar (oarr. Pop ());
B = convert. todouble (narr. Pop ());
A = convert. todouble (narr. Pop ());
Narr. Push (operate (A, O, B ));
Break;
Default:
Return "error ";
Break;
}
} Else {
Narr. Push (w );
W = convert. tostring (ARR [J ++]);
}
}
Return narr. Pop ();
}
There are also two eval algorithms using JScript.
Microsoft. JScript. VSA. vsaengine VE = Microsoft. JScript. VSA. vsaengine. createengine ();
Object qswheval3 (string expression ){
Return Microsoft. JScript. Eval. jscriptevaluate (expression, VE );
}
Object qswheval4 (string expression ){
Return qswhjs. qswheval. eval (expression );
}
Fourth, You need to first create a JS to compile as a DLL, the following code
Import system;
Package qswhjs {
Class qswheval {
Static function eval (expression): object {return eval (expression );}
}
}
The test code is as follows:
Void page_load (Object o, eventargs EA ){
String strexpression = "-12*(-2.2 + 7.7)-44*2 ";
Int I = 0, c = 100;
Datetime D1, D2;
CP. generateexecutable = false;
CP. generateinmemory = true;
D1 = datetime. now;
For (I = 0; I D2 = datetime. now;
Response. Write ("Method 1: Expression Analysis" + d2.subtract (D1) +"
");
D1 = datetime. now;
For (I = 0; I D2 = datetime. now;
Response. Write ("Method 2: Using codecom" + d2.subtract (D1) +"
");
D1 = datetime. now;
For (I = 0; I D2 = datetime. now;
Response. Write ("method 3: using JScript + VSA" + d2.subtract (D1) +"
");
D1 = datetime. now;
For (I = 0; I D2 = datetime. now;
Response. Write ("method 4: Using JSC + DLL" + d2.subtract (D1) +"
");
}
Test results:
Method 1: analyze the expression at 00:00:00. 1702448
Method 2: Use codecom 00:00:23. 7942144
Method 3: Use JScript + VSA 00:00:00. 1902736
Method 4: Use JSC + DLL 00:00:00. 2403456
The first type is recommended here (if it is pure CSHARP)
And the third (simple code, more functions)