设计模式---行为类型---解释器
2016-07-23 14:29
369 查看
1、意图
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释器语言中的句子。
2、动机
如果一种特定类型的问题发生的频率够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
3、适用性
当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好:
1)该文法简单对于复杂的文法,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。
2)效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。
4、C++实例
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释器语言中的句子。
2、动机
如果一种特定类型的问题发生的频率够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
3、适用性
当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好:
1)该文法简单对于复杂的文法,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。
2)效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。
4、C++实例
// Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <atlstr.h> #include <iostream> #include <string> #include <map> using namespace std; #define false 0 #define true 1 class Context; class BooleanExp { public: BooleanExp() { } virtual ~BooleanExp() { } virtual bool Evaluate( Context& ) =0; virtual BooleanExp* Replace( const char *, BooleanExp& ) =0; virtual BooleanExp* Copy() const = 0; virtual void GetName( std::string& name ) = 0; }; class VariableExp:public BooleanExp { public: VariableExp() { } VariableExp(const char *); VariableExp( const VariableExp& exp ) { _name = new char[strlen(exp._name)+1]; strcpy(_name, exp._name); } VariableExp& operator =( const VariableExp & exp ) { return *this; } virtual ~VariableExp(); virtual bool Evaluate( Context& ); virtual BooleanExp* Replace( const char *, BooleanExp& ) ; virtual BooleanExp* Copy() const ; virtual void GetName( std::string& name ); private: char *_name; }; VariableExp::VariableExp( const char * name ) { _name = new char[ strlen(name) + 1 ]; if ( NULL != _name ) { memset( _name, 0 , strlen(name) + 1 ); strncpy( _name, name, strlen( name ) + 1 ); } } VariableExp::~VariableExp() { if ( NULL != _name ) { delete []_name; _name = NULL; } } class Context { public: bool Lookup( const char* name ) const; void Assign( VariableExp* variable, bool bvalue); private: map< VariableExp*, bool > _map_varbool; }; bool VariableExp::Evaluate( Context& aContext ) { return aContext.Lookup( _name ); } BooleanExp* VariableExp::Replace( const char *name, BooleanExp& exp ) { if ( 0 == strcmp( name, _name ) ) { return exp.Copy(); } else { return new VariableExp( _name ); } } BooleanExp* VariableExp::Copy() const { return new VariableExp( _name ); } void VariableExp::GetName( std::string& name ) { name = _name; } void Context::Assign( VariableExp* variable, bool bvalue ) { _map_varbool.insert( map< VariableExp*, bool >::value_type( variable, bvalue ) ); } bool Context::Lookup( const char* name ) const { map< VariableExp*, bool >::const_iterator it = _map_varbool.begin(); for ( ; it != _map_varbool.end(); it++ ) { VariableExp *pVariable = ( it->first ); std::string strname = ""; pVariable->GetName( strname ); if ( 0 == strname.compare( name ) ) { printf("Context::Lookup name %s, value %d \r\n", name, it->second ); return it->second; } } return false; } class AndExp:public BooleanExp { public: AndExp( BooleanExp* op1, BooleanExp* op2 ) { _operand1 = op1; _operand2 = op2; } virtual ~AndExp() { } virtual bool Evaluate( Context& ); virtual BooleanExp* Replace( const char *, BooleanExp& ); virtual BooleanExp* Copy() const ; virtual void GetName( std::string &name ) { } private: BooleanExp* _operand1; BooleanExp* _operand2; }; bool AndExp::Evaluate( Context& aContext) { bool result= _operand1->Evaluate( aContext ) && _operand2->Evaluate( aContext ); printf("AndExp::Evaluate %d\r\n", result ); return result; } BooleanExp* AndExp::Replace( const char *name, BooleanExp& exp) { return new AndExp( _operand1->Replace( name, exp ), _operand2->Replace( name, exp ) ); } BooleanExp* AndExp::Copy() const { return new AndExp( _operand1->Copy(), _operand2->Copy() ); } class NotExp:public BooleanExp { public: NotExp( BooleanExp* op ) { _operand = op; } virtual ~NotExp() { } virtual bool Evaluate( Context& ); virtual BooleanExp* Replace( const char *, BooleanExp& ); virtual BooleanExp* Copy() const ; virtual void GetName( std::string& name ) { } private: BooleanExp* _operand; }; bool NotExp::Evaluate( Context& aContext) { bool result= !(_operand->Evaluate( aContext )); printf("NotExp::Evaluate %d\r\n", result ); return result; } BooleanExp* NotExp::Replace( const char *name, BooleanExp& exp) { return new NotExp( _operand->Replace( name, exp ) ); } BooleanExp* NotExp::Copy() const { return new NotExp( _operand->Copy() ); } class OrExp:public BooleanExp { public: OrExp( BooleanExp* op1, BooleanExp* op2 ) { _operand1 = op1; _operand2 = op2; } virtual ~OrExp() { } virtual bool Evaluate( Context& ); virtual BooleanExp* Replace( const char *, BooleanExp& ); virtual BooleanExp* Copy() const ; virtual void GetName( std::string& name ) { } private: BooleanExp* _operand1; BooleanExp* _operand2; }; bool OrExp::Evaluate( Context& aContext) { return _operand1->Evaluate( aContext ) | _operand2->Evaluate( aContext ); } BooleanExp* OrExp::Replace( const char *name, BooleanExp& exp) { return new OrExp( _operand1->Replace( name, exp ), _operand2->Replace( name, exp ) ); } BooleanExp* OrExp::Copy() const { return new OrExp( _operand1->Copy(), _operand2->Copy() ); } int _tmain(int argc, _TCHAR* argv[]) { // ( not y ) 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 NotExp( y ), x ), new AndExp( y, new NotExp( x ) ) ); context.Assign( x, false ); context.Assign( y, true ); bool result = expression->Evaluate( context ); return 0; }
相关文章推荐
- LeetCode#13 Roman to Integer
- Google C++编程规范--《空格的使用》
- android stutio tabactivity基础
- IE
- hdoj 2035 人见人爱A^B [快速幂 模板题]
- Linux实用命令笔记
- 排序算法
- 资源在Windows编程中的应用
- Codeforces Round #364 (Div. 2) A
- AbstractAxis QML 类型翻译
- 10Mbps以太网的帧长度
- SQL练习题
- JAVA设计模式---模板方法
- leetcode_c++:栈: Basic Calculator(224)
- Ubuntu 14.04 LTS + Qt 5.2.1 源码编译搭建环境
- 棋盘游戏(三子棋)
- ViewGroup.LayoutParams
- 嵌入式 Linux下永久生效环境变量bashrc
- 多媒体文件格式之FLV
- 第一周学习笔记4