Пример #1
0
 public static OperatorPriority GetPriority(PhraseTypeEnum pt)
 {
     if (pt == PhraseTypeEnum.ln || pt == PhraseTypeEnum.log || pt == PhraseTypeEnum.lg)
     {
         return(OperatorPriority.P5);
     }
     else if (pt == PhraseTypeEnum.sin || pt == PhraseTypeEnum.end || pt == PhraseTypeEnum.tg ||
              pt == PhraseTypeEnum.abs || pt == PhraseTypeEnum.when || pt == PhraseTypeEnum.case_ ||
              pt == PhraseTypeEnum.atg || pt == PhraseTypeEnum.then)
     {
         return(OperatorPriority.P4);
     }
     else if (pt == PhraseTypeEnum.greater)
     {
         return(OperatorPriority.P6);
     }
     else if (pt == PhraseTypeEnum.less)
     {
         return(OperatorPriority.P6);
     }
     else if (pt == PhraseTypeEnum.equal)
     {
         return(OperatorPriority.P6);
     }
     else if (pt == PhraseTypeEnum.plus)
     {
         return(OperatorPriority.P1);
     }
     else if (pt == PhraseTypeEnum.minus)
     {
         return(OperatorPriority.P1);
     }
     else if (pt == PhraseTypeEnum.mutiple)
     {
         return(OperatorPriority.P2);
     }
     else if (pt == PhraseTypeEnum.mod || pt == PhraseTypeEnum.divide)
     {
         return(OperatorPriority.P2);
     }
     else if (pt == PhraseTypeEnum.leftbracket)
     {
         return(OperatorPriority.P0);
     }
     else if (pt == PhraseTypeEnum.sharp)
     {
         return(OperatorPriority.P0);
     }
     else
     {
         return(OperatorPriority.Unknown);
     }
 }
Пример #2
0
 /// <summary>
 /// 根据运算符返回对应的运算目数
 /// </summary>
 /// <param name="Phrase">运算符</param>
 /// <returns>运算目数</returns>
 public static OperandType OperandCount(PhraseTypeEnum pt)
 {
     //分析运算符的目数
     if (pt == PhraseTypeEnum.end || pt == PhraseTypeEnum.sin || pt == PhraseTypeEnum.when ||
         pt == PhraseTypeEnum.case_ || pt == PhraseTypeEnum.case_ || pt == PhraseTypeEnum.then ||
         pt == PhraseTypeEnum.atg || pt == PhraseTypeEnum.cbrt || pt == PhraseTypeEnum.else_ ||
         pt == PhraseTypeEnum.lg || pt == PhraseTypeEnum.ln || pt == PhraseTypeEnum.tg || pt == PhraseTypeEnum.abs || pt == PhraseTypeEnum.equal || pt == PhraseTypeEnum.greater || pt == PhraseTypeEnum.less)
     {
         return(OperandType.O1);
     }
     else if (pt == PhraseTypeEnum.divide || pt == PhraseTypeEnum.plus || pt == PhraseTypeEnum.minus ||
              pt == PhraseTypeEnum.mutiple || pt == PhraseTypeEnum.mod || pt == PhraseTypeEnum.log)
     {
         return(OperandType.O2);
     }
     else
     {
         return(OperandType.O0);
     }
 }
Пример #3
0
        /// <summary>
        /// 词法分析
        /// </summary>
        /// <returns>是否成功</returns>
        private bool Analyze()
        {
            int i = 0;
            int startpos = 0, endpos = 0;

            //设置初态
            _prestate = DFAState.S0;
            while (i < _chArray.Length)
            {
                //未知态处理,出错返回
                if (_prestate == DFAState.SX)
                {
                    _succeed = false;
                    return(false);
                }

                if (Char.IsLetter(_chArray[i]))
                {
                    //字母
                    if (_prestate == DFAState.S0)
                    {
                        //初态变字母串
                        _prestate = DFAState.S3;
                    }
                    else if (_prestate == DFAState.S1)
                    {
                        endpos = i - 1; //保存结束位置

                        ////检查字母串的匹配类型
                        //if (CheckString(startpos, endpos) == true)
                        //{
                        //    SavePhrase(startpos, endpos);
                        //    startpos = i;
                        //}
                        _prestate = DFAState.S3;
                    }
                    else if (_prestate == DFAState.S2)
                    {
                        endpos = i - 1; //保存结束位置

                        //检查字母串的匹配类型
                        if (CheckString(startpos, endpos) == true)
                        {
                            SavePhrase(startpos, endpos);
                            startpos = i;
                        }
                        _prestate = DFAState.S3;
                    }
                    else if (_prestate == DFAState.S17)
                    {
                        endpos = i - 1; //保存结束位置

                        //检查字母串的匹配类型
                        if (CheckString(startpos, endpos) == true)
                        {
                            SavePhrase(startpos, endpos);
                            startpos = i;
                        }
                        _prestate = DFAState.S3;
                    }
                    else if (_prestate != DFAState.S3)
                    {
                        //处理前一个词
                        endpos = i - 1; //保存结束位置
                        SavePhrase(startpos, endpos);
                        //非字母串转换为字母串
                        _prestate = DFAState.S3;
                        //保存开始位置
                        startpos = i;
                    }
                    else                //之前的状态为字母串DFAState.S3
                    {
                        endpos = i - 1; //保存结束位置

                        //检查字母串的匹配类型
                        if (CheckString(startpos, endpos) == true)
                        {
                            SavePhrase(startpos, endpos);
                            startpos = i;
                        }
                    }
                }
                else if (Char.IsDigit(_chArray[i]))
                {
                    //数字
                    if (_prestate == DFAState.S0)
                    {
                        //初态
                        _prestate = DFAState.S1;
                        startpos  = i;  //保存开始位置
                    }
                    else if (_prestate == DFAState.S1)
                    {
                        //整数串,状态不变
                    }
                    else if (_prestate == DFAState.S2)  //浮点数串
                    {
                        _prestate = DFAState.S2;
                    }
                    else if (_prestate == DFAState.S3)  //字母
                    {
                        _prestate = DFAState.S2;
                    }
                    else if (_prestate == DFAState.S17) //_
                    {
                        _prestate = DFAState.S2;
                    }
                    else
                    {
                        //处理前一个词
                        endpos = i - 1; //保存结束位置
                        //字符串类型检查
                        if (_prestate == DFAState.S3 && CheckString(startpos, endpos) == false)
                        {
                            return(false);       //如果前一个状态为字符串态,且字符串匹配失败,则退出
                        }
                        else
                        {
                            SavePhrase(startpos, endpos);
                        }

                        //从非数字串转换为整数串
                        _prestate = DFAState.S1;
                        //保存开始位置
                        startpos = i;
                    }
                }
                else if (_chArray[i] == '.')
                {
                    //小数点
                    if (_prestate == DFAState.S1 || _prestate == DFAState.S0)
                    {
                        _prestate = DFAState.S2;        //由整数串或初态变为浮点数串
                    }
                    else
                    {   //未知态
                        // 需要讨论: 是否保存前一个词
                        //_prestate = DFAState.SX;
                    }
                }
                else if (_chArray[i] == '_')
                {
                    _prestate = DFAState.S17;
                }
                else if (Char.IsWhiteSpace(_chArray[i]))
                {
                    //空格,跳过
                    //处理前一个词
                    endpos = i - 1;
                    //字符串类型检查
                    //if (_prestate == DFAState.S3 && CheckString(startpos, endpos) == false)
                    //    return false;	//如果前一个状态为字符串态,且字符串匹配失败,则退出
                    //else
                    SavePhrase(startpos, endpos);
                    startpos  = i + 1;
                    _prestate = DFAState.S0;
                }
                //else if (_chArray[i] == '+' || _chArray[i] == '-' || _chArray[i] == '*' || _chArray[i] == '/' || _chArray[i] == '^' || _chArray[i] == '%' || _chArray[i] == '(' || _chArray[i] == ')' || _chArray[i] == '!' || _chArray[i] == '#' || _chArray[i] == '@' || _chArray[i] == '=')
                else if (_chArray[i] == '+' || _chArray[i] == '-' || _chArray[i] == '*' || _chArray[i] == '/' || _chArray[i] == '(' || _chArray[i] == ')' || _chArray[i] == '#' || _chArray[i] == '=' || _chArray[i] == '>' || _chArray[i] == '<')
                {
                    if (_prestate != DFAState.S0)
                    {
                        //处理前一个词
                        endpos = i - 1;
                        //字符串类型检查
                        //if (_prestate == DFAState.S3 && CheckString(startpos, endpos) == false)
                        //    return false;	//如果前一个状态为字符串态,且字符串匹配失败,则退出
                        //else
                        SavePhrase(startpos, endpos);
                    }
                    if (_chArray[i] == '-')
                    {
                        if (_ps.PhraseTypeResult.Length > 0)
                        {
                            PhraseTypeEnum prept = _ps.PhraseTypeResult[_ps.PhraseTypeResult.Length - 1];
                            if (prept != PhraseTypeEnum.ax && prept != PhraseTypeEnum.bx && prept != PhraseTypeEnum.cx && prept != PhraseTypeEnum.dx && prept != PhraseTypeEnum.ex && prept != PhraseTypeEnum.fx && prept != PhraseTypeEnum.clr && prept != PhraseTypeEnum.sto && prept != PhraseTypeEnum.rightbracket && prept != PhraseTypeEnum.number)
                            {
                                _chArray[i] = '@';
                            }
                        }
                        else
                        {
                            _chArray[i] = '@';
                        }
                    }
                    if (_chArray[i] == '+')
                    {
                        _prestate = DFAState.S4;
                    }
                    else if (_chArray[i] == '-')
                    {
                        _prestate = DFAState.S5;
                    }
                    else if (_chArray[i] == '*')
                    {
                        _prestate = DFAState.S6;
                    }
                    else if (_chArray[i] == '/')
                    {
                        _prestate = DFAState.S7;
                    }
                    else if (_chArray[i] == '=')     //not support so far
                    {
                        _prestate = DFAState.S11;
                    }
                    else if (_chArray[i] == '>')     //not support so far
                    {
                        _prestate = DFAState.S11;
                    }
                    else if (_chArray[i] == '<')     //not support so far
                    {
                        _prestate = DFAState.S11;
                    }
                    else if (_chArray[i] == '%')
                    {
                        _prestate = DFAState.S8;
                    }
                    else if (_chArray[i] == '^')
                    {
                        _prestate = DFAState.S10;
                    }
                    else if (_chArray[i] == '(')
                    {
                        _prestate = DFAState.S12;
                    }
                    else if (_chArray[i] == ')')
                    {
                        _prestate = DFAState.S13;
                    }
                    else if (_chArray[i] == '!')
                    {
                        _prestate = DFAState.S9;
                    }
                    else if (_chArray[i] == '#')
                    {
                        _prestate = DFAState.S14;
                    }
                    else if (_chArray[i] == '@')
                    {
                        _prestate = DFAState.S15;
                    }

                    //保存开始位置
                    startpos = i;
                }
                else
                {
                    //未知字符,进入未知态
                    //_prestate=DFAState.SX;
                    _prestate = DFAState.S3;
                }
                i++;
            }
            return(true);
        }
Пример #4
0
 /// <summary>
 /// 添加一个词和它对应的词类
 /// </summary>
 /// <param name="phrase">词</param>
 /// <param name="pt">词类</param>
 public void AddPhraseResult(string phrase, PhraseTypeEnum pt)
 {
     _scOutput.Add(phrase);
     _stcOutput.Add(pt);
 }
Пример #5
0
 /// <summary>
 /// 添加一个词类
 /// </summary>
 /// <param name="pt">词类</param>
 public void AddPhraseType(PhraseTypeEnum pt)
 {
     _stcOutput.Add(pt);
 }
Пример #6
0
        /// <summary>
        /// 虚拟运算(不进行真实的计算)
        /// </summary>
        /// <returns>是否有错误发生</returns>
        private bool FakeCalculate()
        {
            PhraseTypeEnum pt = (PhraseTypeEnum)_optr.Pop();
            OperandType    oc = Operator.OperandCount(pt); //栈顶运算符目数

            PhraseTypeEnum temp_pt;                        //存储_op中pop出的一个符号

            switch (oc)
            {
            case OperandType.O0:        //0目运算符,不存在
                _lastOpForError = pt;
                return(false);

            //_op.Pop();
            //break;
            case OperandType.O1:        //1目运算符
                if (_opnd.Count >= 1)
                {
                    _opnd.Pop();
                    _op.Pop();          //抛出数符
                }
                else
                {       //没有足够的数符用于匹配运算符,出错
                    _lastOpForError = pt;
                    return(false);
                }
                temp_pt = (PhraseTypeEnum)_op.Pop();
                //抛出运算符,邻近符号检查
                if (Operator.OperatorCmp((PhraseTypeEnum)_op.Peek(), temp_pt) == PriorityCmpType.Unknown)
                {
                    _lastOpForError = pt;
                    return(false);
                }
                _opnd.Push(PhraseTypeEnum.number);
                _op.Push(PhraseTypeEnum.number);
                break;

            case OperandType.O2:        //2目运算符
                if (_opnd.Count >= 2)
                {
                    _opnd.Pop();
                    _opnd.Pop();
                    _op.Pop();          //抛出数符
                }
                else
                {
                    _lastOpForError = pt;
                    return(false);
                }
                temp_pt = (PhraseTypeEnum)_op.Pop();
                //抛出数符,邻近符号检查
                if (Operator.OperatorCmp((PhraseTypeEnum)_op.Peek(), temp_pt) == PriorityCmpType.Unknown)
                {
                    _lastOpForError = pt;
                    return(false);
                }
                temp_pt = (PhraseTypeEnum)_op.Pop();
                //抛出运算符,邻近符号检查
                if (Operator.OperatorCmp((PhraseTypeEnum)_op.Peek(), temp_pt) == PriorityCmpType.Unknown)
                {
                    _lastOpForError = pt;
                    return(false);
                }

                _opnd.Push(PhraseTypeEnum.number);
                _op.Push(PhraseTypeEnum.number);
                break;
            }
            return(true);
        }
Пример #7
0
        /// <summary>
        /// 检查文法
        /// </summary>
        /// <returns>是否正确</returns>
        public bool Check()
        {
            msg = string.Empty;
            _optr.Clear();
            _optr.Push(PhraseTypeEnum.sharp);   //将#作为栈操作结束标志
            _opnd.Clear();
            _op.Clear();
            _op.Push(PhraseTypeEnum.sharp);             //将#作为栈操作结束标志

            int i = 0;

            while (i < _ps.Length)
            {
                PhraseTypeEnum temp_pt = _ps.PhraseTypeResult[i];
                if (temp_pt == PhraseTypeEnum.case_)
                {
                    int n1 = -1, n2 = -1, n3 = -1, n4 = -1;
                    int k1 = -1, k2 = -1, k3 = -1, k4 = -1;
                    n1 = i + 1;
                    while (n1 < _ps.Length)
                    {
                        if (_ps.PhraseTypeResult[n1] == PhraseTypeEnum.when)
                        {
                            k1 = n1;
                            break;
                        }
                        n1++;
                    }

                    n2 = n1 + 1;
                    while (n2 < _ps.Length)
                    {
                        if (_ps.PhraseTypeResult[n2] == PhraseTypeEnum.then)
                        {
                            k2 = n2;
                            break;
                        }
                        n2++;
                    }

                    n3 = n2 + 1;
                    while (n3 < _ps.Length)
                    {
                        if (_ps.PhraseTypeResult[n3] == PhraseTypeEnum.else_)
                        {
                            k3 = n3;
                            break;
                        }
                        n3++;
                    }

                    n4 = n3 + 1;
                    while (n4 < _ps.Length)
                    {
                        if (_ps.PhraseTypeResult[n4] == PhraseTypeEnum.end)
                        {
                            k4 = n4;
                            break;
                        }
                        n4++;
                    }

                    if (k4 == -1)
                    {
                        msg = "case when then else end 语句不完整";
                        return(false);
                    }

                    if ((k4 - k3) == 1)
                    {
                        msg = "case when then else end 语句有误,else和end之间不能为空";
                        return(false);
                    }

                    if ((k3 - k2) == 1)
                    {
                        msg = "case when then else end 语句有误,then和else之间不能为空";
                        return(false);
                    }

                    if ((k2 - k1) == 1)
                    {
                        msg = "case when then else end 语句有误,when和then之间不能为空";
                        return(false);
                    }

                    i       = k4;
                    temp_pt = PhraseTypeEnum.number;
                }

                //运算前算符相邻检查
                PriorityCmpType temp_pct = (PriorityCmpType)Operator.OperatorCmp((PhraseTypeEnum)_op.Peek(), temp_pt);
                if (temp_pct == PriorityCmpType.Unknown)
                {
                    _lastOpForError = temp_pt;
                    return(false);
                }

                //假运算处理
                if (temp_pt == PhraseTypeEnum.number || temp_pt == PhraseTypeEnum.e || temp_pt == PhraseTypeEnum.pi || temp_pt == PhraseTypeEnum.ans ||
                    temp_pt == PhraseTypeEnum.ax || temp_pt == PhraseTypeEnum.bx || temp_pt == PhraseTypeEnum.cx || temp_pt == PhraseTypeEnum.dx ||
                    temp_pt == PhraseTypeEnum.ex || temp_pt == PhraseTypeEnum.fx)
                {       //是数
                    _opnd.Push(PhraseTypeEnum.number);
                    _op.Push(PhraseTypeEnum.number);
                }
                else    //是运算符
                {
                    //运算结束
                    if ((PhraseTypeEnum)_optr.Peek() == PhraseTypeEnum.sharp && temp_pt == PhraseTypeEnum.sharp)
                    {
                        break;
                    }

                    temp_pct = (PriorityCmpType)Operator.OperatorCmp2((PhraseTypeEnum)_optr.Peek(), temp_pt);
                    if (temp_pct == PriorityCmpType.Higher)
                    {
                        do
                        {
                            if (this.FakeCalculate() == false)  //虚拟运算
                            {
                                return(false);
                            }
                        } while ((PriorityCmpType)Operator.OperatorCmp2((PhraseTypeEnum)_optr.Peek(), temp_pt) == PriorityCmpType.Higher);
                        //当相邻PhraseTypeEnum优先级相等时
                        if ((PriorityCmpType)Operator.OperatorCmp2((PhraseTypeEnum)_optr.Peek(), temp_pt) == PriorityCmpType.Equal)
                        {
                            _optr.Pop();        //抛出相等的prePhraseTypeEnum
                            //对类似于(number)的情况做处理
                            PhraseTypeEnum pt1 = (PhraseTypeEnum)_op.Pop();
                            _op.Pop();
                            _op.Push(pt1);
                        }
                        else
                        {
                            _optr.Push(temp_pt);
                            _op.Push(temp_pt);
                        }
                    }
                    else if (temp_pct == PriorityCmpType.Lower)
                    {
                        _optr.Push(temp_pt);
                        _op.Push(temp_pt);
                    }
                    else if (temp_pct == PriorityCmpType.Equal)
                    {
                        _optr.Pop();
                        PhraseTypeEnum pt1 = (PhraseTypeEnum)_op.Pop();
                        _op.Pop();
                        _op.Push(pt1);
                    }
                    else
                    {           //出现了不允许相邻的符号
                        _lastOpForError = (PhraseTypeEnum)_optr.Peek();
                        return(false);
                    }
                }
                i++;
            }
            //数栈检查,如果并非只剩一个元素报错
            if (_opnd.Count != 1)
            {
                _lastOpForError = PhraseTypeEnum.unknown;
                return(false);
            }
            return(true);
        }
Пример #8
0
        /// <summary>
        /// 有间隔相邻符号比较(只包含数符)
        /// </summary>
        /// <param name="prePt">前一个符号</param>
        /// <param name="postPt">后一个符号</param>
        /// <returns>优先级比较值</returns>
        public static PriorityCmpType OperatorCmp2(PhraseTypeEnum prePt, PhraseTypeEnum postPt)
        {
            int result = _priorityTable2[(int)prePt, (int)postPt];

            return((PriorityCmpType)result);
        }