设计模式(第二十三式:解释器模式)

时间:2019-07-04
本文章向大家介绍设计模式(第二十三式:解释器模式),主要包括设计模式(第二十三式:解释器模式)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

概念:
  解释器模式:Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. 给定一门语言,定义他的文法的表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。这个其实就从根本上解释了java的运行原理。java我们通常说即使编译语言又是解释语言。这里就是解释语言就笨都是这么干的。

实现:
  定义指令串

    public class Directive {
        private Integer index = 0;
        private String [] commands;
        private String currentCommand;

        public Directive(String directive){
            commands =  directive.split(" ");
            nextCommand();

        }

        public String nextCommand() {
            if(index < commands.length){
                currentCommand =  commands[index++];
            }else {
                currentCommand = null;
            }
            return currentCommand;
        }

        public String getCurrentCommand(){
            return currentCommand;
        }

        public void skipCurrentCommand(String command){
            if(!command.equalsIgnoreCase(currentCommand)){
                System.err.println("错误提示:"+command+"解析错误");
            }
            nextCommand();
        }

        public Integer getCurrentNum(String command){
            try{
                return Integer.parseInt(command);
            }catch (EnumConstantNotPresentException e){
                System.err.println("错误提示:"+command+"不是数字");
            }
            return null;
        }

    }


  抽象指令关键字

    public abstract class AbstractKey {

        public abstract void interpreter(Directive directive);

        public abstract void execute();
    }


  命令关键字

    public class CommandKey extends AbstractKey {
        private AbstractKey node;

        @Override
        public void interpreter(Directive directive) {
            if (directive.getCurrentCommand().equalsIgnoreCase("loop"))
            {
                node = new LoopKey();
                node.interpreter(directive);
            }
            else
            {
                node = new EndKey();
                node.interpreter(directive);
            }
        }

        @Override
        public void execute() {
            node.execute();
        }
    }


  表达式关键字

    public class ExpressionKey extends AbstractKey {

        private List<AbstractKey> list = new ArrayList<>();

        @Override
        public void interpreter(Directive directive) {
            while (true) {
                if (directive.getCurrentCommand() == null) break;
                else if (directive.getCurrentCommand().equalsIgnoreCase("end")) {
                    directive.skipCurrentCommand(directive.getCurrentCommand());
                    break;
                } else {
                    AbstractKey expression = new CommandKey();
                    expression.interpreter(directive);
                    list.add(expression);
                }
            }
        }

        @Override
        public void execute() {
            list.forEach(item -> {
                item.execute();
            });
        }
    }


  循环关键字

    public class LoopKey extends AbstractKey {
        private int number;
        private AbstractKey commandNode;

        @Override
        public void interpreter(Directive directive) {
            directive.skipCurrentCommand("LOOP");
            number = directive.getCurrentNum(directive.getCurrentCommand());
            directive.nextCommand();
            commandNode = new ExpressionKey();
            commandNode.interpreter(directive);
        }

        @Override
        public void execute() {
            for (int i = 0; i < number; i++)
            {
                commandNode.execute();
            }
        }
    }


  结束关键字

    public class EndKey extends AbstractKey {

        private String name;
        private String text;

        @Override
        public void interpreter(Directive directive) {
            name = directive.getCurrentCommand();
            directive.skipCurrentCommand(name);

            if (!name.equalsIgnoreCase("PRINT")
                    && !name.equalsIgnoreCase("BREAK")
                    && !name.equalsIgnoreCase("SPACE")) {
                System.out.println("非法指令");
            }

            if (name.equalsIgnoreCase("PRINT")) {
                text = directive.getCurrentCommand();
                directive.nextCommand();
            }
        }

        @Override
        public void execute() {
            if (name.equalsIgnoreCase("PRINT")) System.out.print(text);
            else if (name.equalsIgnoreCase("SPACE")) System.out.print(" ");
            else if (name.equalsIgnoreCase("BREAK")) System.out.print("\r\n");

        }
    }


测试及结果:

    public class InterpreterTest {
@Test
public void interpretertest(){ String directiveStr = "LOOP 2 PRINT good SPACE END PRINT study BREAK LOOP 2 PRINT day SPACE END PRINT up"; Directive directive = new Directive(directiveStr); AbstractKey node = new ExpressionKey(); node.interpreter(directive); System.out.println("原指令:"+directiveStr); System.out.println("解析后:"); node.execute(); } }


  原指令:LOOP 2 PRINT good SPACE END PRINT study BREAK LOOP 2 PRINT day SPACE END PRINT up
  解析后:
  good good study
  day day up

分析:
  1.可以写简单的语法工具,ide更开发工具都有用到。
  2.创造新的结束语言必要的一种设计模式。
  3.平时基本很少用到,就不扯一些书上空洞的东西了,主要在于理解这种设计模式的思路和对解释型语言的运行。


原文地址:https://www.cnblogs.com/ben-mario/p/11134137.html