目录
1.核心思想
定义一个语言的文法,并且建立一个解释器来解释该语言中的语句
简单来说:
有固定的语法结构,类似于加减乘除,数据库的增删改查的一系列固定了语法结构的语句。通过非终结表达式进行运算,终结符表达式来表示值,上下文做扩展,客户端使用。
2.成员
抽象表达式(Abstract Expression):
定义解释器模式中所有表达式的抽象接口或抽象类。通常包含一个 interpret()
方法,用于解释给定的上下文(Context)。
终结符表达式(Terminal Expression):
实现抽象表达式接口,表示文法中的终结符(Terminal Symbols)。终结符表达式是不可再分的基本元素,通常对应文法中的基本单元。
非终结符表达式(Non-terminal Expression):
实现抽象表达式接口,表示文法中的非终结符(Non-terminal Symbols)。非终结符表达式通常由终结符表达式和其他非终结符表达式组成。
上下文(Context):
上下文对象包含解释器解释时需要的全局信息或状态。它维护解释器解释时所需的信息,可能包括文法中的变量、符号表或其他运行时信息。
客户端(Client):
创建或配置解释器并且传递给它解析语言的表达式。客户端通常是使用解释器模式的应用程序或模块。
3.优点
灵活性:解释器模式使得可以轻易地改变和扩展文法,因为它使用类来表示文法规则,每个文法规则可以通过继承或组合来扩展和变化,使得系统更加灵活。
易于实现文法:
解释器模式将每个文法规则表示为一个类或表达式,这样更容易理解和实现复杂的文法。
易于扩展:可以通过增加新的表达式来扩展语言的语法,同时可以通过继承或组合已有的表达式来实现新的表达式,这样扩展解释器模式比较容易。
适用于复杂文法:当语法规则非常复杂并且经常变化时,解释器模式比编写复杂的解析器更加简单和灵活。
解耦语法分析和执行:解释器模式通过将语法分析和执行分离,使得可以更容易地管理和修改文法规则,不影响其它部分的代码。
较好的可维护性:解释器模式中的每个表达式可以独立编写、测试和维护,因此系统的可维护性较好
4.代码实现
4.1 抽象表达式
//抽象表达式
public abstract class AbstractExpression {
public abstract int interpreter(Context context);
}
4.2 终结符表达式
//终结符表达式
public class NumberExpression extends AbstractExpression{
private String variableName;
public NumberExpression(String variableName) {
this.variableName = variableName;
}
@Override
public int interpreter(Context context) {
return context.getValue(variableName);
}
}
4.3 非终结符表达式
// 非终结符表达式:表示加法操作
public class AddExpression extends AbstractExpression{
private AbstractExpression leftOperand;
private AbstractExpression rightOperand;
public AddExpression(AbstractExpression left, AbstractExpression right) {
this.leftOperand = left;
this.rightOperand = right;
}
@Override
public int interpreter(Context context) {
return leftOperand.interpreter(context)+ rightOperand.interpreter(context) ;
}
}
// 非终结符表达式:表示减法操作
public class SubtractExpression extends AbstractExpression{
private AbstractExpression leftOperand;
private AbstractExpression rightOperand;
public SubtractExpression(AbstractExpression left, AbstractExpression right) {
this.leftOperand = left;
this.rightOperand = right;
}
@Override
public int interpreter(Context context) {
return leftOperand.interpreter(context) - rightOperand.interpreter(context) ;
}
}
// 非终结符表达式:表示乘法操作
public class MultiplyExpression extends AbstractExpression{
private AbstractExpression leftOperand;
private AbstractExpression rightOperand;
public MultiplyExpression(AbstractExpression left, AbstractExpression right) {
this.leftOperand = left;
this.rightOperand = right;
}
@Override
public int interpreter(Context context) {
return leftOperand.interpreter(context) * rightOperand.interpreter(context) ;
}
}
// 非终结符表达式:表示除法操作
public class DivideExpression extends AbstractExpression{
private AbstractExpression leftOperand;
private AbstractExpression rightOperand;
public DivideExpression(AbstractExpression left, AbstractExpression right) {
this.leftOperand = left;
this.rightOperand = right;
}
@Override
public int interpreter(Context context) {
int right = rightOperand.interpreter( context);
if (right != 0) {
return leftOperand.interpreter(context) / right;
} else {
throw new ArithmeticException("被除数不能为0!");
}
}
}
4.4 上下文
//上下文类
public class Context {
private Map<String,Integer> variables =new HashMap();
public void setValue(String key,Integer value){
variables.put(key,value);
}
public Integer getValue(String key){
return variables.get(key); }
}
4.5 客户端
public class Test {
public static void main(String[] args) {
//(1 + 2 * 3) / (5 -4)
Context context = new Context();
context.setValue("one",1);
context.setValue("two",2);
context.setValue("three",3);
context.setValue("four",4);
context.setValue("five",5);
DivideExpression divideExpression = new DivideExpression(
new AddExpression(
new NumberExpression("one")
,
new MultiplyExpression(
new NumberExpression("two")
,
new NumberExpression("three")
)
)
,
new SubtractExpression(
new NumberExpression("five")
,
new NumberExpression("four")
)
);
int interpreter = divideExpression.interpreter(context);
System.out.println(interpreter);
}
}