其他分享
首页 > 其他分享> > 第二十七章-解释器模式

第二十七章-解释器模式

作者:互联网

解释器模式(Interpreter): 给定一个语言,定义它的文法中的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

图片

解释器模式的好处

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

音乐解释器

图片

图片

#include <iostream>
#include<vector>
#include<string>
#include<ctime>
#include<unordered_map>

using namespace std;

class PlayContext
{
private:
    string text;
public:
    string getText() { return text; }
    void setText(string text_t) { text = text_t; }
};

class Expression
{
public:
    virtual void Interpret(PlayContext* context)
    {
        if (context->getText().size() == 0)
            return;
        else
        {
            string playKey = context->getText().substr(0, 1);
            context->setText(context->getText().substr(2));
            int i = 0, j = 0;
            string tmp = context->getText();
            while (j<tmp.size() && tmp[j] != ' ')
                j++;
            double playValue = stod(tmp.substr(i, j - i + 1));
            if(j < tmp.size())
                context->setText(tmp.substr(j + 1));
            else
                context->setText("");
            Excute(playKey[0], playValue);
        }
    }

    virtual void Excute(char key, double value) = 0;
};

class Note :public Expression
{
public:
    void Excute(char 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;
        }
        cout << note << " ";
    }
};

class Scale : public Expression
{
public:
    void Excute(char key, double value)
    {
        string scale;
        switch (int(value))
        {
        case 1:
            scale = "低音";
            break;
        case 2:
            scale = "中音";
            break;
        case 3:
            scale = "高音";
            break;
        }
        cout << scale << " ";
    }
};

class Speed :public Expression
{
public:
    void Excute(char key, double value)
    {
        string speed;
        if (value < 500)
            speed = "快速";
        else if (value >= 1000)
            speed = "慢速";
        else
            speed = "中速";
        cout << speed << " ";
    }
};


int main()
{
    PlayContext* context = new PlayContext();

    cout << "上海滩:" << endl;

    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 = nullptr;
    while (context->getText().size())
    {
        string str = context->getText().substr(0, 1);
        switch (str[0])
        {
        case 'O':
            expression = new Scale();
            break;
        case 'T':
            expression = new Speed();
            break;
        case 'C':
        case 'D':
        case 'E':
        case 'F':
        case 'G':
        case 'A':
        case 'B':
        case 'P':
            expression = new Note();
            break;
        }
        expression->Interpret(context);
    }
    
    

    

    system("pause");
    return 0;
}

标签:case,note,解释器,0.5,模式,break,context,第二十七章
来源: https://www.cnblogs.com/wfcg165/p/12060286.html