zoukankan      html  css  js  c++  java
  • 半解释器模式,解析文本+*/ ()

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

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

  • 相关阅读:
    Hadoop集群(三) Hbase搭建
    Hadoop集群(二) HDFS搭建
    Hadoop集群(一) Zookeeper搭建
    Redis Cluster 添加/删除 完整折腾步骤
    Redis Cluster在线迁移
    Hadoop分布式HA的安装部署
    Describe the difference between repeater, bridge and router.
    what is the “handover” and "soft handover" in mobile communication system?
    The main roles of LTE eNodeB.
    The architecture of LTE network.
  • 原文地址:https://www.cnblogs.com/topcoder/p/2305304.html
Copyright © 2011-2022 走看看