/// <summary> /// ToDateTime语句语法 ToDateTime(Expression|Operand) /// </summary> /// <param name="startLink">语句开始标记</param> /// <param name="endLink">语句结束标记</param> /// <returns></returns> public IOperand Key_ToDateTime_Analyze(TOKENLink startLink, out TOKENLink endLink) { IOperand result; List <TOKENLink> commaList; Key_analyze(startLink, out endLink, out commaList); if (commaList.Count > 0) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})表达式过多", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } result = _analyze.Analyze(startLink.Next.Next, endLink.Prev); try { Convert.ToDateTime(result.Value); } catch { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})无法将表达式转换为“datetime”", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } return(new Operand <DateTime>(EDataType.Ddatetime, Convert.ToDateTime(result.Value))); }
/// <summary> /// IF语句语法 if(JudgeExpression,TrueExpression,FalseExpression) /// JudgeExpression 为 true 返回 TrueExpression 否则 返回 FalseExpression /// </summary> /// <param name="startLink">语句开始标记</param> /// <param name="endLink">语句结束标记</param> /// <returns></returns> public IOperand Key_IF_Analyze(TOKENLink startLink, out TOKENLink endLink) { //分离表达式 List <TOKENLink> commaList; Key_analyze(startLink, out endLink, out commaList); if (commaList.Count < 2) { throw new Exception(string.Format("Error! 关键字“if”(索引:{0})缺少表达式", startLink.Token.Index.ToString())); } else if (commaList.Count > 2) { throw new Exception(string.Format("Error! 关键字“if”(索引:{0})表达式过多", startLink.Token.Index.ToString())); } //执行 JudgeExpression 表达式 - 此处必需表达式有值 IOperand judgeResult = _analyze.Analyze(startLink.Next.Next, commaList[0].Prev); if (judgeResult.Type != EDataType.Dbool) { throw new Exception(string.Format("Error! 关键字“if”(索引:{0})的逻辑表达式无法转换为“bool”", startLink.Token.Index.ToString())); } _analyze.Analyze(commaList[0].Next, commaList[1].Prev); _analyze.Analyze(commaList[1].Next, endLink.Prev); return(new Operand <Unknown>(EDataType.Dunknown, new Unknown())); }
/// <summary> /// AND,OR语句语法 and(JudgeExpression,JudgeExpression,......) /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public IOperand Key_ANDOR_Analyze(TOKENLink startLink, out TOKENLink endLink) { //分离表达式 IOperand result = null; List <TOKENLink> commaList; int count = 1; Key_analyze(startLink, out endLink, out commaList); TOKENLink link_s = startLink.Next.Next; foreach (TOKENLink comma in commaList) { result = _analyze.Analyze(link_s, comma.Prev); if (result.Type != EDataType.Dbool) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})的第{2}逻辑表达式无法转换为“bool”", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString(), count.ToString())); } link_s = comma.Next; count++; } result = _analyze.Analyze(link_s, endLink.Prev); if (result.Type != EDataType.Dbool) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})的第{2}逻辑表达式无法转换为“bool”", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString(), count.ToString())); } return(result); }
/// <summary> /// AND语句语法 and(JudgeExpression,JudgeExpression,......) /// 所有 JudgeExpression 表达式为 true 返回 true 否则 返回 false /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public IOperand Key_AND(TOKENLink startLink, out TOKENLink endLink) { //分离表达式 IOperand result = null; List <TOKENLink> commaList; Key_Analyze(startLink.Next, out endLink, out commaList); TOKENLink link_s = startLink.Next.Next; foreach (TOKENLink comma in commaList) { result = _eval.ExpressionEvaluate(link_s, comma.Prev); if (result != null && result.Type == EDataType.Dbool && ((Operand <bool>)result).TValue == false) { break; } link_s = comma.Next; } if (result == null || (result != null && result.Type == EDataType.Dbool && ((Operand <bool>)result).TValue == true)) { result = _eval.ExpressionEvaluate(link_s, endLink.Prev); } return(result); }
/// <summary> /// 分解关键字 - 包含括弧表达式 /// </summary> /// <param name="startLink">开始括弧</param> /// <param name="endLink">结束括弧</param> /// <param name="commaList">表达式分隔符列表</param> public void Key_Analyze(TOKENLink startLink, out TOKENLink endLink, out List <TOKENLink> commaList) { int i = 1; TOKENLink curLink = startLink; commaList = new List <TOKENLink>(); do { curLink = curLink.Next; if (curLink.Token.Type == ETokenType.token_operator) { if (((TOKEN <Operator>)curLink.Token).Tag.Type == EOperatorType.LeftParen) { i++; } else if (((TOKEN <Operator>)curLink.Token).Tag.Type == EOperatorType.RightParen) { i--; } } else if (i == 1 && curLink.Token.Type == ETokenType.token_separator) { commaList.Add(curLink); } }while (i != 0); endLink = curLink; }
/// <summary> /// ToDateTime语句语法 ToDateTime(Expression|Operand) /// </summary> /// <param name="startLink">语句开始标记</param> /// <param name="endLink">语句结束标记</param> /// <returns></returns> public IOperand Key_ToDateTime(TOKENLink startLink, out TOKENLink endLink) { IOperand result; List <TOKENLink> commaList; Key_Analyze(startLink.Next, out endLink, out commaList); result = _eval.ExpressionEvaluate(startLink.Next.Next, endLink.Prev); return(new Operand <DateTime>(EDataType.Ddatetime, Convert.ToDateTime(result.Value))); }
/// <summary> /// LEN语句语法 Len(Expression) /// Expression 返回值 长度 /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public IOperand Key_Len(TOKENLink startLink, out TOKENLink endLink) { IOperand result; List <TOKENLink> commaList; Key_Analyze(startLink.Next, out endLink, out commaList); result = _eval.ExpressionEvaluate(startLink.Next.Next, endLink.Prev); result = new Operand <int>(EDataType.Dint, result.ToString().Length); return(result); }
/// <summary> /// LEN语句语法 Len(Expression) /// Expression 返回值 长度 /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public IOperand Key_Len_Analyze(TOKENLink startLink, out TOKENLink endLink) { IOperand result; List <TOKENLink> commaList; Key_analyze(startLink, out endLink, out commaList); if (commaList.Count > 0) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})表达式过多", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } result = _analyze.Analyze(startLink.Next.Next, endLink.Prev); return(new Operand <int>(EDataType.Dint, 0)); }
/// <summary> /// False语句语法 false() /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public IOperand Key_False_Analyze(TOKENLink startLink, out TOKENLink endLink) { if (!(startLink.Next != null && startLink.Next.Token.Type == ETokenType.token_operator && ((TOKEN <Operator>)startLink.Next.Token).Tag.Type == EOperatorType.LeftParen && startLink.Next.Next != null && startLink.Next.Next.Token.Type == ETokenType.token_operator && ((TOKEN <Operator>)startLink.Next.Next.Token).Tag.Type == EOperatorType.RightParen)) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})附近有语法错误", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } endLink = startLink.Next.Next; return(new Operand <bool>(EDataType.Dbool, false)); }
public void Add(TOKENLink token) { if (token != null) { if (Tail != null) { Tail.Next = token; token.Prev = Tail; Tail = token; } else { Head = token; Tail = token; } } }
/// <summary> /// ToString语句语法 ToString(Expression|Operand,FormatString) /// </summary> /// <param name="startLink">语句开始标记</param> /// <param name="endLink">语句结束标记</param> /// <returns></returns> public IOperand Key_ToString(TOKENLink startLink, out TOKENLink endLink) { IOperand result; List <TOKENLink> commaList; Key_Analyze(startLink.Next, out endLink, out commaList); if (commaList.Count == 0) { result = _eval.ExpressionEvaluate(startLink.Next.Next, endLink.Prev); return(new Operand <string>(EDataType.Dstring, result.ToString())); } else { result = _eval.ExpressionEvaluate(startLink.Next.Next, commaList[0].Prev); IOperand format = _eval.ExpressionEvaluate(commaList[0].Next, endLink.Prev); return(new Operand <string>(EDataType.Dstring, ((Operand <DateTime>)result).TValue.ToString(format.ToString()))); } }
/// <summary> /// ToString语句语法 ToString(Expression|Operand,FormatString) /// </summary> /// <param name="startLink">语句开始标记</param> /// <param name="endLink">语句结束标记</param> /// <returns></returns> public IOperand Key_ToString_Analyze(TOKENLink startLink, out TOKENLink endLink) { IOperand result; List <TOKENLink> commaList; Key_analyze(startLink, out endLink, out commaList); if (commaList.Count == 0) { _analyze.Analyze(startLink.Next.Next, endLink.Prev); } else if (commaList.Count == 1) { result = _analyze.Analyze(startLink.Next.Next, commaList[0].Prev); if (result.Type != EDataType.Ddatetime) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1}) 第一表达式无法转换为“datatime”", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } IOperand format = _analyze.Analyze(commaList[0].Next, endLink.Prev); try { DateTime.Now.ToString(format.ToString()); } catch { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1}) 日期转换格式有误“{2}”", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString(), format.ToString())); } return(new Operand <string>(EDataType.Dstring, ((Operand <DateTime>)result).TValue.ToString(((TOKEN <IOperand>)commaList[0].Next.Token).Tag.ToString()))); } else { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})表达式过多", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } return(new Operand <string>(EDataType.Dstring, "")); }
/// <summary> /// Not语句语法 not(JudgeExpression) /// JudgeExpression 表达式为 true 返回 fase 否则 返回 true /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public IOperand Key_Not(TOKENLink startLink, out TOKENLink endLink) { //分离表达式 IOperand result; List <TOKENLink> commaList; Key_Analyze(startLink.Next, out endLink, out commaList); result = _eval.ExpressionEvaluate(startLink.Next.Next, endLink.Prev); if (result != null && result.Type == EDataType.Dbool && ((Operand <bool>)result).TValue == true) { result = new Operand <bool>(EDataType.Dbool, false); } else { result = new Operand <bool>(EDataType.Dbool, true); } return(result); }
private void CheckParen(TOKENLink startLink, TOKENLink endLink) { TOKENLink curLink = startLink; int cout = 0; while (true) { if (curLink.Token.Type == ETokenType.token_operator) { if (((TOKEN <Operator>)curLink.Token).Tag.Type == EOperatorType.LeftParen) { cout++; } else if (((TOKEN <Operator>)curLink.Token).Tag.Type == EOperatorType.RightParen) { cout--; } if (cout < 0) { throw new Exception(string.Format("Error! 缺少左括弧(索引:{0})", curLink.Token.Index.ToString())); } } if (curLink == endLink) { break; } curLink = curLink.Next; } if (cout > 0) { throw new Exception(string.Format("Error! 缺少“{0}”个右括弧", cout.ToString())); } }
/// <summary> /// IF语句语法 if(JudgeExpression,TrueExpression,FalseExpression) /// JudgeExpression 为 true 返回 TrueExpression 否则 返回 FalseExpression /// </summary> /// <param name="startLink">语句开始标记</param> /// <param name="endLink">语句结束标记</param> /// <returns></returns> public IOperand Key_IF(TOKENLink startLink, out TOKENLink endLink) { //分离表达式 IOperand result; List <TOKENLink> commaList; Key_Analyze(startLink.Next, out endLink, out commaList); //执行 JudgeExpression 表达式 - 此处必需表达式有值 IOperand judgeResult = _eval.ExpressionEvaluate(startLink.Next.Next, commaList[0].Prev); if (judgeResult != null && judgeResult.Type == EDataType.Dbool && ((Operand <bool>)judgeResult).TValue == true) { //执行 TrueExpression 表达式 result = _eval.ExpressionEvaluate(commaList[0].Next, commaList[1].Prev); } else { //执行 FalseExpression 表达式 result = _eval.ExpressionEvaluate(commaList[1].Next, endLink.Prev); } return(result); }
/// <summary> /// Not语句语法 not(JudgeExpression) /// JudgeExpression 表达式为 true 返回 fase 否则 返回 true /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public IOperand Key_Not_Analyze(TOKENLink startLink, out TOKENLink endLink) { //分离表达式 IOperand result; List <TOKENLink> commaList; Key_analyze(startLink, out endLink, out commaList); if (commaList.Count > 0) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})表达式过多", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } result = _analyze.Analyze(startLink.Next.Next, endLink.Prev); if (result.Type != EDataType.Dbool) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})的逻辑表达式无法转换为“bool”", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } return(result); }
/// <summary> /// 去关键字后 检查标记应用环境(不检查操作符与数据类型匹配关系) /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> private void TokenEnvirAnalyze(TOKENLink startLink, TOKENLink endLink) { TOKENLink curLink = startLink; while (true) { switch (curLink.Token.Type) { case ETokenType.token_keyword: throw new Exception(string.Format("Error! 关键字“{0}”未解析(索引:{1})", ((TOKEN <KeyWord>)curLink.Token).Tag.Value, curLink.Token.Index.ToString())); case ETokenType.token_operand: if (curLink.Prev != null && (curLink.Prev.Token.Type == ETokenType.token_operand || (curLink.Prev.Token.Type == ETokenType.token_operator && ((TOKEN <Operator>)curLink.Prev.Token).Tag.Type == EOperatorType.RightParen))) { string err = ""; if (_operandSource[curLink.Token] == null) { err = string.Format("Error! 操作数“{0}”附近有语法错误(索引:{1})", ((TOKEN <IOperand>)curLink.Token).Tag.ToString(), curLink.Token.Index.ToString()); } else { err = string.Format("Error! 关键字“{0}”附近有语法错误(索引:{1})", _operandSource[curLink.Token], curLink.Token.Index.ToString()); } throw new Exception(err); } break; case ETokenType.token_operator: EOperatorType type = ((TOKEN <Operator>)curLink.Token).Tag.Type; switch (type) { case EOperatorType.Positive: //正 case EOperatorType.Negative: //负 if (!(curLink.Next != null && (curLink.Next.Token.Type == ETokenType.token_operand || (curLink.Next.Token.Type == ETokenType.token_operator && ((TOKEN <Operator>)curLink.Next.Token).Tag.Type == EOperatorType.LeftParen)))) { throw new Exception(string.Format("Error! 一元操作符“{0}”附近有语法错误(索引:{1})", ((TOKEN <Operator>)curLink.Token).Tag.Value, curLink.Token.Index.ToString())); } break; case EOperatorType.LeftParen: if (curLink.Prev != null && (curLink.Prev.Token.Type == ETokenType.token_operand || (curLink.Prev.Token.Type == ETokenType.token_operator && ((TOKEN <Operator>)curLink.Prev.Token).Tag.Type == EOperatorType.RightParen))) { throw new Exception(string.Format("Error! 左括弧“{0}”附近有语法错误(索引:{1})", ((TOKEN <Operator>)curLink.Token).Tag.Value, curLink.Token.Index.ToString())); } break; case EOperatorType.RightParen: if (curLink.Prev == null || (curLink.Prev.Token.Type == ETokenType.token_operator && ((TOKEN <Operator>)curLink.Prev.Token).Tag.Type == EOperatorType.LeftParen)) { throw new Exception(string.Format("Error! 右括弧“{0}”附近有语法错误(索引:{1})", ((TOKEN <Operator>)curLink.Token).Tag.Value, curLink.Token.Index.ToString())); } break; default: if (!((curLink.Prev != null && (curLink.Prev.Token.Type == ETokenType.token_operand || (curLink.Prev.Token.Type == ETokenType.token_operator && ((TOKEN <Operator>)curLink.Prev.Token).Tag.Type == EOperatorType.RightParen))) && (curLink.Next != null && (curLink.Next.Token.Type == ETokenType.token_operand || (curLink.Next.Token.Type == ETokenType.token_operator && (((TOKEN <Operator>)curLink.Next.Token).Tag.Type == EOperatorType.LeftParen || ((TOKEN <Operator>)curLink.Next.Token).Tag.Type == EOperatorType.Negative || ((TOKEN <Operator>)curLink.Next.Token).Tag.Type == EOperatorType.Positive)))))) { throw new Exception(string.Format("Error! 二元操作符“{0}”附近有语法错误(索引:{1})", ((TOKEN <Operator>)curLink.Token).Tag.Value, curLink.Token.Index.ToString())); } break; } break; case ETokenType.token_separator: throw new Exception(string.Format("Error! 分隔符“{0}”只能用于关键字(索引:{1})", ((TOKEN <Separator>)curLink.Token).Tag.Value, curLink.Token.Index.ToString())); default: break; } if (curLink == endLink) { break; } else { curLink = curLink.Next; } } }
/// <summary> /// NowDate语句语法 NowDate() /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public IOperand Key_NowDate(TOKENLink startLink, out TOKENLink endLink) { endLink = startLink.Next.Next; return(new Operand <DateTime>(EDataType.Ddatetime, DateTime.Now)); }
/// <summary> /// 分解关键字 - 处理拥有逻辑表达式的关键字 /// </summary> /// <param name="startLink">关键字</param> /// <param name="endLink">结束括弧</param> /// <param name="commaList">表达式分隔符列表</param> public void Key_analyze(TOKENLink startLink, out TOKENLink endLink, out List <TOKENLink> commaList) { if (startLink.Next == null || !(startLink.Next.Token.Type == ETokenType.token_operator && ((TOKEN <Operator>)startLink.Next.Token).Tag.Type == EOperatorType.LeftParen)) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})附近有语法错误", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } int i = 1; TOKENLink curLink = startLink.Next; commaList = new List <TOKENLink>(); do { curLink = curLink.Next; if (curLink.Token.Type == ETokenType.token_operator) { if (((TOKEN <Operator>)curLink.Token).Tag.Type == EOperatorType.LeftParen) { i++; } else if (((TOKEN <Operator>)curLink.Token).Tag.Type == EOperatorType.RightParen) { i--; } } else if (i == 1 && curLink.Token.Type == ETokenType.token_separator) { if (curLink.Prev.Token.Type == ETokenType.token_operand || (curLink.Prev.Token.Type == ETokenType.token_operator && ((TOKEN <Operator>)curLink.Prev.Token).Tag.Type == EOperatorType.RightParen)) { commaList.Add(curLink); } else { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})的分隔符“,”有语法错误", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } } }while (i != 0); endLink = curLink; if (endLink.Prev.Token.Type == ETokenType.token_separator) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})的分隔符“,”有语法错误", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } if (startLink.Next.Next == endLink) { throw new Exception(string.Format("Error! 关键字“{0}”(索引:{1})缺少表达式", ((TOKEN <KeyWord>)startLink.Token).Tag.Value, startLink.Token.Index.ToString())); } }
/// <summary> /// False语句语法 false() /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public IOperand Key_False(TOKENLink startLink, out TOKENLink endLink) { endLink = startLink.Next.Next; return(new Operand <bool>(EDataType.Dbool, false)); }
/// <summary> /// 检查操作符与操作数的类型匹配 /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> private IOperand OperatorEvalAnalyze(TOKENLink startLink, TOKENLink endLink) { //先检查再进行后缀表达式转换 TokenEnvirAnalyze(startLink, endLink); TOKENLink postfixLink = _toolBox.InfixToPostfix(startLink, endLink); TOKENLink link_new = null; IToken token = null; while (postfixLink.Next != null) { postfixLink = postfixLink.Next; if (postfixLink.Token.Type == ETokenType.token_operator) { link_new = null; token = null; EOperatorType type = ((TOKEN <Operator>)postfixLink.Token).Tag.Type; switch (type) { case EOperatorType.Positive: //正 case EOperatorType.Negative: //负 IOperand operand = ((TOKEN <IOperand>)postfixLink.Prev.Token).Tag; if (operand.Type == EDataType.Ddouble || operand.Type == EDataType.Dint) { token = postfixLink.Prev.Token; } else { throw new Exception(string.Format("Error! 运算符“{0}”无法应用于“{2}”类型的操作数(索引:{1})", ((TOKEN <Operator>)postfixLink.Token).Tag.Value, postfixLink.Token.Index.ToString(), operand.Type.ToString())); } break; case EOperatorType.Plus: case EOperatorType.Minus: case EOperatorType.Multiply: case EOperatorType.Divide: case EOperatorType.Mod: if ((((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Dstring || ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Dstring) && (type == EOperatorType.Plus || type == EOperatorType.Minus)) { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <string>(EDataType.Dstring, ""), postfixLink.Token.Index); } else if ((((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Ddouble || ((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Dint) && (((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Ddouble || ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Dint)) { if ((((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Ddouble || ((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Ddouble) || (type == EOperatorType.Divide || type == EOperatorType.Mod)) { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <double>(EDataType.Ddouble, 0), postfixLink.Token.Index); } else { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <int>(EDataType.Dint, 0), postfixLink.Token.Index); } } else { throw new Exception(string.Format("Error! 运算符“{0}”无法应用于“{2}”和“{3}”类型的操作数(索引:{1})", ((TOKEN <Operator>)postfixLink.Token).Tag.Value, postfixLink.Token.Index.ToString(), ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type.ToString(), ((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type.ToString())); } break; case EOperatorType.LessThan: case EOperatorType.GreaterThan: case EOperatorType.Equal: case EOperatorType.NotEqual: case EOperatorType.GreaterEqual: case EOperatorType.LessEqual: if (((((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Ddouble || ((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Dint) && (((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Ddouble || ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Dint)) || (((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Ddatetime && ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Ddatetime) || (((((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Dstring && ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Dstring) || (((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Dbool && ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Dbool)) && (type == EOperatorType.Equal || type == EOperatorType.NotEqual))) { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <bool>(EDataType.Dbool, true), postfixLink.Token.Index); } else { throw new Exception(string.Format("Error! 运算符“{0}”无法应用于“{2}”和“{3}”类型的操作数(索引:{1})", ((TOKEN <Operator>)postfixLink.Token).Tag.Value, postfixLink.Token.Index.ToString(), ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type.ToString(), ((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type.ToString())); } break; default: break; } if (token != null) { link_new = new TOKENLink(token); link_new.Next = postfixLink.Next; if (postfixLink.Next != null) { postfixLink.Next.Prev = link_new; } if (((TOKEN <Operator>)postfixLink.Token).Tag.Dimension == 1) { //一元操作符 if (postfixLink.Prev.Prev != null) { link_new.Prev = postfixLink.Prev.Prev; postfixLink.Prev.Prev.Next = link_new; } } else if (((TOKEN <Operator>)postfixLink.Token).Tag.Dimension == 2) { //二元操作符 if (postfixLink.Prev.Prev.Prev != null) { link_new.Prev = postfixLink.Prev.Prev.Prev; postfixLink.Prev.Prev.Prev.Next = link_new; } } postfixLink = link_new; } } //end if } //end while return(((TOKEN <IOperand>)postfixLink.Token).Tag); }
/// <summary> /// 逻辑表达式求值 /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public IOperand ExpressionEvaluate(TOKENLink startLink, TOKENLink endLink) { TOKENLink curLink = startLink; while (true) { if (curLink.Token.Type == ETokenType.token_keyword) { TOKENLink endLink_key = null; IOperand result = null; switch (((TOKEN <KeyWord>)curLink.Token).Tag.Type) { case EKeyword.IF: result = _gmm.Key_IF(curLink, out endLink_key); break; case EKeyword.AND: result = _gmm.Key_AND(curLink, out endLink_key); break; case EKeyword.OR: result = _gmm.Key_OR(curLink, out endLink_key); break; case EKeyword.NOT: result = _gmm.Key_Not(curLink, out endLink_key); break; case EKeyword.FALSE: result = _gmm.Key_False(curLink, out endLink_key); break; case EKeyword.TRUE: result = _gmm.Key_True(curLink, out endLink_key); break; case EKeyword.Len: result = _gmm.Key_Len(curLink, out endLink_key); break; case EKeyword.NowDate: result = _gmm.Key_NowDate(curLink, out endLink_key); break; case EKeyword.ToDateTime: result = _gmm.Key_ToDateTime(curLink, out endLink_key); break; case EKeyword.ToDouble: result = _gmm.Key_ToDouble(curLink, out endLink_key); break; case EKeyword.ToInt: result = _gmm.Key_ToInt(curLink, out endLink_key); break; case EKeyword.ToString: result = _gmm.Key_ToString(curLink, out endLink_key); break; default: break; } TOKENLink tokenLink = new TOKENLink(new TOKEN <IOperand>(ETokenType.token_operand, result, curLink.Token.Index)); if (endLink_key != null) { //链表重构 if (curLink.Prev != null) { tokenLink.Prev = curLink.Prev; curLink.Prev.Next = tokenLink; } if (endLink_key.Next != null) { tokenLink.Next = endLink_key.Next; endLink_key.Next.Prev = tokenLink; } if (curLink == startLink) { startLink = tokenLink; } if (endLink_key == endLink) { endLink = tokenLink; } curLink = tokenLink; } // end if } //end if if (curLink == endLink) { break; } else { curLink = curLink.Next; } } if (startLink == endLink) { return(((TOKEN <IOperand>)curLink.Token).Tag); } else { return(MathEvaluate(startLink, endLink)); } }
/// <summary> /// 执行语法检查 /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public EDataType Execute(TOKENLink startLink, TOKENLink endLink) { CheckParen(startLink, endLink); return(Analyze(startLink, endLink).Type); }
/// <summary> /// 中缀表达式转后缀表达式 /// -1*6+5*(2+3) 转换成 1 - 6 * 5 2 3 + * + /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> public TOKENLink InfixToPostfix(TOKENLink startLink, TOKENLink endLink) { //进入此函数的链表 - 只含操作符和操作数 TOKENLink postfixLinkHead = null; TOKENLink postfixLinkTail = null; TOKENLink tempLink = null; TOKENLink curLink = startLink; KeyValueList <IToken, int> tokenList = new KeyValueList <IToken, int>(); int Deep_PRI = 0; //括弧深度优先级 try { while (true) { if (curLink.Token.Type == ETokenType.token_operand) { //操作数 直接放入后缀链表 TOKENLink link = new TOKENLink(curLink.Token); if (postfixLinkHead == null) { postfixLinkHead = link; postfixLinkTail = link; } else { postfixLinkTail.Next = link; link.Prev = postfixLinkTail; postfixLinkTail = link; } } else if (curLink.Token.Type == ETokenType.token_operator) { if (((TOKEN <Operator>)curLink.Token).Tag.Type == EOperatorType.LeftParen) { Deep_PRI++; } else if (((TOKEN <Operator>)curLink.Token).Tag.Type == EOperatorType.RightParen) { Deep_PRI--; } else { //将操作符放入临时链表 TOKENLink link_new = new TOKENLink(curLink.Token); tokenList.Add(link_new.Token, Deep_PRI); if (tempLink == null) { tempLink = link_new; } else { tempLink.Next = link_new; link_new.Prev = tempLink; tempLink = link_new; } //判断需要放入后缀链表的项 while (tempLink.Prev != null) { if ((tokenList[tempLink.Prev.Token] > tokenList[tempLink.Token]) || ((tokenList[tempLink.Prev.Token] == tokenList[tempLink.Token]) && (((TOKEN <Operator>)tempLink.Prev.Token).Tag.PRI >= ((TOKEN <Operator>)tempLink.Token).Tag.PRI))) { TOKENLink link_Operator = tempLink.Prev; if (tempLink.Prev.Prev != null) { tempLink.Prev.Prev.Next = tempLink; tempLink.Prev = tempLink.Prev.Prev; } else { tempLink.Prev = null; } postfixLinkTail.Next = link_Operator; link_Operator.Prev = postfixLinkTail; postfixLinkTail = link_Operator; } else { break; } } }// end if } else { throw new Exception(string.Format("Error! 后缀表达式出现未解析类型“{0}”(索引:{1})", curLink.Token.Type.ToString(), curLink.Token.Index.ToString())); } if (curLink == endLink) { break; } curLink = curLink.Next; }// end while TOKENLink link_p = tempLink; while (link_p != null) { tempLink = tempLink.Prev; postfixLinkTail.Next = link_p; link_p.Prev = postfixLinkTail; postfixLinkTail = link_p; link_p = tempLink; } postfixLinkHead.Prev = null; postfixLinkTail.Next = null; return(postfixLinkHead); } catch (Exception e) { return(null); } }
/// <summary> /// 分析函数 /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> public IOperand Analyze(TOKENLink startLink, TOKENLink endLink) { TOKENLink curLink = startLink; while (true) { if (curLink.Token.Type == ETokenType.token_keyword) { TOKENLink endLink_key = null; IOperand result = null; switch (((TOKEN <KeyWord>)curLink.Token).Tag.Type) { case EKeyword.IF: result = _gaz.Key_IF_Analyze(curLink, out endLink_key); break; case EKeyword.AND: case EKeyword.OR: result = _gaz.Key_ANDOR_Analyze(curLink, out endLink_key); break; case EKeyword.NOT: result = _gaz.Key_Not_Analyze(curLink, out endLink_key); break; case EKeyword.FALSE: result = _gaz.Key_False_Analyze(curLink, out endLink_key); break; case EKeyword.TRUE: result = _gaz.Key_True_Analyze(curLink, out endLink_key); break; case EKeyword.Len: result = _gaz.Key_Len_Analyze(curLink, out endLink_key); break; case EKeyword.NowDate: result = _gaz.Key_NowDate_Analyze(curLink, out endLink_key); break; case EKeyword.ToDateTime: result = _gaz.Key_ToDateTime_Analyze(curLink, out endLink_key); break; case EKeyword.ToDouble: result = _gaz.Key_ToDouble_Analyze(curLink, out endLink_key); break; case EKeyword.ToInt: result = _gaz.Key_ToInt_Analyze(curLink, out endLink_key); break; case EKeyword.ToString: result = _gaz.Key_ToString_Analyze(curLink, out endLink_key); break; default: break; } TOKENLink tokenLink = new TOKENLink(new TOKEN <IOperand>(ETokenType.token_operand, result, curLink.Token.Index)); _operandSource.Add(tokenLink.Token, ((TOKEN <KeyWord>)curLink.Token).Tag.Value); if (endLink_key != null) { //链表重构 if (curLink.Prev != null) { tokenLink.Prev = curLink.Prev; curLink.Prev.Next = tokenLink; } if (endLink_key.Next != null) { tokenLink.Next = endLink_key.Next; endLink_key.Next.Prev = tokenLink; } if (curLink == startLink) { startLink = tokenLink; } if (endLink_key == endLink) { endLink = tokenLink; } curLink = tokenLink; } // end if } //end if if (curLink == endLink || curLink.Next == null) { break; } else { curLink = curLink.Next; } } if (startLink == endLink) { if (startLink.Token.Type != ETokenType.token_operand) { string err = string.Empty; if (startLink.Token.Type == ETokenType.token_operator) { err = string.Format("Error! 操作符“{0}”附近有语法错误(索引:{1})", ((TOKEN <Operator>)curLink.Token).Tag.Value, curLink.Token.Index.ToString()); } else if (startLink.Token.Type == ETokenType.token_separator) { err = string.Format("Error! 分隔符“{0}”附近有语法错误(索引:{1})", ((TOKEN <Separator>)curLink.Token).Tag.Value.ToString(), curLink.Token.Index.ToString()); } else { err = string.Format("Error! 索引{0}附近有语法错误", curLink.Token.Index.ToString()); } throw new Exception(err); } return(((TOKEN <IOperand>)curLink.Token).Tag); } else { // return(OperatorEvalAnalyze(startLink, endLink)); } }
/// <summary> /// 数表达式求值 /// </summary> /// <param name="startLink"></param> /// <param name="endLink"></param> /// <returns></returns> private IOperand MathEvaluate(TOKENLink startLink, TOKENLink endLink) { TOKENLink postfixLink = _toolBox.InfixToPostfix(startLink, endLink); TOKENLink link_new = null; IToken token = null; while (postfixLink.Next != null) { postfixLink = postfixLink.Next; if (postfixLink.Token.Type == ETokenType.token_operator) { link_new = null; token = null; EOperatorType type = ((TOKEN <Operator>)postfixLink.Token).Tag.Type; switch (type) { case EOperatorType.Positive: //正 case EOperatorType.Negative: //负 IOperand operand = ((TOKEN <IOperand>)postfixLink.Prev.Token).Tag; if (type == EOperatorType.Negative) { if (operand.Type == EDataType.Dint) { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <int>(EDataType.Dint, -((Operand <int>)operand).TValue), postfixLink.Token.Index); } else if (operand.Type == EDataType.Ddouble) { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <double>(EDataType.Ddouble, -((Operand <double>)operand).TValue), postfixLink.Token.Index); } } else { token = postfixLink.Prev.Token; } break; case EOperatorType.Plus: case EOperatorType.Minus: if (((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Dstring || ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Dstring) { if (type == EOperatorType.Plus) { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <string>(EDataType.Dstring, ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.ToString() + ((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.ToString()), postfixLink.Token.Index); } else { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <string>(EDataType.Dstring, ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.ToString().Replace(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.ToString(), "")), postfixLink.Token.Index); } } else if (((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Ddouble || ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Ddouble) { if (type == EOperatorType.Plus) { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <double>(EDataType.Ddouble, Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Value) + Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Value)), postfixLink.Token.Index); } else { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <double>(EDataType.Ddouble, Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Value) - Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Value)), postfixLink.Token.Index); } } else { if (type == EOperatorType.Plus) { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <int>(EDataType.Dint, ((Operand <int>)((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag).TValue + ((Operand <int>)((TOKEN <IOperand>)postfixLink.Prev.Token).Tag).TValue), postfixLink.Token.Index); } else { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <int>(EDataType.Dint, ((Operand <int>)((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag).TValue - ((Operand <int>)((TOKEN <IOperand>)postfixLink.Prev.Token).Tag).TValue), postfixLink.Token.Index); } } break; case EOperatorType.Multiply: if (((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Ddouble || ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Ddouble) { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <double>(EDataType.Ddouble, Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Value) * Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Value)), postfixLink.Token.Index); } else { token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <int>(EDataType.Dint, ((Operand <int>)((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag).TValue * ((Operand <int>)((TOKEN <IOperand>)postfixLink.Prev.Token).Tag).TValue), postfixLink.Token.Index); } break; case EOperatorType.Divide: token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <double>(EDataType.Ddouble, Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Value) / Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Value)), postfixLink.Token.Index); break; case EOperatorType.Mod: token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <double>(EDataType.Ddouble, Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Value) % Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Value)), postfixLink.Token.Index); break; case EOperatorType.LessThan: case EOperatorType.GreaterThan: case EOperatorType.GreaterEqual: case EOperatorType.LessEqual: bool result = false; if (((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Ddatetime) { DateTime f = ((Operand <DateTime>)((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag).TValue; DateTime s = ((Operand <DateTime>)((TOKEN <IOperand>)postfixLink.Prev.Token).Tag).TValue; switch (type) { case EOperatorType.LessThan: result = f < s; break; case EOperatorType.GreaterThan: result = f > s; break;; case EOperatorType.GreaterEqual: result = f >= s; break; case EOperatorType.LessEqual: result = f <= s; break; } } else { double f = Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Value); double s = Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Value); switch (type) { case EOperatorType.LessThan: result = f < s; break; case EOperatorType.GreaterThan: result = f > s; break;; case EOperatorType.GreaterEqual: result = f >= s; break; case EOperatorType.LessEqual: result = f <= s; break; } } token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <bool>(EDataType.Dbool, result), postfixLink.Token.Index); break; case EOperatorType.Equal: case EOperatorType.NotEqual: bool r = false; if (((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Dstring && ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Dstring) { if (type == EOperatorType.Equal) { r = ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.ToString().Equals(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.ToString()); } else { r = !((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.ToString().Equals(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.ToString()); } } else if (((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Ddatetime && ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Ddatetime) { DateTime f = ((Operand <DateTime>)((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag).TValue; DateTime s = ((Operand <DateTime>)((TOKEN <IOperand>)postfixLink.Prev.Token).Tag).TValue; if (type == EOperatorType.Equal) { r = f == s; } else { r = f != s; } } else if (((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Type == EDataType.Dbool && ((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Type == EDataType.Dbool) { bool f = ((Operand <bool>)((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag).TValue; bool s = ((Operand <bool>)((TOKEN <IOperand>)postfixLink.Prev.Token).Tag).TValue; if (type == EOperatorType.Equal) { r = f == s; } else { r = f != s; } } else { double f = Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Value); double s = Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Value); if (type == EOperatorType.Equal) { r = f == s; } else { r = f != s; } } token = new TOKEN <IOperand>(ETokenType.token_operand, new Operand <bool>(EDataType.Dbool, r), postfixLink.Token.Index); break; default: break; } if (token != null) { link_new = new TOKENLink(token); link_new.Next = postfixLink.Next; if (postfixLink.Next != null) { postfixLink.Next.Prev = link_new; } if (((TOKEN <Operator>)postfixLink.Token).Tag.Dimension == 1) { //一元操作符 if (postfixLink.Prev.Prev != null) { link_new.Prev = postfixLink.Prev.Prev; postfixLink.Prev.Prev.Next = link_new; } } else if (((TOKEN <Operator>)postfixLink.Token).Tag.Dimension == 2) { //二元操作符 if (postfixLink.Prev.Prev.Prev != null) { link_new.Prev = postfixLink.Prev.Prev.Prev; postfixLink.Prev.Prev.Prev.Next = link_new; } } postfixLink = link_new; } } //end if } //end while return(((TOKEN <IOperand>)postfixLink.Token).Tag); }