半解释器模式,解析文本+-*/ ()

 

前面想做一个公式编辑器,正好在学习设计模式,想起解释器模式。

解释器模式有5个角色,抽象表达式角色、终结符表达式角色、非终结符表达式角色、上下文角色、客户角色。

为什么 说我这是半解释器模式呢?

我这里以我的理解分为 上下文角色 和 表达式角色 ,因为偷懒所以没有抽象表达式角色。就造成应该分为4个解释器的合并到一个里面了。

在我这个解释器里有四个方法  OneLevel,KracketLevel,TwoLevel,ThreeLevel,分别为 %比解释、()括号解释(其中有用递归解释括号里的表达式)、*/解释、+-解释,构成了我这个解析运算功能。

下面请大家欣赏代码。。。 

解析器
using System;
using System.Collections.Generic;
using System.Text;

namespace JTK.CalculateInterpreter
{
     public  class Expression
    {
         public  void Interpret(Context context)  // 解释
        {
             try
            {
                context.Input = OneLevel(context.Input);
                context.Input = KracketLevel(context.Input);
                context.Input = TwoLevel(context.Input);
                context.Input = ThreeLevel(context.Input);
                context.Output = Convert.ToDouble(context.Input);
            }
             catch
            {
                 throw  new ExceptionExpression();
            }
        }

         private  string KracketLevel( string input) // 括号级别
        {
             // 验证括号
             if (!CommonFunction.CheckKracket(input))
            {
                 throw  new ExceptionExpression( " 括号不匹配 ");
            }
             // 去除层括号 递归调用
             while (input.IndexOf( " ) ") >  0)
            {
                 int nEndIndex = input.IndexOf( " ) ");
                 if (nEndIndex >  0)
                {
                     int nStartIndex = CommonFunction.DaoZhao( ' ( ', input.Substring( 0, nEndIndex));

                     string strSub = input.Substring(nStartIndex +  1, nEndIndex - nStartIndex -  1);
                    Expression exp =  new Expression();
                    Context context =  new Context(strSub);
                    exp.Interpret(context);
                    input = input.Replace( string.Format( " ({0}) ", strSub), context.Input);
                }
            }

             return input;
        }

         private  string OneLevel( string input) // 级别1 %
        {
             int SignPostion = input.IndexOf( " % ");
             while (SignPostion >=  0)
            {
                 string strTemp = input.Substring( 0, SignPostion);
                 int nTemp1 = CommonFunction.DaoZhao( ' + ', strTemp);
                 int nTemp2 = CommonFunction.DaoZhao( ' - ', strTemp);
                nTemp1 = nTemp1 >= nTemp2 ? nTemp1 : nTemp2;
                nTemp2 = CommonFunction.DaoZhao( ' * ', strTemp);
                nTemp1 = nTemp1 >= nTemp2 ? nTemp1 : nTemp2;
                nTemp2 = CommonFunction.DaoZhao( ' / ', strTemp);
                nTemp1 = nTemp1 >= nTemp2 ? nTemp1 : nTemp2;

                 string strResult =  "";
                 if (nTemp1 == - 1)
                {
                    strResult = strTemp.Substring( 0, strTemp.Length);
                }
                 else
                {
                    strResult = strTemp.Substring(nTemp1 +  1, strTemp.Length - nTemp1 -  1);
                }
                 double dTemp = Convert.ToDouble(strResult);
                dTemp /=  100;
                dTemp = Math.Round(dTemp,  4);
                input = input.Replace(strResult +  " % ", dTemp.ToString());
                SignPostion = input.IndexOf( " % ");
            }
             return input;
        }

         private  string TwoLevel( string input)  // 级别2 * /
        {
             string Sign =  " * ";
             int SignPostion = input.IndexOf( " * ");
             if ((SignPostion > input.IndexOf( " / ") && input.IndexOf( " / ") != - 1) || (SignPostion == - 1))
            {
                Sign =  " / ";
                SignPostion = input.IndexOf( " / ");
            }

             while (SignPostion >=  0)
            {
                 string[] strs = CommonFunction.ZhaoShuZi(input, SignPostion);
                 double dTemp =  0.0;
                 if (Sign ==  " * ")
                {
                    dTemp = Convert.ToDouble(strs[ 0]) * Convert.ToDouble(strs[ 1]);
                    dTemp = Math.Round(dTemp,  2);
                    input = input.Replace(strs[ 0] +  " * " + strs[ 1], dTemp.ToString());
                }
                 else
                {
                    dTemp = Convert.ToDouble(strs[ 0]) / Convert.ToDouble(strs[ 1]);
                    dTemp = Math.Round(dTemp,  2);
                    input = input.Replace(strs[ 0] +  " / " + strs[ 1], dTemp.ToString());
                }

                Sign =  " * ";
                SignPostion = input.IndexOf( " * ");
                 if ((SignPostion > input.IndexOf( " / ") && input.IndexOf( " / ") != - 1) || (SignPostion == - 1))
                {
                    Sign =  " / ";
                    SignPostion = input.IndexOf( " / ");
                }
            }

             return input;
        }

         private  string ThreeLevel( string input)  // 级别 3 + -
        {
             string Sign =  " + ";
             int SignPostion = input.IndexOf( " + ");
             if ((SignPostion > input.IndexOf( " - ") && input.IndexOf( " - ") != - 1) || (SignPostion == - 1))
            {
                Sign =  " - ";
                SignPostion = input.IndexOf( " - ");
            }

             while (SignPostion >  0)
            {
                 string[] strs = CommonFunction.ZhaoShuZi(input, SignPostion);
                 double dTemp =  0.0;
                 if (Sign ==  " + ")
                {
                    dTemp = Convert.ToDouble(strs[ 0]) + Convert.ToDouble(strs[ 1]);
                    dTemp = Math.Round(dTemp,  2);
                    input = input.Replace(strs[ 0] +  " + " + strs[ 1], dTemp.ToString());
                }
                 else
                {
                    dTemp = Convert.ToDouble(strs[ 0]) - Convert.ToDouble(strs[ 1]);
                    dTemp = Math.Round(dTemp,  2);
                    input = input.Replace(strs[ 0] +  " - " + strs[ 1], dTemp.ToString());
                }

                Sign =  " + ";
                SignPostion = input.IndexOf( " + ");
                 if ((SignPostion > input.IndexOf( " - ") && input.IndexOf( " - ") != - 1) || (SignPostion == - 1))
                {
                    Sign =  " - ";
                    SignPostion = input.IndexOf( " - ");
                }
            }

             return input;
        }
    }

     public  class ExceptionExpression : Exception
    {
         string message =  "";
         public ExceptionExpression()
        {
        }

         public ExceptionExpression(String Message)
        {
            message = Message;
        }

         public  override  string Message
        {
             get
            {
                 if (message !=  ""return message;
                 return  " 表达式错误 ";
            }
        }
    }
}


公共函数

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace JTK.CalculateInterpreter
{
     public  class CommonFunction
    {
         public  static  int DaoZhao( char separator,  string txt)
        {
             int length = txt.Length -  1;
             for ( int i = length; i >=  0; i--)
            {
                 if (txt[i].CompareTo(separator) ==  0)
                {
                     return i;
                }
            }
             return - 1;
        }

         public  static  string[] ZhaoShuZi( string txt,  int postion)
        {
             string[] strs = txt.Split( ' + '' - '' * '' / ');
             int n =  0;
             for ( int i =  0; i < txt.Length; i++)
            {
                 switch (txt[i])
                {
                     case  ' + ':
                        n++;
                         break;
                     case  ' - ':
                        n++;
                         break;
                     case  ' * ':
                        n++;
                         break;
                     case  ' / ':
                        n++;
                         break;
                }
                 if (i == postion)
                {
                     break;
                }

            }

             string[] strsResult =  new  string[ 2];
            strsResult[ 0] = strs[n -  1];
            strsResult[ 1] = strs[n];
             return strsResult;
        }

         public  static  bool CheckKracket( string InputString)
        {
             bool isok =  true;
            Stack stack =  new Stack();
             for ( int i =  0; i < InputString.Length; i++)
            {
                 if (InputString[i].ToString() ==  " ( ")
                {
                    stack.Push(i);
                }
                 if (InputString[i].ToString() ==  " ) ")
                {
                     try
                    {
                        stack.Pop();
                    }
                     catch
                    {
                        isok =  false;
                         break;
                    }
                }
            }
             if (isok)
            {
                 if (stack.Count ==  0) {  return  true; }  else {  return  false; };
            }
             else
            {
                 return  false;
            }

        }
    }


被解析

namespace JTK.CalculateInterpreter
{
     public  class Context
    {
         private  string _input;

         public  string Input
        {
             get {  return _input; }
             set { _input = value; }
        }
         private  double _output;

         public  double Output
        {
             get {  return _output; }
             set { _output = value; }
        }

         public Context( string input)
        {
             this._input = input;
        }
    }

你可能感兴趣的:(解析)