概念:
解釋器模式: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咱們一般說即便編譯語言又是解釋語言。這裏就是解釋語言就笨都是這麼幹的。
實現:
定義指令串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; } }
抽象指令關鍵字node
public abstract class AbstractKey { public abstract void interpreter(Directive directive); public abstract void execute(); }
命令關鍵字express
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(); }); } }
循環關鍵字ide
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"); } }
測試及結果:oop
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.平時基本不多用到,就不扯一些書上空洞的東西了,主要在於理解這種設計模式的思路和對解釋型語言的運行。
開發工具