zoukankan      html  css  js  c++  java
  • 设计模式之笔记--解释器模式(Interpreter)

    解释器模式(Interpreter)

    定义

          解释器模式(Interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

    类图

    描述

    Expression:抽象表达式,声明一个所有的具体表达式都需要实现的抽象接口;这个接口主要是一个interpret()方法,称做解释操作。

    Terminal Expression:终结符表达式,实现了抽象表达式所要求的接口;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如公式R=R1+R2,R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。

    Nonterminal Expression:非终结符表达式,文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,“+"就是非终结符,解析“+”的解释器就是一个非终结符表达式。

    Context:环境,它的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,给R1赋值100,给R2赋值200,这些信息需要存放到环境中。

    应用场景

    首先输入一个加减或乘除的运算公式,比如a+b-c+a或a*b/c*a,再给每个参数赋值,最后根据公式完成运算并得到结果。

     

        /// <summary>
        /// 环境
        /// </summary>
        public class Context
        {
            private Dictionary<char, double> variable;
            public Dictionary<char, double> Variable 
            {
                get
                {
                    if (this.variable == null)
                    {
                        this.variable = new Dictionary<char, double>();
                    }
                    return this.variable;
                }
            }
        }
    
        /// <summary>
        /// 抽象表达式
        /// </summary>
        public abstract class Expression
        {
            public abstract double Interpret(Context context);
        }
    
        /// <summary>
        /// 变量,终结符表达式
        /// </summary>
        public class VariableExpression : Expression
        {
            private char key;
            public VariableExpression(char key)
            {
                this.key = key;
            }
    
            public override double Interpret(Context context)
            {
                return context.Variable[this.key];
            }
        }
    
        /// <summary>
        /// 操作符,非终结符表达式
        /// </summary>
        public abstract class OperatorExpression : Expression
        {
            protected Expression left;
            protected Expression right;
    
            public OperatorExpression(Expression left, Expression right)
            {
                this.left = left;
                this.right = right;
            }
        }
    
        public class AddExpression : OperatorExpression
        {
            public AddExpression(Expression left, Expression right)
                : base(left, right)
            { 
            
            }
    
            public override double Interpret(Context context)
            {
                return this.left.Interpret(context) + this.right.Interpret(context);
            }
        }
    
        public class SubExpression : OperatorExpression
        {
            public SubExpression(Expression left, Expression right)
                : base(left, right)
            {
    
            }
    
            public override double Interpret(Context context)
            {
                return this.left.Interpret(context) - this.right.Interpret(context);
            }
        }
    
        public class MulExpression: OperatorExpression
        {
            public MulExpression(Expression left, Expression right)
                : base(left, right)
            { 
            
            }
    
            public override double Interpret(Context context)
            {
                return this.left.Interpret(context) * this.right.Interpret(context);
            }
        }
    
        public class DivExpression: OperatorExpression
        {
            public DivExpression(Expression left, Expression right)
                : base(left, right)
            { 
            
            }
    
            public override double Interpret(Context context)
            {
                return this.left.Interpret(context) / this.right.Interpret(context);
            }
        }
    
        public class Calculator
        {
            private string expression;
            private Context context;
    
            public Calculator(string expression)
            {
                this.expression = expression;
                this.context = new Context();
            }
    
            public double Calculate()
            {
                char[] vars = this.expression.ToCharArray();
                foreach (char c in vars)
                {
                    if (c == '+' || c == '-' || c == '*' || c == '/')
                    {
                        continue;
                    }
                    if (!this.context.Variable.ContainsKey(c))
                    {
                        Console.Write(c + "=");
                        this.context.Variable.Add(c, double.Parse(Console.ReadLine()));
                    }
                }
                Expression left = new VariableExpression(vars[0]);
                Expression right = null;
                Stack<Expression> stack = new Stack<Expression>();
                stack.Push(left);
                for (int i = 1; i < vars.Length; i += 2)
                {
                    left = stack.Pop();
                    right = new VariableExpression(vars[i + 1]);
                    switch (vars[i])
                    {
                        case '+':
                            stack.Push(new AddExpression(left, right));
                            break;
                        case '-':
                            stack.Push(new SubExpression(left, right));
                            break;
                        case '*':
                            stack.Push(new MulExpression(left, right));
                            break;
                        case '/':
                            stack.Push(new DivExpression(left, right));
                            break;
                    }
                }
                double value = stack.Pop().Interpret(this.context);
                stack.Clear();
                return value;
            }
        }

    输入公式:a+b-c+a

    赋值:

    a=10
    b=5
    c=3

    运算结果:22

  • 相关阅读:
    项目进展1
    团队项目(百药食坊)介绍
    结对编程—黄金点游戏(庞思瑶&季远琦)
    WC项目
    四则运算
    Week3——Session
    Spring IOC (DI-依赖注入)
    Week2——XML
    Week2——提交表单后后台的工作
    Week1——JavaEE
  • 原文地址:https://www.cnblogs.com/zhou-yi/p/5462663.html
Copyright © 2011-2022 走看看