【设计模式】——解释器模式

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

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

#include <iostream>
#include <list>
using namespace std;
class Context;
//AbstractExpression(抽象表达式),声明一个抽象的解释操作,这个接口为抽象语法树中所有的结点所共享
class AbstractExpression
{
public:
    virtual void Interpret(Context *context)=0;
};
//TerminalExpression(终结符表达式),实现与文法中的终结符相关联的解释操作。实现抽象表达式中所要求的接口,
//主要是一个interpret()方法。文法中每一个终结符都有一个具体终结表达式与之相对应。
class TerminalExpression:public AbstractExpression
{
public:
    void Interpret(Context *context)
    {
        cout << "终端解释器" << endl;
    }
};
//NonterminalExpression(非终结符表达式),为文法中的非终结符实现解释操作。对文法中每一条规则R1、R2......Rn
//都需要一个具体的非终结符表达式类。通过实现抽象表达式的interpret()方法实现解释操作。解释操作以递归方式调用
//上面所提到的代表R1、R2......Rn中各个符号的实例变量
class NonterminalExpression:public AbstractExpression
{
public:
    void Interpret(Context *context)
    {
        cout << "非终端解释器" << endl;
    }
};
//Context,包含解释器之外的一些全局信息
class Context
{
private:
    string m_input;
    string m_output;
public:
    void SetInput(string input)
    {
        this->m_input=input;
    }
    string GetInput()
    {
        return m_input;
    }
    void SetOutput(string output)
    {
        this->m_output=output;
    }
    string GetOutput()
    {
        return m_output;
    }
};
//客户端代码,构建表示该文法定义的语言中一个特定的句子的抽象语法树。调用解释操作
int main()
{
    Context *context=new Context();
    list<AbstractExpression*> alist;
    alist.push_back(new TerminalExpression());
    alist.push_back(new NonterminalExpression());
    alist.push_back(new TerminalExpression());
    alist.push_back(new TerminalExpression());
    list<AbstractExpression*>::iterator iter=alist.begin();
    for(;iter!=alist.end();iter++)
        (*iter)->Interpret(context);
    return 0;
}

  当有一个语言需要解释执行,并且可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。用了解释器模式,就意味着可以很容易地改变和扩展文法,因为该模式使用类来表示文法规则,你可以使用继承来改变或扩展该文法。也比较容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,这些类都易于直接编写。解释器模式也有不足,解释器模式为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护。建议当文法非常复杂时,使用其他的技术如语法分析程序或编译器生成器来处理。

音乐解释器

#include <iostream>
#include <list>
#include <string>
#include <string.h>
#include <cstdlib>
using namespace std;
//演奏内容类
class PlayContext
{
private:
    string m_text;
public:
    void SetText(string text)
    {
        this->m_text=text;
    }
    string GetText()
    {
        return m_text;
    }
};
//表达式类
class Expression
{
public:
    void Interpret(PlayContext *context)
    {
        if(context->GetText().length()==0)
            return;
        else
        {
            string playKey=context->GetText().substr(0,1);
            context->SetText(context->GetText().substr(2));
            int nPos=context->GetText().find(" ");
            string strPlayValue=context->GetText().substr(0,nPos);
            int nPlayValue=atoi(strPlayValue.c_str());
            nPos=context->GetText().find(" ");
            context->SetText(context->GetText().substr(nPos+1));
            Execute(playKey,nPlayValue);
        }
    }
    virtual void Execute(string strKey,const int nValue)=0;
};
//音符类
class Note:public Expression
{
public:
    void Execute(string strKey,const int nValue)
    {
        char szKey[2];
        strncpy(szKey,strKey.c_str(),strKey.length());
        string note="";
        switch(szKey[0])
        {
        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;
        }
        cout << note << " ";
    }
};
//音阶类
class Scale:public Expression
{
public:
    void Execute(string key,const int value)
    {
        string strScale;
        switch(value)
        {
        case 1:
            strScale="低音";
            break;
        case 2:
            strScale="中音";
            break;
        case 3:
            strScale="高音";
            break;
        }
        cout << strScale << " ";
    }
};
//音速类
class Speed:public Expression
{
public:
    void Execute(string key,const int value)
    {
        string speed;
        if(value<500)
            speed="快速";
        else if(value>=1000)
            speed="慢速";
        else
            speed="中速";
        cout << speed << " ";
    }
};
int main()
{
    PlayContext *context=new PlayContext();
    cout << "上海滩:";
    context->SetText("T 500 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 ");
    Expression *expression=NULL;
    while(!context->GetText().empty())
    {
        string str=context->GetText().substr(0,1);
        char szKey[2];
        strncpy(szKey,str.c_str(),str.length());
        switch(szKey[0])
        {
        case 'T':
            expression=new Speed();
            break;
        case 'O':
            expression=new Scale();
            break;
        case 'C':
        case 'D':
        case 'E':
        case 'F':
        case 'G':
        case 'A':
        case 'B':
            expression = new Note();
            break;
        default:
            break;
        }
        if(NULL!=expression)
            expression->Interpret(context);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/awy-blog/p/3844408.html