【設計模式】——解釋器模式

解釋器模式(interpreter),給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。ios

  解釋器模式須要解決的問題,若是一個特定類型的問題發生的頻率足夠高,那麼可能就值得將該問題的各個實例表述爲一個簡單語言中的句子。這樣就能夠構建一個解釋器,該解釋器經過解釋這些句子來解決該問題。express

#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(非終結符表達式),爲文法中的非終結符實現解釋操做。對文法中每一條規則R一、R2......Rn
//都須要一個具體的非終結符表達式類。經過實現抽象表達式的interpret()方法實現解釋操做。解釋操做以遞歸方式調用
//上面所提到的表明R一、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;
}

  當有一個語言須要解釋執行,而且可將該語言中的句子表示爲一個抽象語法樹時,可以使用解釋器模式。用瞭解釋器模式,就意味着能夠很容易地改變和擴展文法,由於該模式使用類來表示文法規則,你可使用繼承來改變或擴展該文法。也比較容易實現文法,由於定義抽象語法樹中各個節點的類的實現大致相似,這些類都易於直接編寫。解釋器模式也有不足,解釋器模式爲文法中的每一條規則至少定義了一個類,所以包含許多規則的文法可能難以管理和維護。建議當文法很是複雜時,使用其餘的技術如語法分析程序或編譯器生成器來處理。this

音樂解釋器

#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;
}
相關文章
相關標籤/搜索