解释器设计模式

 

 

1在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法分析树,最终形成一颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器 2解析器模式:是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解析器,使用该解析器来解析语言中的句子(表达式) 3应用场景 A:应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树 B:一些重复出现的问题可以用一种简单的语言来表达 C:一个简单语法需要解释的场景 D:这样的例子还有,比如编译器、运算表达式计算、正则表达式、机器人等

解释器中用到了递归!

表达式: a+b-c+d a-b-c-d 1-2-3-4

Map {a=1,b=2,c=3,d=4} ,请你计算 出

1+2-3+4=10

/**
 * @Author lcw
 * @Description 抽象类
 * @Date 2021/12/21
 */
public   abstract class Expression {

    //依据不同的表达式,计算 map中的值   a =1  b = 2 c = 3 d= 4
    //如果提供的表达式是: a+b+c+d   1+2+3 +4
    public  abstract  int parse(Map<String,Integer> map);

}
/**
 * @Author lcw
 * @Description  变量的表达式:  通过key 获取相关的值
 * @Date 2021/12/21
 */
public class VarExpression extends Expression {

    private  String key; // a  b  c  d

    public VarExpression(String key) {
        this.key = key;
    }

    //依据初始化的key 从中拿 到key 对应的值
    @Override
    public int parse(Map<String, Integer> map) {
        return map.get(key);
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}
/**
 * @Author lcw
 * @Description  符号表达式:  a+b+c+d  //这是一个字符串
 *
 * @Date 2021/12/21
 */
public class SymbolExpression  extends  Expression{

    //符号左边的表达式
    private  Expression left;
    //符号右边的表达式
    private  Expression right;

    public SymbolExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int parse(Map<String, Integer> map) {
        return 0;
    }

    public Expression getLeft() {
        return left;
    }

    public void setLeft(Expression left) {
        this.left = left;
    }

    public Expression getRight() {
        return right;
    }

    public void setRight(Expression right) {
        this.right = right;
    }
}
/**
 * @Author lcw
 * @Description  加法表达式  a+ b+c +d
 * @Date 2021/12/21
 */
public class AddExpression  extends SymbolExpression {

    public AddExpression(Expression left, Expression right) {
        super(left, right);
    }

    //返回+法两边的结果和
    @Override
    public int parse(Map<String, Integer> map) {
        return   this.getLeft().parse(map)+ this.getRight().parse(map);
    }
}
/**
 * @Author lcw
 * @Description
 * @Date 2021/12/21
 */
public class Calculator {

    //1. 最终的Expression
    private  Expression expression;

    //2.提供一个字符串  a+b+c+d 去完成  Expressionge 表达式的封装
    public  void  parseStr(String s) {



        //1. string ==> char[
        char[] chars = s.toCharArray();
        //2. 创建一个栈 ,用来存储 数据
        Stack<Expression> stack = new Stack<>();

        //3.开始循环  a+b+c+d
        for (int i = 0; i < chars.length; i++) {

            char ex = chars[i];
            //3.1.提供一个左边和右边的表达式
            Expression left;
            Expression right;
            //判断当前是不是+号
            if(ex=='+') {
                //把左边的内容拿出来
                left = stack.pop(); //弹出并删除
                //把+号右侧的拿出来
                right = new VarExpression(String.valueOf(chars[++i]));

                AddExpression add = new AddExpression(left,right);

                //把结果再次入栈
                stack.push(add);
            }else {
                //如果不是+号,那么进行入栈
                VarExpression v = new VarExpression(String.valueOf(ex));
                stack.push(v);
            }
        }
        this.expression = stack.pop();
    }

    // a + b + c + d
    //拿到最后的Expression表达式的对象的结构如下:
   /* new AddExpression(
        new AddExpression (
             new AddExpression( new VarExpression(a)new VarExpression(b)),
             new VarExpression(c))
        new VarExpression(d) );
    */

    //把结果解析进行返回
    public  int count(Map<String,Integer> map) {

        return  this.expression.parse(map);
    }



}
/**
 * @Author lcw
 * @Description
 * @Date 2021/12/21
 */
public class TMain {

    public static void main(String[] args) {

        //1准备一个Map
        Map<String,Integer> map = new HashMap<>();
        map.put("a",1);
        map.put("b",3);
        map.put("c",4);
        map.put("d",1);

        //2.准备一个表达式
        String str = "a+b+c+d";

        //准备一个 计算器
        Calculator c = new Calculator();
        c.parseStr(str);
        int count = c.count(map);
        System.out.println("count="+count);

    }
}

 

posted on 2021-12-21 21:07  无心睡眠A8  阅读(48)  评论(0)    收藏  举报