zoukankan      html  css  js  c++  java
  • 设计模式完结(15) -- 解释器模式 -- 自定义语言的实现模式

    expression ::= direction action distance | composite //表达式
    composite ::= expression 'and' expression //复合表达式
    direction ::= 'up' | 'down' | 'left' | 'right' //移动方向
    action ::= 'move' | 'run' //移动方式
    distance ::= an integer //移动距离

    上述语言一共定义了五条文法规则,对应五个语言单位,这些语言单位可以分为两类,一类为终结符(也称为终结符表达式),例如direction、action和distance,它们是语言的最小组成单位,不能再进行拆分;另一类为非终结符(也称为非终结符表达式),例如expression和composite,它们都是一个完整的句子,包含一系列终结符或非终结符。

    abstract class AbstractExpression {
           public  abstract void interpret(Context ctx);
    }
    
    class TerminalExpression extends  AbstractExpression {
           public  void interpret(Context ctx) {
                  //终结符表达式的解释操作
           }
    }
    
    class NonterminalExpression extends  AbstractExpression {
           private  AbstractExpression left;
           private  AbstractExpression right;
    
           public  NonterminalExpression(AbstractExpression left,AbstractExpression right) {
                  this.left=left;
                  this.right=right;
           }
    
           public void interpret(Context ctx) {
                  //递归调用每一个组成部分的interpret()方法
                  //在递归调用时指定组成部分的连接方式,即非终结符的功能
           }     
    }

    除了上述用于表示表达式的类以外,通常在解释器模式中还提供了一个环境类Context,用于存储一些全局信息,通常在Context中包含了一个HashMap或ArrayList等类型的集合对象(也可以直接由HashMap等集合类充当环境类),存储一系列公共信息,如变量名与值的映射关系(key/value)等,用于在进行具体的解释操作时从中获取相关信息。其典型代码片段如下:

    lass Context {
         private HashMap map = new HashMap();
         public void assign(String key, String value) {
             //往环境类中设值
         }
    public String  lookup(String key) {
             //获取存储在环境类中的值
         }
    }

    抽象语法树如图18-4所示:

    机器人控制程序实例基本结构如图18-5所示:

     

    //注:本实例对机器人控制指令的输出结果进行模拟,将英文指令翻译为中文指令,实际情况是调用不同的控制程序进行机器人的控制,包括对移动方向、方式和距离的控制等  
    import java.util.*;  
    
    //抽象表达式  
    abstract class AbstractNode {  
        public abstract String interpret();  
    }  
    
    //And解释:非终结符表达式  
    class AndNode extends AbstractNode {  
        private AbstractNode left; //And的左表达式  
        private AbstractNode right; //And的右表达式  
    
        public AndNode(AbstractNode left, AbstractNode right) {  
            this.left = left;  
            this.right = right;  
        }  
    
        //And表达式解释操作  
        public String interpret() {  
            return left.interpret() + "再" + right.interpret();  
        }  
    }  
    
    //简单句子解释:非终结符表达式  
    class SentenceNode extends AbstractNode {  
        private AbstractNode direction;  
        private AbstractNode action;  
        private AbstractNode distance;  
    
        public SentenceNode(AbstractNode direction,AbstractNode action,AbstractNode distance) {  
            this.direction = direction;  
            this.action = action;  
            this.distance = distance;  
        }  
    
        //简单句子的解释操作  
        public String interpret() {  
            return direction.interpret() + action.interpret() + distance.interpret();  
        }     
    }  
    
    //方向解释:终结符表达式  
    class DirectionNode extends AbstractNode {  
        private String direction;  
    
        public DirectionNode(String direction) {  
            this.direction = direction;  
        }  
    
        //方向表达式的解释操作  
        public String interpret() {  
            if (direction.equalsIgnoreCase("up")) {  
                return "向上";  
            }  
            else if (direction.equalsIgnoreCase("down")) {  
                return "向下";  
            }  
            else if (direction.equalsIgnoreCase("left")) {  
                return "向左";  
            }  
            else if (direction.equalsIgnoreCase("right")) {  
                return "向右";  
            }  
            else {  
                return "无效指令";  
            }  
        }  
    }  
    
    //动作解释:终结符表达式  
    class ActionNode extends AbstractNode {  
        private String action;  
    
        public ActionNode(String action) {  
            this.action = action;  
        }  
    
        //动作(移动方式)表达式的解释操作  
        public String interpret() {  
            if (action.equalsIgnoreCase("move")) {  
                return "移动";  
            }  
            else if (action.equalsIgnoreCase("run")) {  
                return "快速移动";  
            }  
            else {  
                return "无效指令";  
            }  
        }  
    }  
    
    //距离解释:终结符表达式  
    class DistanceNode extends AbstractNode {  
        private String distance;  
    
        public DistanceNode(String distance) {  
            this.distance = distance;  
        }  
    
    //距离表达式的解释操作  
        public String interpret() {  
            return this.distance;  
        }     
    }  
    
    
    //指令处理类:工具类  
    class InstructionHandler {  
        private String instruction;  
        private AbstractNode node;  
    
        public void handle(String instruction) {  
            AbstractNode left = null, right = null;  
            AbstractNode direction = null, action = null, distance = null;  
            Stack stack = new Stack(); //声明一个栈对象用于存储抽象语法树  
            String[] words = instruction.split(" "); //以空格分隔指令字符串  
            for (int i = 0; i < words.length; i++) {  
    //本实例采用栈的方式来处理指令,如果遇到“and”,则将其后的三个单词作为三个终结符表达式连成一个简单句子SentenceNode作为“and”的右表达式,而将从栈顶弹出的表达式作为“and”的左表达式,最后将新的“and”表达式压入栈中。                  
    if (words[i].equalsIgnoreCase("and")) {
    left = (AbstractNode)stack.pop(); //弹出栈顶表达式作为左表达式 String word1= words[++i]; direction = new DirectionNode(word1); String word2 = words[++i]; action = new ActionNode(word2); String word3 = words[++i]; distance = new DistanceNode(word3); right = new SentenceNode(direction,action,distance); //右表达式 stack.push(new AndNode(left,right)); //将新表达式压入栈中 } //如果是从头开始进行解释,则将前三个单词组成一个简单句子SentenceNode并将该句子压入栈中 else { String word1 = words[i]; direction = new DirectionNode(word1); String word2 = words[++i]; action = new ActionNode(word2); String word3 = words[++i]; distance = new DistanceNode(word3); left = new SentenceNode(direction,action,distance); stack.push(left); //将新表达式压入栈中 } } this.node = (AbstractNode)stack.pop(); //将全部表达式从栈中弹出 } public String output() { String result = node.interpret(); //解释表达式 return result; } } class Client { public static void main(String args[]) { String instruction = "up move 5 and down run 10 and left move 5"; InstructionHandler handler = new InstructionHandler(); handler.handle(instruction); String outString; outString = handler.output(); System.out.println(outString); } }
  • 相关阅读:
    用mapreduce 处理气象数据集
    熟悉常用的HBase操作
    爬虫大作业
    熟悉常用的HDFS操作
    数据结构化与保存
    获取全部校园新闻
    爬取校园新闻首页的新闻的详情,使用正则表达式,函数抽离
    NPOI的excel导出1
    DbHelperSQL帮助类
    C# mvc导出excel
  • 原文地址:https://www.cnblogs.com/wuer888/p/6694363.html
Copyright © 2011-2022 走看看