設計模式之筆記--解釋器模式(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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM