20.解释器模式
终结符表达式(Terminal Expression):实现文法中与终结符有关的解释操作。文法中每一个终结符都有一个具体的终结符表达式与之相对应。比如我们的R=M+N运算,M和N就是终结符,对应的解析M和N的解释器就是终结符表达式。
非终符结表达式(Nonterminal Expression):实现文法中与非终结符有关的解释操作。文法中的每一条规则都对应了一个非终结符表达式。非终结表达式一般是文法中的运算符或者关键字,如上面公示:R=M+N中的“+”号就是非终结符,解析“+”号的解释器就是一个非终结符表达式。
接口类和抽象类
public interface IExpression { public int interpret(); }
/** * @author wuyimin * @create 2021-07-29 15:28 * @description 非终结表达式(符号)抽象类 * 抽象类可以不实现接口 */ public abstract class AbstractNonTerminalExpression implements IExpression { protected int left;//左值 protected int right;//右值 public AbstractNonTerminalExpression(int left, int right) { this.left = left; this.right = right; } }
终结表达式(数字类)
public class NumberExpression implements IExpression { int value; public NumberExpression(String value) { this.value = Integer.parseInt(value); } @Override public int interpret() { return value; } }
加减法(非终结表达式的实现类)
public class AddExpression extends AbstractNonTerminalExpression { public AddExpression(int left, int right) { super(left, right); } @Override public int interpret() { return left+right; } } public class SubExpression extends AbstractNonTerminalExpression { public SubExpression(int left, int right) { super(left, right); } @Override public int interpret() { return left-right; } }
上下文和客户端
/** * @author wuyimin * @create 2021-07-29 15:38 * @description 上下文信息来储存运算结果 */ public class ExpressionContext { Stack<String> strings=new Stack<>(); public ExpressionContext(String expression) { parse(expression); } public void parse(String expression){ String[] s = expression.split(" "); for (int i = 0; i < s.length; i++) { if(s[i].equals("+")){ //取出最上面刚刚刚进去的数字 NumberExpression numberExpression = new NumberExpression(strings.pop()); int left=numberExpression.value; //这里需要将i++因为已经将下一个数处理了 NumberExpression numberExpression2 = new NumberExpression(s[++i]); int right=numberExpression2.value; AddExpression addExpression = new AddExpression(left, right); int interpret = addExpression.interpret(); //把int变成字符串的快捷方式 不能用+" "会造成parseInt解析不了 strings.push(interpret+""); }else if(s[i].equals("-")){ //取出最上面刚刚刚进去的数字 NumberExpression numberExpression = new NumberExpression(strings.pop()); int left=numberExpression.value; NumberExpression numberExpression2 = new NumberExpression(s[++i]); int right=numberExpression2.value; SubExpression subExpression = new SubExpression(left, right); int interpret = subExpression.interpret(); strings.push(interpret+""); }else{//数字直接入栈 strings.push(s[i]); } } } public int getResult(){ return Integer.parseInt(strings.pop()); } public static void main(String[] args) { String s="1 + 2 + 3 - 4"; ExpressionContext expressionContext = new ExpressionContext(s); System.out.println(expressionContext.getResult()); } }