定义:
定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
角色划分:
AbstractExpression——抽象解释器
实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。具体到我们例子就是VarExpression类,表达式中的每个终结符都在栈中产生了一个VarExpression对象。
TerminalExpression——终结符表达式
实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。具体到我们例子就是VarExpression类,表达式中的每个终结符都在栈中产生了一个VarExpression对象。
NonterminalExpression——非终结符表达式
文法中的每条规则对应于一个非终结表达式,具体到我们的例子就是加减法规则分别对应到AddExpression和SubExpression两个类。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。
Context——环境角色
具体到我们的例子中是采用HashMap代替。
通用示例代码:
/**
* 解释器模式
* 抽象表达式
*/
public abstract class Expression {
//每个表达式必须有一个表达任务
public abstract Object interpreter(Context context);
}
/**
* 解释器模式
* 非终结符表达式
*/
public class NotTerminaExpression extends Expression {
//每个非终结表达式都会对其他表达式产生依赖
public NotTerminaExpression(Expression ...expressions){
}
@Override
public Object interpreter(Context context) {
//进行文本处理
return null;
}
}
/**
* 解释器模式
* 终结符表达式
*/
public class TerminalExpression extends Expression {
//通常终结符表达式只有一个,但是有多个对象
@Override
public Object interpreter(Context context) {
return null;
}
}
/**
* 解释器模式
* 环境角色
*/
public class Context {
}
/**
* 解释器模式
*/
public class Client {
public static void main(String[] args) {
Context context = new Context();
Stack<Expression> stack = null;
for (;;){
//进行语法判断,递归调用
}
Expression exp = stack.pop();
exp.interpreter(context);
}
}
总结:
优点:
解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了。
缺点:
- 解释器模式会引起类膨胀
- 解释器模式采用递归调用方法
- 效率问题,递归调用效率问题需要注意