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());

    }
}

 

posted @ 2021-07-29 16:06  一拳超人的逆袭  阅读(44)  评论(0编辑  收藏  举报