定义
给定一个语言, 定于它的文法,并定义一个解释器,这个解释器使用改表示来解释语言中的句子。
类型
行为型模式
案例
像很熟知的正則表達式就是描写叙述字符串模式的一种标准语言,它为每个模式都构造了一个特定的算法。
AbstractExpression - 一个抽象的解释操作,这个接口为抽象语法树中全部的节点所共享。
TerminalExpression - 终结符表达式,实现与文法中的终结符相关联的解释操作。
NonterminalExpression - 非终结符表达式,对文法中每一条规则R1R2...Rn都须要一个NonterminalExpressoin。
Context - 上下文,包括解释器之外的一些全局信息。
比方如今有一些表达式:
PRINT MyLanguage: NEXTLINE
LOOP 2
PRINT Hello SPACE
PRINT world!
NEXTLINE- BREAK
- END
要解释这些语句,我们先用Context把他们分成一个一个的单词,然后通过IteratorExpression遍历这个Context得到每个字符,然后调用详细的解释器进行解释,比方LoopExpression, CommandExpression,当中IteratorExpression和LoopExpression是非终结符表达式,CommandExpression四终结符表达式:
Context类进行输入字符串的分解,并能获取单一表达式:
class Context {
public:
Context(const string str)
{
m_size = splitStr(str, m_strs);
}
string current()
{
return m_strs[m_size];
}
string next()
{
return m_strs[++m_size];
}
private:
vector<string> m_strs;
int m_size;
}
AbstractExpression定义了一个统一的接口:
class AbstractExpression {
public:
virtual void interpret(Context* context) = 0;
virtual void execute() = 0;
}
在IteratorExpression中进行Context中字符串的遍历,并分配合适的解释器:
class IteratorExpression : public AbstractExpression {
public:
virtual void interpret(Context* context);
virtual void execute();
private:
vector<AbstractExpression*> m_exps;
}
void IteratorExpression::interpret(Context* context)
{
while(context->current() != "END")
{
if(context->current() == "LOOP")
{
LoopExpression* loopExp = new LoopExpression(context);
m_exp.insert(loopExp);
}
else
{
CommandExpresion* cmdExp = new CommandExpression(context);
m_exps.insert(cmdExp);
}
}
}
void IteratorExpresion::execute()
{
for(int i = 0; i < m_str.size(); ++i)
m_exps[i]->execute();
}
在LoopExpression中处理LOOP和BREAK之间的内容,并分配合适的解释器:
class LoopExpression : public AbstractExpresion
{
public:
virtual void interpret(Context* context);
virtual void execute();
private:
vector<AbstractExpression*> m_exps;
int m_count;
}
void LoopExpression::interpret(Context* context)
{
while(context->current() != "BREAK")
{
if(context->current() == "LOOP")
{
m_count = context->next().toInt();
}
else
{
CommandExpresion* cmdExp = new CommandExpression(context);
m_exps.insert(cmdExp);
}
}
}
void LoopExpression::execute()
{
for(int i = 0; i < m_count; ++i)
for(int j = 0; j < m_exps.size(); ++j)
m_exps[j]->execute();
}
在CommandExpression中决定详细解释操作:
class CommandExpression : public AbstractExpression
{
public:
virtual void interpret(Context* context);
virtual void execute();
private:
string m_name;
string m_text;
}
void CommandExpression::interpret(Context* context)
{
m_name = context->current();
if(context->current() == "PRINT")
{
m_text = context->next();
}
context->next();
}
void CommandExpression::execute()
{
if(m_name == "PRINT")
cout << m_text;
else if(m_name == "NEXTLINE")
cout << endl;
else if(m_name == "SPACE")
cout << " ";
}
有了以上对类的定义,就能够输出我们想要的结果了
string str = "PRINT MyLanguage: NEXTLINE LOOP 2 PRINT Hello SPACE PRINT world! NEXTLINE BREAK END";
Context* context = new Context(str);
IteratorExpression* iterExp = new IteratorExpression();
iterExp->interpret(context);
iterExp->execute();
结果:
MyLauguage:
Hello world!
Hello world!