定义
给定一个语言,定义他的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
结构和说明
示例代码
public class InterpreterDemo {
/**
* 抽象表达式
*/
public static abstract class AbstractExpression {
/**
* 解释的操作
*
* @param ctx
* 上下文对象
*/
public abstract void interpret(Context ctx);
}
/**
* 终结符表达式
*/
public static class TerminalExpression extends AbstractExpression {
@Override
public void interpret(Context ctx) {
// 实现与语法规则中的终结符相关联的解释操作
}
}
/**
* 非终结符表达式
*/
public static class NonterminalExpression extends AbstractExpression {
@Override
public void interpret(Context ctx) {
// 实现与语法规则中的非终结符相关联的解释操作
}
}
/**
* 上下文,包含解释器之外的一些全局信息
*/
public static class Context {
}
/**
* 使用解释器的客户
*/
public static class Client {
// 主要按照语法规则对特定的句子构建抽象语法树
// 然后调用解释操作
}
}
调用顺序
优缺点
优点
- 易于实现语法
在解释器模式中,一条语法规则用一个解释器对象来解释执行。对于解释器的实现来讲,功能就变得比较简单,只需要考虑这一条语法规则的实现就可以了,其他的都不用管。
- 易于扩展新的语法
正是由于采用一个解释器对象负责一条语法规则的方式,使得扩展新的语法非常容易。扩展了新的语法,只需要增加新的解释器对象,在创建抽象语法树的时候使用这个新的解释器对象就可以。
缺点
- 不适合复杂的语法
如果语法非常复杂,构建解释器模式需要的抽象语法树的工作是非常艰巨的,再加上还可能会构建多个抽象语法树。所以解析模式不太适合复杂的语法,对于复杂的语法,使用语法分析程序或编译器生成器可能会更好一些。
思考
本质
分离实现,解释执行。
何时选用
- 当一个语言需要解释执行,并且可以讲该语言中的句子表示为一个抽象语法树的时候,可以考虑使用解释器模式。
在使用解释器模式的时候,还有两个特点需要考虑,一个是语法相对应该比较简单,太复杂的语法不太适合使用解释器模式;另一个效率要求不是很高,对效率要求很高的情况下,不适合使用解释器模式。
相关模式
TODO 后面补上。