大话设计模式-第27章 其实你不懂老板的心--解释器模式

27 其实你不懂老板的心--解释器模式

27.2 解释器模式

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

如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。


AbstractExpression(抽象表达时),声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。

Abstract class AbstractExpression

{

    public abstract void Interpret(Context context);

}


TerminalExpression(终结符表达式),实现与文法中的终结符相关联的解释操作。实现抽象表达式中所要求的接口,主要是一个interpret()方法。文法中的每一个终结符都有一个具体终结符表达式与之对应。

class TerminalExpression : AbstractExpression

{

    public override void Interpret(Context context)

    {

        Console.WriteLine(“终端解释器”);

    }

}


NonterminalExpression(非终结符表达式),为文法中的非终结符实现解释操作。对文法中每一条规则R1、R2····Rn都需要一个具体的非终结符表达式类。通过实现抽象表达式的interpret()方法实现解释操作。解释操作以递归方式调用上面所提到的代表R1、R2····Rn中各个符号的实例变量。

class NonterminalExpression : AbstractExpression

{

    public override void Interpret(Context context)

    {

        Console.WriteLine(“非终端解释器”);

    }

}


Context,包含解释器之外的一些全局信息。

class Context

{

    private string input;

    public string Input

    {

        get { return input; }

        set { input = value;}

    }


    private string output;

    public string Output

    {

        get { return output; }

        set { output = value;}

    }

}

客户端代码,构建表示该文法定义的语言中一个特定的语句的抽象语法树。调用解释操作。

static void Main(string[] args)

{

    Context context = new Context();

    IList<AbstractExpression>list = new List<AbstractExpression>();


    list.Add(new TerminalExpression());

    list.Add(new NonterminalExpression());

    list.Add(new TerminalExpression());

    list.Add(new TerminalExpression());


    foreach(AbstractExpression expo in list)

    {

        exp.Interpret(context);

    }


    Console.Read();

}



27.3 解释器模式的好处

当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。


可以很容易的改变和扩展文法,因为该模式使用类来表示文法规则,你可以使用继承来改变或扩展该文法。也比较容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,这些类都易于直接编写。

解释器模式也有不足的,解释器模式为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以维护和管理。建议当文法非常复杂时,使用其他的结束如语法分析程序或编译器生成器来处理。


27.4 音乐解释器

27.5 音乐解释器实现

//演奏内容类

class PlayContext

{

    //演奏文本

    private string text;

    public string PlayText

    {

        get{ return text; }

        set{ text = value;}

    }

}


//表达式类(AbstractExpression)

abstract class Expression

{

    //解释器

    public void Interpret(PlayContext context)

    {

        if(context.PlayText.Length == 0)

        {

            return;

        }

        else

        {

            string playKey = context.PlayText.Substring(0,1);

            context.PlayText = context.PlayText.Substring(2);

            double playValue = Convert.ToDouble(context.PlayText.Substring(0,context.PlayText.IndexOf(“ “)));

            context.PlayText = context.PlayText.Substring(context.PlayText.IndexOf(“ “) + 1);


            Excute(playkey,playValue);

        }

    }

    //执行

    public abstract void Excute(string key, double value);

}


音符类(TermianalExpression)

class Note : Expression

{

    public override void Execute(string key, double value)

    {

        string note = “”;

        switch(key)

        {

            case”C”:

                note = “1”;

                break;

            case”D”:

                note = “2”;

                break;

            case”E”:

                note = “3”;

                break;

            case”F”:

                note = “4”;

                break;

            case”G”:

                note = “5”;

                break;

            case”A”:

                note = “6”;

                break;

            case”B”:

                note = “7”;

                break;

        }

        Console.Write(“{ 0 }”,note);

    }

}


音阶类(TerminalExpression)

class Scale : Expression

{

    public override void Excute(string key, double value)

    {

        string scale = “”;

        switch (Convert.ToInt32(value))

        {

            case 1:

                scale = “低音”;

                break;

            case 2:

                scale = “中音”;

                break;

            case 3:

                scale = “高音”;

                break;

        }

        Console.Write(“{ 0 }”,note);

    }

}


//客户端代码

static void Main(string[] args)

{

    PlayContext context = new PlayContext();

    //音乐-上海滩

    Console.WriteLine(“上海滩:”);

    context.PlayText = “ O 2 E 0.5 G 0.5 A 3 E 0.5”;

    Expression expression = null;

    try

    {

        while(context.PlayText.Length > 0)

        {

            string str = context.PlayText.Substring(0,1);

            switch(str)

            {

                case “0”:

                    expression = new Scale();

                    break;

                case “E”:

                case “D”:

                case “E”:

                case “F”:

                case “G”:

                case “A”:

                case “B”:

                case “P”:

                    expression = new Note();

                    break;

            }

            expression.Interpret(context);

        }

    }

    catch (Exception ex)

    {

        Console.WriteLine(ex.Message);

    }

    Console.Read();

}


现在增加一个演奏速度,要求以T代表速度

class Speed : Expression

{

    public override void Excute(string key,double)

    {

        string speed;

        if (value<500)

            speed = “快速“;

        else if (value>=1000)

            speed = “慢速“;

        else

            speed = “中速”;


        Console.Write(“{0}”,speed);

    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值