24_解釋器模式

解釋器模式是一種行爲設計模式,它通過定義一個語言的文法規則,並且根據規則解釋和執行對應的語言表達式。

在解釋器模式中,通過定義抽象表達式(Abstract Expression)和具體表達式(Concrete Expression)來表示語言中的各種表達式。抽象表達式定義了表達式的解釋方法,而具體表達式則實現瞭解釋方法。

解釋器模式包含以下幾個角色:

  1. 抽象表達式(Abstract Expression):定義了表達式解釋方法的接口。

  2. 終結符表達式(Terminal Expression):實現瞭解釋方法,表示語言中的終結符表達式。

  3. 非終結符表達式(Non-terminal Expression):實現瞭解釋方法,表示語言中的非終結符表達式。

  4. 環境(Context):包含了解釋器需要的信息,負責存儲和傳遞變量的值等。

解釋器模式的工作流程如下:

  1. 定義語言的文法規則,並將每個規則抽象成一個抽象表達式。

  2. 實現具體表達式,來表示語言中的各種表達式。

  3. 根據具體情況,創建具體表達式的實例,並將其組合成一個解釋器樹。

  4. 調用解釋器樹的解釋方法,對語言表達式進行解釋和執行。

解釋器模式的優點包括:

  1. 可擴展性好,可以動態地添加新的表達式。

  2. 可以靈活地改變文法規則和解釋方法。

  3. 可以方便地實現對語言表達式的解釋和執行。

解釋器模式適用於以下情況:

  1. 有一個簡單的語言,需要解釋和執行其中的表達式。

  2. 表達式的數量和複雜度有限,且經常需要進行修改和擴展。

總之,解釋器模式是一種通過定義文法規則來解釋和執行語言表達式的設計模式。它可以靈活地對語言進行解釋和執行,適用於處理簡單的、數量有限的語言表達式。

 

案例場景:

指令:
方向:up=向上,down=向下,left=向左,right=向右
模式:move=移動,run=快速移動
距離:實際值,不解釋

表達式:string expression="up move 100 and down run 200 and left run 300";
指令格式:方向 運動模式 距離值

 

Abstract Expression

public abstract class ExpressionBase
    {
        public abstract string Interpret();
    }

 

 Terminal Expression

/// <summary>
    /// 方向模式的解釋器表達式
    /// </summary>
    public class DirectionExpression : ExpressionBase
    {
        private string content;

        public DirectionExpression(string content)
        {
            this.content = content;
        }

        public override string Interpret()
        {
            switch (content)
            {
                case "up":
                    return "向上";
                    break;
                case "down":
                    return "向下";
                    break;
                case "left":
                    return "向左";
                    break;
                case "right":
                    return "向右";
                    break;
                default:
                    return "方向錯誤";
                    break;
            }
        }
    }
/// <summary>
    /// 運動模式的解釋器表達式
    /// </summary>
    public class ModeExpression : ExpressionBase
    {
        private string content;

        public ModeExpression(string content)
        {
            this.content = content;
        }
        public override string Interpret()
        {
             if(this.content=="move")
            {
                return "移動";
            }
             else if(content=="run")
            {
                return "快速移動";
            }
             else
            {
                return "模式錯誤";
            }
        }
    }
/// <summary>
    /// 距離表達式
    /// </summary>
    public class DistanceExpression : ExpressionBase
    {
        private string content;

        public DistanceExpression(string content)
        {
            this.content = content;
        }
        public override string Interpret()
        {
            return content;
        }
    }

 

/// <summary>
    /// 終結符表達式
    /// </summary>
    public class TerminalExpression: ExpressionBase
    {
        private ExpressionBase direction, mode, distance;

        public TerminalExpression(ExpressionBase direction, ExpressionBase mode, ExpressionBase distance)
        {
            this.direction = direction;
            this.mode = mode;
            this.distance = distance;
        }

        public override string Interpret()
        {
            return string.Concat(direction.Interpret(), mode.Interpret(), distance.Interpret());
        }
    }

 

 Non-terminal Expression

/// <summary>
    /// 非終結符表達式
    /// </summary>
    public class NonTerminalExpression : ExpressionBase
    {
        private ExpressionBase left,right;

        public NonTerminalExpression(ExpressionBase left, ExpressionBase right)
        {
            this.left = left;
            this.right = right;
        }   

        public override string Interpret()
        {
            return $"{left.Interpret()}  然後  {right.Interpret()}";
        }
    }

 

Context

public class Context
    {
        private Stack<ExpressionBase> stack=new Stack<ExpressionBase>();
        private ExpressionBase direction, mode, distance, all;
        public void Execute(string content)
        {
            string[] array = content.Split(' ');
            for(int i=0;i<array.Length;i++)
            {
                if (array[i]=="and")
                {
                    ExpressionBase left=stack.Pop();
                    direction = new DirectionExpression(array[++i]);
                    mode = new ModeExpression(array[++i]);
                    distance = new DistanceExpression(array[++i]);
                    ExpressionBase right=new TerminalExpression(direction, mode, distance);
                    ExpressionBase end = new NonTerminalExpression(left, right);
                    stack.Push(end);
                }
                else
                {
                    direction= new DirectionExpression(array[i]);
                    mode = new ModeExpression(array[++i]);
                    distance = new DistanceExpression(array[++i]);
                    ExpressionBase end =new TerminalExpression(direction, mode, distance);
                    stack.Push(end);
                }
            }
            all=stack.Pop();
        }

        public string InterpretAll()
        {
            return all.Interpret();
        }
    }

 

調用

 internal class Client
    {
        public void Start()
        {
            Context context = new Context();
            string expression = "up move 100 and down run 200 and left run 300";
            context.Execute(expression);
            string result = context.InterpretAll();
            Console.WriteLine(result);
        }
    }
 static void Main(string[] args)
        {
            new Client().Start();
            Console.ReadKey();
            Console.WriteLine("Hello, World!");
        }

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章