http://blog.csdn.net/cuike519/archive/2004/08/29/87929.aspx
抛出异常就是表达式错误

解决方案 »

  1.   

    在http://www.xue68.com 搜索到过类似的解决方法
      

  2.   

    目的是为了什么,如果只是要实现算法,可以用以下方法几种方法。
    http://www.yestar2000.com/TechCenter/1410/TC_16048.htm
    //===========================================================
    //四种Eval测试结果:不要用CodeDom做大批量的表达式四则运算
    //===========================================================--------------------------------------------------------------------------------
    作者:qiushuiwuhen 来源:未知 加入时间:2004-6-29 浏览次数: 
    -------------------------------------------------------------------------------- 
    有时候需要表达式运算,如
    String strExpression="-12 * ( - 2.2 + 7.7 ) - 44 * 2";网上找的,一般是利用CodeDom,见
    http://www.codeproject.com/csharp/runtime_eval.asp简化为:
     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);

    但用起来感觉很慢,毕竟需要实时编译。于是,就自己照数据结构书上写了一种算法:
    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();
    }还有利用JScript的Eval的两种算法
    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);
    }第四种需先建立一js编译为dll,如下代码
    import System;package qswhJs {
      class qswhEval {
        static function Eval(Expression):Object { return eval(Expression); }
      }
    }测试代码如下:
    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<c;i++)qswhEval1(strExpression);
     d2=DateTime.Now;
     Response.Write("方法一:对表达式分析 "+d2.Subtract(d1)+"<br>");
     
     d1=DateTime.Now;
     for(i=0;i<c;i++)qswhEval2(strExpression);
     d2=DateTime.Now;
     Response.Write("方法二:利用CodeCom  "+d2.Subtract(d1)+"<br>");
     
     d1=DateTime.Now;
     for(i=0;i<c;i++)qswhEval3(strExpression);
     d2=DateTime.Now;
     Response.Write("方法三:利用Jscript+Vsa  "+d2.Subtract(d1)+"<br>");
     
     d1=DateTime.Now;
     for(i=0;i<c;i++)qswhEval4(strExpression);
     d2=DateTime.Now;
     Response.Write("方法四:利用Jsc+Dll  "+d2.Subtract(d1)+"<br>");
    }测试结果:方法一:对表达式分析 00:00:00.1702448
    方法二:利用CodeCom 00:00:23.7942144
    方法三:利用Jscript+Vsa 00:00:00.1902736
    方法四:利用Jsc+Dll 00:00:00.2403456在此推荐第一种(如果要纯CSharp的话)
    和第三种(代码简单,功能更多)
      

  3.   

    如果是 sin(a)+b 怎么伴,我里面还要对数学函数解析