private void CheckOperand(object p1, object p2, int nPos) { if (p1 == null || p2 == null) { throw ParsingException.NewParsingException(Parse_Error.peNeedOperand, nPos); } }
/// <summary> /// 重新构造二叉树 /// </summary> /// <param name="strExpression">表达式</param> public void ChangeExpression(string strExpression) { _Expression = strExpression; _Tree = null; _Position = 0; _Identifiers = null; _CurrentIdentifier = null; _ParentIdentifier = null; if (strExpression != string.Empty) { try { _ExpressionChars = new Char[strExpression.Length + 1]; strExpression.CopyTo(0, _ExpressionChars, 0, strExpression.Length); _ExpressionChars[strExpression.Length] = '\0'; _Tree = DoExpression(); if (_ExpressionChars[_Position] != '\0') { throw ParsingException.NewParsingException(Parse_Error.peSyntaxError, _Position); } } finally { _CurrentIdentifier = null; _ParentIdentifier = null; } } }
/// <summary> /// 处理各种系数、负数、括号等 /// </summary> /// <returns></returns> private EXP_TreeNode DoFactor() { EXP_TreeNode node = null; EXP_TreeNode left = null; EXP_TreeNode node2 = null; SkipSpaces(); char ch = _ExpressionChars[_Position]; int nPos = _Position; if (ch == '-') //处理负号 { OutputID(Operation_IDs.OI_NEG, "-", _Position); _Position++; node2 = DoExpression(); left = NewTreeNode(); left._OperationID = Operation_IDs.OI_NEG; left._Value = (double)-1; left._Position = nPos; node = NewTreeNode(left, node2, Operation_IDs.OI_MUL, nPos); } else if (ch == '(') { OutputID(Operation_IDs.OI_LBRACKET, "(", _Position); _Position++; node = DoExpression(); SkipSpaces(); if (_ExpressionChars[_Position] != ')') { throw ParsingException.NewParsingException(Parse_Error.peCharExpected, _Position, ")"); } else { OutputID(Operation_IDs.OI_RBRACKET, ")", _Position); } _Position++; } else { node = DoIdentifier(); } SkipSpaces(); return(node); }
private EXP_TreeNode DoVariable() { int nPos = _Position; char ch = _ExpressionChars[++_Position]; //OutputID(Operation_IDs.OI_Variable, "$", nPos); //EXP_TreeNode node = NewTreeNode(); //node._Position = nPos; //node._OperationID = Operation_IDs.OI_Variable; //node._Params = new ArrayList(); //node._Params.Add(DoString()); //return node; StringBuilder strB = new StringBuilder(256); if (Char.IsLetter(ch)) { strB.Append(ch); ch = _ExpressionChars[++_Position]; while (Char.IsLetter(ch) || Char.IsDigit(ch) || ch == '_') { strB.Append(ch); ch = _ExpressionChars[++_Position]; } //if (ch == '\0') // throw ParsingException.NewParsingException(Parse_Error.peCharExpected, _Position, "\""); string strID = strB.ToString(); OutputID(Operation_IDs.OI_Variable, "$", nPos); EXP_TreeNode node = NewTreeNode(); node._Position = nPos; node._OperationID = Operation_IDs.OI_Variable; node._Params = new ArrayList(); EXP_TreeNode param = NewTreeNode(); param._Value = strID; param._OperationID = Operation_IDs.OI_STRING; node._Params.Add(param); OutputID(Operation_IDs.OI_STRING, strID, _Position); this.Variables.Add("$" + strID); return(node); } else { throw ParsingException.NewParsingException(Parse_Error.peInvalidChar, _Position, ""); } }
private EXP_TreeNode DoString() { int nPos = _Position; char ch = _ExpressionChars[++_Position]; StringBuilder strB = new StringBuilder(256); StringBuilder strIDB = new StringBuilder(256); strIDB.Append('"'); while (ch != '\0') { if (ch != '"') { strB.Append(ch); strIDB.Append(ch); _Position++; } else if (_ExpressionChars[_Position + 1] == '"') { strB.Append('"'); strIDB.Append("\"\""); _Position += 2; } else { strIDB.Append('"'); _Position++; break; } ch = _ExpressionChars[_Position]; } if (ch == '\0') { throw ParsingException.NewParsingException(Parse_Error.peCharExpected, _Position, "\""); } string strID = strIDB.ToString(); OutputID(Operation_IDs.OI_STRING, strID, nPos); EXP_TreeNode node = NewTreeNode(); node._Position = nPos; node._OperationID = Operation_IDs.OI_STRING; node._Value = strB.ToString(); return(node); }
private EXP_TreeNode DoDatetime() { int nPos = _Position; char ch = _ExpressionChars[++_Position]; StringBuilder strB = new StringBuilder(256); strB.Append("#"); while (ch != '\0') { strB.Append(ch); if (ch == '#') { _Position++; break; } ch = _ExpressionChars[++_Position]; } if (ch == '\0') { throw ParsingException.NewParsingException(Parse_Error.peCharExpected, _Position, "#"); } EXP_TreeNode node = NewTreeNode(); node._Position = nPos; node._OperationID = Operation_IDs.OI_DATETIME; try { string strID = strB.ToString(); node._Value = DateTime.Parse(strID); OutputID(Operation_IDs.OI_DATETIME, strID, nPos); return(node); } catch (System.FormatException) { throw ParsingException.NewParsingException(Parse_Error.peFormatError, nPos); } }
/// <summary> /// 处理各种数字、标识符、自定义函数、字符串等 /// </summary> /// <returns></returns> private EXP_TreeNode DoIdentifier() { EXP_TreeNode result = null; SkipSpaces(); char ch = _ExpressionChars[_Position]; if (ch != '\0') { if (ch == '#') //string { result = DoDatetime(); } else if (ch == '"') //string { result = DoString(); } else if (Char.IsDigit(ch) || ch == '.') { result = DoNumber(); } else if (ch == '$') { result = DoVariable(); } else if (Char.IsLetter(ch) || ch == '_') { result = DoFunctionID(); } else { throw ParsingException.NewParsingException(Parse_Error.peInvalidOperator, _Position, ch.ToString()); } SkipSpaces(); } return(result); }
private object VExp(EXP_TreeNode node) { object oValue = null; if (node != null) { try { switch (node._OperationID) { case Operation_IDs.OI_NUMBER: case Operation_IDs.OI_STRING: case Operation_IDs.OI_NEG: case Operation_IDs.OI_BOOLEAN: case Operation_IDs.OI_DATETIME: oValue = node._Value; break; case Operation_IDs.OI_ADD: oValue = AddOP(VExp(node._Left), VExp(node._Right), node._Position); break; case Operation_IDs.OI_MINUS: { object p1 = VExp(node._Left); object p2 = VExp(node._Right); CheckOperand(p1, p2, node._Position); oValue = (double)p1 - (double)p2; } break; case Operation_IDs.OI_MUL: { object p1 = VExp(node._Left); object p2 = VExp(node._Right); CheckOperand(p1, p2, node._Position); oValue = (double)p1 * (double)p2; } break; case Operation_IDs.OI_DIV: { object p1 = VExp(node._Left); object p2 = VExp(node._Right); CheckOperand(p1, p2, node._Position); oValue = (double)p1 / (double)p2; } break; case Operation_IDs.OI_LOGICAL_OR: { oValue = (bool)VExp(node._Left); object oRight = (bool)false; if (Optimize == false || (bool)oValue == false) { oRight = VExp(node._Right); } CheckOperand(oValue, oRight, node._Position); oValue = (bool)oValue || (bool)oRight; } break; case Operation_IDs.OI_LOGICAL_AND: { oValue = (bool)VExp(node._Left); object oRight = (bool)true; if (Optimize == false || (bool)oValue == true) { oRight = VExp(node._Right); } CheckOperand(oValue, oRight, node._Position); oValue = (bool)oValue && (bool)oRight; } break; case Operation_IDs.OI_NOT: oValue = VExp(node._Right); CheckOperand(oValue, node._Position); oValue = !(bool)oValue; break; case Operation_IDs.OI_GREAT: oValue = CompareGreatOP(VExp(node._Left), VExp(node._Right), node._Position); break; case Operation_IDs.OI_GREATEQUAL: oValue = CompareGreatEqualOP(VExp(node._Left), VExp(node._Right), node._Position); break; case Operation_IDs.OI_LESS: oValue = CompareLessOP(VExp(node._Left), VExp(node._Right), node._Position); break; case Operation_IDs.OI_LESSEQUAL: oValue = CompareLessEqualOP(VExp(node._Left), VExp(node._Right), node._Position); break; case Operation_IDs.OI_NOT_EQUAL: oValue = CompareNotEqualOP(VExp(node._Left), VExp(node._Right), node._Position); break; case Operation_IDs.OI_EQUAL: oValue = CompareEqualOP(VExp(node._Left), VExp(node._Right), node._Position); break; case Operation_IDs.OI_Variable: { ParamObject[] po = GetParamArray(node._Params); oValue = CalculateFunction("getValue", po, this); } break; case Operation_IDs.OI_USERDEFINE: { ParamObject[] po = GetParamArray(node._Params); oValue = CalculateFunction(node._FunctionName, po, this); } break; default: throw ParsingException.NewParsingException(Parse_Error.peInvalidOperator, node._Position); } } catch//(System.InvalidCastException ex) { throw ParsingException.NewParsingException(Parse_Error.peTypeMismatch, node._Position); } } return(oValue); }
EXP_TreeNode GetFunctionNode(Operation_IDs funcID, string strID) { EXP_TreeNode node = null; EXP_TreeNode nodeTemp = null; ArrayList paramBase = new ArrayList(4); int nStartFunction = _Position - strID.Length; OutputID(Operation_IDs.OI_USERDEFINE, strID, nStartFunction); if (_ExpressionChars[_Position] == '(') //有参数 { OutputIDToSubLevel(); OutputID(Operation_IDs.OI_LBRACKET, "(", _Position); do { _Position++; SkipSpaces(); nodeTemp = DoExpression(); if (nodeTemp != null) { paramBase.Add(nodeTemp); SkipSpaces(); } else { break; } if (_ExpressionChars[_Position] == ',') { OutputID(Operation_IDs.OI_COMMA, ",", _Position); } }while (_ExpressionChars[_Position] == ','); if (_ExpressionChars[_Position] == ')') { OutputID(Operation_IDs.OI_RBRACKET, ")", _Position); OutputIDToParentLevel(); _Position++; node = NewTreeNode(); node._Position = nStartFunction; node._Params = paramBase; node._OperationID = funcID; if (funcID == Operation_IDs.OI_USERDEFINE) { node._FunctionName = strID; } } else { throw ParsingException.NewParsingException(Parse_Error.peCharExpected, _Position, ")"); } SkipSpaces(); } else //没有参数 { node = NewTreeNode(); node._Position = nStartFunction; node._Params = paramBase; node._OperationID = funcID; if (funcID == Operation_IDs.OI_USERDEFINE) { node._FunctionName = strID; } } return(node); }
/// <summary> /// 逻辑比较运算 /// </summary> /// <returns></returns> private EXP_TreeNode DoLogicalOP() { EXP_TreeNode node = null; EXP_TreeNode node1 = DoAddSub(); EXP_TreeNode node2 = null; char op = _ExpressionChars[_Position]; string strID = ""; while (op == '>' || op == '<' || op == '=') { int nPos = _Position; Operation_IDs oID = Operation_IDs.OI_NONE; if (_ExpressionChars[++_Position] == '=') { switch (op) { case '>': //>= oID = Operation_IDs.OI_GREATEQUAL; strID = ">="; break; case '<': //<= oID = Operation_IDs.OI_LESSEQUAL; strID = "<="; break; case '=': //== oID = Operation_IDs.OI_EQUAL; strID = "=="; break; default: throw ParsingException.NewParsingException(Parse_Error.peInvalidOperator, _Position, op.ToString()); } _Position++; } else { if (_ExpressionChars[_Position] == '>') { if (op == '<') //<> { strID = "<>"; oID = Operation_IDs.OI_NOT_EQUAL; _Position++; } else { throw ParsingException.NewParsingException(Parse_Error.peInvalidOperator, _Position, op.ToString()); } } else { switch (op) { case '>': oID = Operation_IDs.OI_GREAT; strID = ">"; break; case '<': oID = Operation_IDs.OI_LESS; strID = "<"; break; default: throw ParsingException.NewParsingException(Parse_Error.peInvalidOperator, _Position, op.ToString()); } } } OutputID(oID, strID, nPos); node2 = DoAddSub(); node = NewTreeNode(node1, node2, oID, nPos); node1 = node; op = _ExpressionChars[_Position]; } return(node1); }