public void ProcParentheses(int index, OperatorType op) { if (op == OperatorType.L_Parentheses) //左括号 { needOp = false; needParentheses = false; stackOp.Push(op); } else if (op == OperatorType.R_Parentheses) //右括号 { bool find = false; //如果是函数,则此处为函数的参数个数 //通过统计逗号的个数得出参数的个数 int funcParam = 1; while (stackOp.Count > 0) { if (stackOp.Peek() != OperatorType.L_Parentheses) { OperatorType opPop = stackOp.Pop(); if (opPop == OperatorType.Comma) { funcParam++; } else { rePoland.Add(new ExpressionToken(TokenType.Operator, opPop)); } } else { stackOp.Pop(); find = true; break; } } if (!find) { throw new ExpressionException("括号不匹配.(缺少左括号)", 1003); } //如果再前一个是函数,也要加到 rePoland 中 if (stackOp.Count > 0) { OperatorType opPrev = stackOp.Peek(); if (IsFunc(opPrev)) { //先判断函数的参数个数是否正确 FunctionBase func = FuncFactory.GetFunc((int)opPrev); if (func.ParamCount != funcParam) { throw new ExpressionException("函数(" + func.Name + ")参数个数不正确\n" + "应为" + func.ParamCount + "个," + "实为" + funcParam + "个"); } rePoland.Add(new ExpressionToken(TokenType.Operator, stackOp.Pop())); } } } }
/// <summary> /// 计算二元表达式的值 /// </summary> public object CalcOperator(OperatorType op, decimal?[] data) { if (IsBaseOperator(op)) { decimal?d1 = data[0]; decimal?d2 = data[1]; if (d1 == null || d2 == null) { return(DBNull.Value); } switch (op) { case OperatorType.Plus: return(d1 + d2); case OperatorType.Subtract: return(d1 - d2); case OperatorType.MultiPly: return(d1 * d2); case OperatorType.Divide: if (d2 == 0) { throw new DivideByZeroException(); } return(d1 / d2); case OperatorType.Power: //幂运算 return(Math.Pow((double)d1, (double)d2)); } } else if (IsFunc(op)) { FunctionBase func = FuncFactory.GetFunc((int)op); if (func == null) { throw new ExpressionException("不可识别的函数名."); } else { func.Data = data; try { return(func.Calc()); } catch (Exception ex) { throw new ExpressionException("函数计算出错:" + ex.Message, 9000); } } } return(0); }
private object CalcInner() { int index = 0; //存放常数表 List <decimal?> digit = new List <decimal?>(); //备份表达式 List <ExpressionToken> polandCalc = new List <ExpressionToken>(rePoland.Count); for (int i = 0; i < rePoland.Count; i++) { polandCalc.Add(rePoland[i]); } while (index < polandCalc.Count) { if (polandCalc.Count == 1 && polandCalc[0].Type == TokenType.Numeric) { break; } ExpressionToken token = polandCalc[index]; switch (token.Type) { case TokenType.Numeric: if (polandCalc[index].Data == DBNull.Value) { digit.Add(null); } else { digit.Add(Convert.ToDecimal(polandCalc[index].Data)); } index++; break; //case TokenType.Variant: // //将变量替换为常量 // polandCalc[index].Data = GetVariantValue(token); // polandCalc[index].Type = TokenType.Numeric; // break; case TokenType.Operator: int paramCount = 2; //一般是二元式,需要二个参数 //函数 if (IsFunc((OperatorType)token.Data)) { FunctionBase func = FuncFactory.GetFunc((int)(OperatorType)token.Data); if (func == null) { throw new ExpressionException("不可识别的函数名."); } paramCount = func.ParamCount; } //计算前面两个数的值 if (digit.Count < paramCount) { throw new ExpressionException("缺少操作数", 1002); } //传入参数 decimal?[] data = new decimal?[paramCount]; for (int i = 0; i < paramCount; i++) { data[i] = digit[index - paramCount + i]; } polandCalc[index - paramCount].Data = CalcOperator((OperatorType)token.Data, data); //将参数从 repoland 中移除 for (int i = 0; i < paramCount; i++) { polandCalc.RemoveAt(index - i); digit.RemoveAt(index - i - 1); } index -= paramCount; break; default: break; } } if (polandCalc.Count == 1) { switch (polandCalc[0].Type) { case TokenType.Numeric: return(polandCalc[0].Data); default: throw new ExpressionException("缺少操作数", 1002); } } else { throw new ExpressionException("缺少操作符或操作数", 1002); } }