zoukankan      html  css  js  c++  java
  • 设计模式(第二十三式:解释器模式)

    概念:
      解释器模式: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("
    ");
    
            }
        }


    测试及结果:

        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.平时基本很少用到,就不扯一些书上空洞的东西了,主要在于理解这种设计模式的思路和对解释型语言的运行。


  • 相关阅读:
    js 判断是否包含
    react-navigation-easy-helper
    mobx 小结
    react native使用 mobx , can't find variable:Symbol
    react-native 极光推送(jpush-react-native)
    react-native 启动页(react-native-splash-screen)
    react-native Android 全面屏手机 底部留有一大块黑屏
    RAP + MOCK
    ES7新特性
    POP动画[2]
  • 原文地址:https://www.cnblogs.com/ben-mario/p/11134137.html
Copyright © 2011-2022 走看看