解释器
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子.
实例
main.cc:
#include <windows.h>
#include "context.h"
#include "terminal_expression.h"
#include "operator_nonterminal_expression.h"
/*
design_pattern:"interpreter"
Two digit Four arithmetic operations.
*/
int main(){
string express = "8*4";//8+4,8-4,8*4,8/4
Context context = Context(express);
Expression *expression_num_1 = new TerminalExpression(context.expression_[0]);
Expression *expression_num_2 = new TerminalExpression(context.expression_[2]);
Expression *expression_operator = new OperatorNonTerminalExpression(expression_num_1,expression_num_2);
printf("%s=%d\n",express.c_str(),expression_operator->interpreter(context));
//clear
delete expression_num_1;
delete expression_num_2;
delete expression_operator;
system("Pause");
return 0;
}
Context:
//context.h
#ifndef HELENDP_SOURCE_CONTEXT_H_
#define HELENDP_SOURCE_CONTEXT_H_
#include <string>
using namespace std;
#define EXPRESSION_MAX_LENGTH 3
class Context{
public:
Context(string string);
~Context();
char expression_[EXPRESSION_MAX_LENGTH];//byte0:num1,byte1:operator,byte2:num2
};
#endif
//context.cc
#include "context.h"
Context::Context(string str){
if(EXPRESSION_MAX_LENGTH == str.length()){
strcpy((char*)expression_, str.c_str());
}
else
printf("Context construct error,str length is %d\n",str.length());
}
Context::~Context(){
}
Expression:
//expression.h
#ifndef HELENDP_SOURCE_EXPRESSION_H_
#define HELENDP_SOURCE_EXPRESSION_H_
#include "context.h"
class Expression{
public:
Expression();
~Expression();
virtual int interpreter(Context context) = 0;
};
#endif
//expression.cc
#include "expression.h"
Expression::Expression(){
}
Expression::~Expression(){
}
TerminalExpression:
//terminal_expression.h
#ifndef HELENDP_SOURCE_TERMINAL_EXPRESSION_H_
#define HELENDP_SOURCE_TERMINAL_EXPRESSION_H_
#include "expression.h"
class TerminalExpression : public Expression{
public:
TerminalExpression(unsigned char value);
~TerminalExpression();
int interpreter(Context context);
private:
int value_;
};
#endif
//terminal_expression.cc
#include "terminal_expression.h"
TerminalExpression::TerminalExpression(unsigned char value){
value_ = value - '0';
}
TerminalExpression::~ TerminalExpression(){
}
int TerminalExpression::interpreter(Context context){
return value_;
}
OperatorNonTerminalExpression:
//operator_nonterminal_expression.h
#ifndef HELENDP_SOURCE_OPERATOR_NONTERMINAL_EXPRESSION_H_
#define HELENDP_SOURCE_OPERATOR_NONTERMINAL_EXPRESSION_H_
#include "expression.h"
class OperatorNonTerminalExpression : public Expression{
public:
OperatorNonTerminalExpression(Expression *expression_1,Expression *expression_2);
~OperatorNonTerminalExpression();
int interpreter(Context context);
private:
unsigned char operator_;
Expression *expression_1_;
Expression *expression_2_;
};
#endif
//operator_nonterminal_expression.cc
#include "operator_nonterminal_expression.h"
OperatorNonTerminalExpression::OperatorNonTerminalExpression(Expression *expression_1,Expression *expression_2){
expression_1_ = expression_1;
expression_2_ = expression_2;
}
OperatorNonTerminalExpression::~OperatorNonTerminalExpression(){
}
int OperatorNonTerminalExpression::interpreter(Context context){
int result;
switch(context.expression_[1]){
case '+':
result = expression_1_->interpreter(context) + expression_2_->interpreter(context);
break;
case '-':
result = expression_1_->interpreter(context) - expression_2_->interpreter(context);
break;
case '*':
result = expression_1_->interpreter(context) * expression_2_->interpreter(context);
break;
case '/':
result = expression_1_->interpreter(context) / expression_2_->interpreter(context);
break;
}
return result;
}
代码和UML图(EA)工程文件,最后会整理打包上传.
UML类图
结构
- Context(Context):包含一些解释器之外的一些全局信息.
- AbstractExpression(Expression):抽象表达式.
- TerminalExpression(TerminalExpression):终结符表达式.
- NonterminalExpression(OperatorNonTerminalExpression):非终结符表达式.
优点
- 易于改变和扩展文法。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法.
- 每一条文法规则都可以表示为一个类,因此可以方便地实现一个简单的语言.
- 实现文法较为容易。在抽象语法树中每一个表达式节点类的实现方式都是相似的,这些类的代码编写都不会特别复杂,还可以通过一些工具自动生成节点类代码.
- 增加新的解释表达式较为方便。如果用户需要增加新的解释表达式只需要对应增加一个新的终结符表达式或非终结符表达式类,原有表达式类代码无须修改,符合“开闭原则”.
缺点
- 对于复杂文法难以维护。在解释器模式中,每一条规则至少需要定义一个类,因此如果一个语言包含太多文法规则,类的个数将会急剧增加,导致系统难以管理和维护,此时可以考虑使用语法分析程序等方式来取代解释器模式.
- 执行效率较低。由于在解释器模式中使用了大量的循环和递归调用,因此在解释较为复杂的句子时其速度很慢,而且代码的调试过程也比较麻烦.