/// <summary> /// 构造节点实例 /// </summary> /// <param name="value">操作数或运算符</param> public DMEWeb_ExpressionNode(string value) { this._Value = value; this._Type = ParseNodeType(value); this._PRI = GetNodeTypePRI(this.Type); this._Numeric = null; }
/// <summary> /// 判断是否是一元操作符节点 /// </summary> /// <param name="nodeType"></param> /// <returns></returns> public static bool IsUnitaryNode(DMEWeb_ExpressionNodeType nodeType) { return (nodeType == DMEWeb_ExpressionNodeType.Plus || nodeType == DMEWeb_ExpressionNodeType.Subtract); }
/// <summary> /// 获取各节点类型的优先级 /// </summary> /// <param name="nodeType"></param> /// <returns></returns> private static int GetNodeTypePRI(DMEWeb_ExpressionNodeType nodeType) { switch (nodeType) { case DMEWeb_ExpressionNodeType.LParentheses: case DMEWeb_ExpressionNodeType.RParentheses: return 9; //逻辑非是一元操作符,所以其优先级较高 case DMEWeb_ExpressionNodeType.Not: return 8; case DMEWeb_ExpressionNodeType.Mod: return 7; case DMEWeb_ExpressionNodeType.MultiPly: case DMEWeb_ExpressionNodeType.Divide: case DMEWeb_ExpressionNodeType.Power: return 6; case DMEWeb_ExpressionNodeType.Plus: case DMEWeb_ExpressionNodeType.Subtract: return 5; case DMEWeb_ExpressionNodeType.LShift: case DMEWeb_ExpressionNodeType.RShift: return 4; case DMEWeb_ExpressionNodeType.BitwiseAnd: case DMEWeb_ExpressionNodeType.BitwiseOr: return 3; case DMEWeb_ExpressionNodeType.Equal: case DMEWeb_ExpressionNodeType.Unequal: case DMEWeb_ExpressionNodeType.GT: case DMEWeb_ExpressionNodeType.LT: case DMEWeb_ExpressionNodeType.GTOrEqual: case DMEWeb_ExpressionNodeType.LTOrEqual: return 2; case DMEWeb_ExpressionNodeType.And: case DMEWeb_ExpressionNodeType.Or: return 1; default: return 0; } }
/// <summary> /// 计算节点的值 /// </summary> /// <param name="nodeType">节点的类型</param> /// <param name="data">要计算的值,有可能是两位或一位数</param> /// <returns></returns> private static object Calculate(DMEWeb_ExpressionNodeType nodeType, object[] data) { decimal d1, d2; bool b1, b2; switch (nodeType) { case DMEWeb_ExpressionNodeType.Plus: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return d1 + d2; case DMEWeb_ExpressionNodeType.Subtract: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return d1 - d2; case DMEWeb_ExpressionNodeType.MultiPly: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return d1 * d2; case DMEWeb_ExpressionNodeType.Divide: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); if (d2 == 0) throw new DivideByZeroException(); return d1 / d2; case DMEWeb_ExpressionNodeType.Power: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return Math.Pow((double)d1, (double)d2); case DMEWeb_ExpressionNodeType.Mod: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); if (d2 == 0) throw new DivideByZeroException(); return d1 % d2; case DMEWeb_ExpressionNodeType.BitwiseAnd: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return (int)d1 & (int)d2; case DMEWeb_ExpressionNodeType.BitwiseOr: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return (int)d1 | (int)d2; case DMEWeb_ExpressionNodeType.And: b1 = ConvertToBool(data[0]); b2 = ConvertToBool(data[1]); return b1 && b2; case DMEWeb_ExpressionNodeType.Or: b1 = ConvertToBool(data[0]); b2 = ConvertToBool(data[1]); return b1 || b2; case DMEWeb_ExpressionNodeType.Not: b1 = ConvertToBool(data[0]); return !b1; case DMEWeb_ExpressionNodeType.Equal: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return d1 == d2; case DMEWeb_ExpressionNodeType.Unequal: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return d1 != d2; case DMEWeb_ExpressionNodeType.GT: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return d1 > d2; case DMEWeb_ExpressionNodeType.LT: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return d1 < d2; case DMEWeb_ExpressionNodeType.GTOrEqual: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return d1 >= d2; case DMEWeb_ExpressionNodeType.LTOrEqual: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return d1 <= d2; case DMEWeb_ExpressionNodeType.LShift: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return (long)d1 << (int)d2; case DMEWeb_ExpressionNodeType.RShift: d1 = ConvertToDecimal(data[0]); d2 = ConvertToDecimal(data[1]); return (long)d1 >> (int)d2; default: return 0; } }