Esempio n. 1
0
        /// <summary>
        /// 获取后缀分词 - 用于测试分析
        /// </summary>
        public List <string> PostfixWords(TOKENLink startLink, TOKENLink endLink)
        {
            CheckParen(startLink, endLink);
            //先检查再进行后缀表达式转换
            TokenEnvirAnalyze(startLink, endLink);

            TOKENLink     link     = _toolBox.InfixToPostfix(startLink, endLink);
            List <string> wordList = new List <string>();

            while (link != null)
            {
                if (link.Token.Type == ETokenType.token_operand)
                {
                    wordList.Add(((TOKEN <IOperand>)link.Token).Tag.ToString());
                }
                else
                {
                    Operator op = ((TOKEN <Operator>)link.Token).Tag;

                    if (op.Value == "+" || op.Value == "-")
                    {
                        wordList.Add(op.Value + "  " + op.Type.ToString());
                    }
                    else
                    {
                        wordList.Add(op.Value);
                    }
                }

                link = link.Next;
            }

            return(wordList);
        }
Esempio n. 2
0
 public void Add(TOKENLink token)
 {
     if (token != null)
     {
         if (Head != null)
         {
             Tail.Next  = token;
             token.Prev = Tail;
             Tail       = token;
         }
         else
         {
             Head = token;
             Tail = token;
         }
     }
 }
Esempio n. 3
0
        /// <summary>
        /// 括弧必须成对出现,并且先有“(”才有“)”
        /// </summary>
        /// <param name="startLink"></param>
        /// <param name="endLink"></param>
        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()));
            }
        }
Esempio n. 4
0
        /// <summary>
        /// 语法分析
        /// </summary>
        /// <param name="startLink"></param>
        /// <param name="endLink"></param>
        public IOperand Analyze(TOKENLink startLink, TOKENLink endLink)
        {
            //分三步
            //1、括弧有效性判断
            //2、操作符和操作数应用环境分析
            //3、操作符好操作数匹配类型分析

            //第一步
            CheckParen(startLink, 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.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);
        }
Esempio n. 5
0
        /// <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_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)))
                    {
                        throw new Exception(string.Format("Error! 操作数“{0}”附近有语法错误(索引:{1})",
                                                          ((TOKEN <IOperand>)curLink.Token).Tag.ToString(), curLink.Token.Index.ToString()));
                    }

                    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;

                default:
                    break;
                }

                if (curLink == endLink)
                {
                    break;
                }
                else
                {
                    curLink = curLink.Next;
                }
            }
        }
Esempio n. 6
0
        /// <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;  //括弧深度优先级

            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 (((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
                }

                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);
        }
Esempio n. 7
0
        /// <summary>
        /// 表达式求值
        /// </summary>
        /// <param name="startLink"></param>
        /// <param name="endLink"></param>
        /// <returns></returns>
        public IOperand ExpressionEvaluate(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;

                        double first  = Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Prev.Token).Tag.Value);
                        double second = Convert.ToDouble(((TOKEN <IOperand>)postfixLink.Prev.Token).Tag.Value);

                        switch (type)
                        {
                        case EOperatorType.LessThan:
                            result = first < second;
                            break;

                        case EOperatorType.GreaterThan:
                            result = first > second;
                            break;;

                        case EOperatorType.GreaterEqual:
                            result = first >= second;
                            break;

                        case EOperatorType.LessEqual:
                            result = first <= second;
                            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.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);
        }