Interpreter Patterns

GoF定义:如果有一种语言,那么需要定义语法结构并且需要一个翻译器来解释语言中的语句

概念

这里我们为一种语言定义一个语法规范,并且提供了解释器来处理语法。简单来说,这个模式表达的是如何计算语言中语句的值(真实含义)

例子

现实世界:语言翻译就是这个模式最恰当的例子。乐谱也是一个例子
代码世界:Java编译器将源代码解释(广义含义)成字节码。这个字节码可以被JVM读取。C#中源码被转换成MSIL码,它可以被CLR解释。在执行过程中,MSIL会被JIT(just in time)编译器转换为二进制执行码

展示

首先要创建一个解释器上下文(context),然后创建一个表达式的实现,最后要创建一个客户端来接收用户请求并生成翻译结果。客户端也会决定超过一条语句的情况下哪个表达式被使用

代码

public class InterpreterPatternEx {
    private Context context;
    private IExpression expression;

    public InterpreterPatternEx(Context context) {
        this.context = context;
    }

    public void interpret(String str) {
        for(int i=0;i<2;i++){
            System.out.println("\nEnter ur choice(1 or 2)");
            Scanner in = new Scanner(System.in);
            String c = in.nextLine();
            if ("1".equals(c))
            {
                expression = new IntToWords(str);
            }
            else
            {
                expression = new StringToBinaryEx(str);
            }
            expression.interpret(this.context);
        }
    }

    public static void main(String[] args) {
        System.out.println("\n***Interpreter Pattern Demo***\n");
        System.out.println("Enter a number :");
        Scanner in = new Scanner(System.in);
        String input = in.nextLine();
        Context context=new Context(input);
        InterpreterPatternEx client = new InterpreterPatternEx(context);
        client.interpret(input);
    }
}

class Context {
    public String input;

    public Context(String input) {
        this.input = input;
    }

    public void getBinaryForm(String input) {
        int i = Integer.parseInt(input);
        String binaryString = Integer.toBinaryString(i);
        System.out.println("Binary equivalent of "+input+ " is "+ binaryString);
    }

    public void printInWords(String input) {
        this.input = input;
        System.out.println("Printing the input in words:");
        char[] c = input.toCharArray();
        for (char cs: c) {
            switch (cs)
            {
                case '1':
                    System.out.print("One ");
                    break;
                case '2':
                    System.out.print("Two ");
                    break;
                case '3':
                    System.out.print("Three ");
                    break;
                case '4':
                    System.out.print("Four ");
                    break;
                case '5':
                    System.out.print("Five ");
                    break;
                case '6':
                    System.out.print("Six ");
                    break;
                case '7':
                    System.out.print("Seven ");
                    break;
                case '8':
                    System.out.print("Eight ");
                    break;
                case '9':
                    System.out.print("Nine ");
                    break;
                case '0':
                    System.out.print("Zero ");
                    break;
                default:
                    System.out.print("* ");
                    break;
            }
        }
    }
}

interface IExpression {
    void interpret(Context context);
}

class StringToBinaryEx implements IExpression {

    private String s;

    public StringToBinaryEx(String s) {
        this.s = s;
    }

    @Override
    public void interpret(Context context) {
        context.printInWords(this.s);
    }
}

class IntToWords implements IExpression {

    private String s;

    public IntToWords(String s) {
        this.s = s;
    }

    @Override
    public void interpret(Context context) {
        context.getBinaryForm(this.s);
    }
}

Note

  1. 这个模式广泛用于解释一种语言中的语句(以抽象语法树的方式),当语法简单易读时这种模式表现很好
  2. 可以容易地表示、修改和实现一种语法
  3. 我们可以以自己更喜欢的方式来计算表达式的值。取决于我们要怎么解释这些语句
  4. 如果语法很复杂,实现这个模式会变得非常难。对每个规则,我们都需要实现一个新类,这也是一个很繁复的过程

思考

这个模式将解释器(context)和表达式(语句)分离开,所有的转换规则都在解释器中。开发应用这个模式应该不是很常用,开发一些(简单)语言解释库可以应用

posted on 2020-12-15 09:29  老鼠不上树  阅读(768)  评论(0)    收藏  举报