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

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

解释器模式有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;
        }
    }

原文地址:https://www.cnblogs.com/topcoder/p/2305304.html