设计模式-行为模式-解释器模式

2020-04-30  本文已影响0人  阿棍儿_Leon

解释器模式一般用于语义解释问题。我们把问题抽象一下,这里定义一种简单的语法。这套语法规定,符号和结尾符构成表达式,只支持单个语句构成的表达式,不支持多表达式语句。那么我们可以实现一个比较简单的命令解释器,其结构如是非结尾符号+若干空格+结尾符。这里定义非结尾符号仅有2种,分别是symbolAsymbolB,结尾符是;
解释器模式要求对每个语义成分实现一个表达式子类,并实现解释方法。

以下代码定义了非结尾符号类型。

#include <iostream>

using namespace std;

enum NonTerminalSymbolType
{
    None,
    TypeA,
    TypeB,
};

以下代码定义了抽象表达式类型,子类必须实现解释方法。

class AbstractExpression
{
public:
    virtual void Interpret() = 0;
};

以下代码定义了结尾符类,解释器的工作就是分辨当前符号是否为结尾符。

class TerminalExpression:public AbstractExpression
{
private:
    string m_symbol;
    bool bValid;
public:
    static const string symbolTerminal;
    TerminalExpression(string &symbol):m_symbol(symbol),bValid(false){}
    void Interpret()
    {
        bValid = (symbolTerminal == m_symbol);
    }
    bool IsValid()
    {
        return bValid;
    }
};
const string TerminalExpression::symbolTerminal = string(";");

以下代码定义了非结尾符号类,解释器的工作就是分辨当前符号是哪一种符号。

class NonTerminalExpression:public AbstractExpression
{
private:
    string m_symbol;
    NonTerminalSymbolType m_type;
public:
    static const string symbolsNonTerminal[2];
    NonTerminalExpression(string &symbol):m_symbol(symbol),m_type(None){}
    void Interpret()
    {
        if (m_symbol == symbolsNonTerminal[0])
        {
            m_type = TypeA;
        }
        else if (m_symbol == symbolsNonTerminal[1])
        {
            m_type = TypeB;
        }
        else
        {
            m_type = None;
        }
    }
    NonTerminalSymbolType GetResult()
    {
        return m_type;
    }
};
const string NonTerminalExpression::symbolsNonTerminal[] = {string("symbolA"), string("symbolB")};

以下代码实现了一个解释器类。它的功能是拆分语句为符号,并根据语义使用对应的解释类去解释符号,最后根据解释的结果执行不同的动作。

class Interpretor
{
private:
    string command;
    void AAction()
    {
        cout<<__FUNCTION__<<endl;
    }
    void BAction()
    {
        cout<<__FUNCTION__<<endl;
    }
public:
    Interpretor(string &cmd):command(cmd){}
    static string RemoveSpace(const string &str)
    {
        for (int i = 0; i < str.length(); ++i)
        {
            if (str[i] != L' ')
            {
                if (i > 0)
                {
                    return str.substr(i, str.length()-i);
                }
                break;
            }
        }
        return str;
    }
    void Execute()
    {
        string cmd(RemoveSpace(command));
        string symbolNonTerminal;
        string symbolTerminal;
        for (int i = 0; i < cmd.length(); ++i)
        {
            if (cmd[i] == L' ')
            {
                symbolNonTerminal = cmd;
                symbolNonTerminal.resize(i);
                cmd = RemoveSpace(cmd.substr(i, cmd.length()-i));
                break;
            }
        }
        if (cmd.length() > 0)
        {
            symbolTerminal = cmd.substr(0, 1);
        }
        if (symbolNonTerminal.length() > 0 && symbolTerminal.length() > 0)
        {
            TerminalExpression TE(symbolTerminal);
            TE.Interpret();
            if (TE.IsValid())
            {
                NonTerminalExpression NTE(symbolNonTerminal);
                NTE.Interpret();
                NonTerminalSymbolType type = NTE.GetResult();
                switch (type)
                {
                case TypeA:
                    AAction();
                    break;
                case TypeB:
                    BAction();
                    break;
                case None:
                    break;
                default:
                    break;
                }
            }
        }
    }
};

以下代码测试了两个符号的命令。

int main(void)
{
    string cmdA("symbolA ;");
    Interpretor interpretA(cmdA);
    interpretA.Execute();
    string cmdB("symbolB ;");
    Interpretor interpretB(cmdB);
    interpretB.Execute();
    return 0;
}

输出

AAction
BAction
上一篇 下一篇

猜你喜欢

热点阅读