设计模式学习笔记(十七)——Interpreter解释器

十五、Interpreter(解释器)

情景举例:

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

代码示例:

/* 该例子以布尔表达式的文法为例,文法如下:
     
     
BooleanExp = VariableExp|Constant|OrExp|AndExp|NotExp|’(BooleanExp)’
    
    
AndExp = BooleanExp ‘and’ BooleanExp
    
    
OrExp = BooleanExp ‘or’ BooleanExp
    
    
NotExp = ‘not’ BooleanExp
    
    
Constant = true|false
    
    
VariableExp = A|B|C|……|X|Y|Z
    
    
*/
/* 所有布尔运算的公共父类
     
     
*/
class BooleanExp {
public:
    BooleanExp();
    virtual ~BooleanExp();
/*
*/
    virtual bool Evaluate(Context&) = 0;
    virtual BooleanExp* Replace(const char*, BooleanExp&) = 0;
    virtual BooleanExp* Copy() const = 0;
};
/* 这个类保存了VariableExp到布尔值的映射(与整体结构无关,仅为实现方便)
     
     
*/
class Context {
public:
    bool Lookup(const char*) const;
    void Assign(VariableExp*, bool);
};
/* VariableExp的类声明
     
     
*/
class VariableExp : public BooleanExp {
public:
    VariableExp(const char*);
    virtual ~VariableExp();
/*
*/
    virtual bool Evaluate(Context&);
    virtual BooleanExp* Replace(const char*, BooleanExp&);
    virtual BooleanExp* Copy() const;
private:
    char* _name;
};
/* VariableExp由一个名字(从AZ)作为构造函数参数,并在计算结果时直
     
     
* 接根据名字从上下文Lookup出一个布尔值
*/
VariableExp::VariableExp (const char* name) {
    _name = strdup(name);
}
/*
*/
bool VariableExp::Evaluate (Context& aContext) {
    return aContext.Lookup(_name);
}
/*
*/
BooleanExp* VariableExp::Copy () const {
    return new VariableExp(_name);
}
/* Replace的时候当发现待替换变量名就是本对象名时才执行替换,否则直接
     
     
* 返回本对象
     
     
*/
BooleanExp* VariableExp::Replace (
    const char* name, BooleanExp& exp
) {
    if (strcmp(name, _name) == 0) {
        return exp.Copy();
    } else {
        return new VariableExp(_name);
   }
}
/* “与”操作,其实现基本上递归调用左右2个操作数
     
     
*/
class AndExp : public BooleanExp {
public:
    AndExp(BooleanExp*, BooleanExp*);
    virtual ~ AndExp();
/*
*/
    virtual bool Evaluate(Context&);
    virtual BooleanExp* Replace(const char*, BooleanExp&);
    virtual BooleanExp* Copy() const;
private:
    BooleanExp* _operand1;
    BooleanExp* _operand2;
};
/*
*/
AndExp::AndExp (BooleanExp* op1, BooleanExp* op2) {
    _operand1 = op1;
    _operand2 = op2;
}
/*
*/
bool AndExp::Evaluate (Context& aContext) {
    return
        _operand1->Evaluate(aContext) &&
        _operand2->Evaluate(aContext);
}
/*
*/
BooleanExp* AndExp::Copy () const {
    return
        new AndExp(_operand1->Copy(), _operand2->Copy());
}
/*
*/
BooleanExp* AndExp::Replace (const char* name, BooleanExp& exp) {
    return
        new AndExp(
            _operand1->Replace(name, exp),
            _operand2->Replace(name, exp)
        );
}
/* 下面是常数、或操作、否操作的接口,其实现略
     
     
*/
class Constant : public  BooleanExp {
public:
    Constant(int v) { _value = v; };

  
  
   
    
  
  
    virtual bool Evaluate(Context&);
    virtual BooleanExp* Replace(const char*, BooleanExp&);
    virtual BooleanExp* Copy() const;
private:
    int _value;
};

  
  
   
    
  
  
class OrExp : public BooleanExp {
public:
    OrExp(BooleanExp*, BooleanExp*);
    virtual ~ OrExp();

  
  
   
    
  
  
    virtual bool Evaluate(Context&);
    virtual BooleanExp* Replace(const char*, BooleanExp&);
    virtual BooleanExp* Copy() const;
private:
    BooleanExp* _operand1;
    BooleanExp* _operand2;
};

  
  
   
    
  
  
class NotExp : public BooleanExp {
public:
    NotExp(BooleanExp*);
    virtual ~ NotExp();

  
  
   
    
  
  
    virtual bool Evaluate(Context&);
    virtual BooleanExp* Replace(const char*, BooleanExp&);
    virtual BooleanExp* Copy() const;
private:
    BooleanExp* _operand;
};
main () {
/* 主程序中定义表达式:(true and x) or (y and (not x))
     
     
*/
BooleanExp* expression;
Context context;

  
  
   
    
  
  
VariableExp* x = new VariableExp("X");
VariableExp* y = new VariableExp("Y");

  
  
   
    
  
  
expression = new OrExp(
    new AndExp(new Constant(true), x),
    new AndExp(y, new NotExp(x))
);
/* xy赋值然后计算结果
     
     
*/
context.Assign(x, false);
context.Assign(y, true);

  
  
   
    
  
  
bool result = expression->Evaluate(context);
/* not z代替原先的y然后重新计算
     
     
*/
BooleanExp* replacement;
VariableExp* z = new VariableExp("Z");

  
  
   
    
  
  
replacement = new NotExp(z);
expression->Replace("Y", *replacement);

  
  
   
    
  
  
context.Assign(z, true);

  
  
   
    
  
  
result = expression ->Evaluate(context);
/*
*/
}

 

个人理解:

解释器模式中,非终结符与终结符都继承自公共的抽象父类。非终结符的操作部分递归调用直至终结符完成整个操作。而另外一个比较难懂晦涩的地方就是Context类,该类映射了具体语法在上下文中的具体取值,可以看到在模式结构中,各解释器类都以该类作参数。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值