interpreter mode


The Interpreter Pattern (Interpreter Pattern) provides a way to evaluate the grammar or expressions of a language. It is a behavioral pattern. This pattern implements an expression interface that interprets a specific context. This mode is used in SQL parsing, symbol processing engines, etc.

Introduction

Intent: Given a language, define its grammatical representation, and define an interpreter that uses that representation to interpret sentences in the language .

Main solution: Construct an interpreter that interprets sentences for some fixed grammars.

When to use: If a particular type of problem occurs frequently enough, it may be worthwhile to formulate individual instances of that problem as a sentence in simple language. This makes it possible to build an interpreter that solves the problem by interpreting these sentences.

How to solve: Build a syntax tree and define terminal symbols and non-terminal symbols.

Key code: The component environment class contains some global information outside the interpreter, usually HashMap.

Application examples: Compiler, operation expression calculation.

Advantages: 1. Good scalability and flexibility. 2. Added a new way to interpret expressions. 3. Easy to implement simple grammar.

Disadvantages: 1. There are relatively few available scenarios. 2. It is difficult to maintain complex grammar. 3. The interpreter mode will cause class expansion. 4. The interpreter mode uses a recursive calling method.

Usage scenarios: 1. A sentence in a language that needs to be interpreted and executed can be represented as an abstract syntax tree. 2. Some recurring problems can be expressed in a simple language. 3. A scenario where simple grammar needs explanation.

Note: There are relatively few available scenarios. If you encounter it in JAVA, you can use expression4J instead.

Implementation

We will create an interface Expression and an entity class that implements the Expression interface. Defines the TerminalExpression class that serves as the main interpreter in the context. The other classes OrExpression and AndExpression are used to create combined expressions.

InterpreterPatternDemo, our demo class uses the Expression class to create rules and demonstrate the parsing of expressions.

interpreter_pattern_uml_diagram.jpg

Step 1

Create an expression interface.

Expression.java

public interface Expression {
   public boolean interpret(String context);
}

Step 2

Create an entity class that implements the above interface.

TerminalExpression.java

public class TerminalExpression implements Expression {
	
   private String data;

   public TerminalExpression(String data){
      this.data = data; 
   }

   @Override
   public boolean interpret(String context) {
      if(context.contains(data)){
         return true;
      }
      return false;
   }
}

OrExpression.java

public class OrExpression implements Expression {
	 
   private Expression expr1 = null;
   private Expression expr2 = null;

   public OrExpression(Expression expr1, Expression expr2) { 
      this.expr1 = expr1;
      this.expr2 = expr2;
   }

   @Override
   public boolean interpret(String context) {		
      return expr1.interpret(context) || expr2.interpret(context);
   }
}

AndExpression.java

public class AndExpression implements Expression {
	 
   private Expression expr1 = null;
   private Expression expr2 = null;

   public AndExpression(Expression expr1, Expression expr2) { 
      this.expr1 = expr1;
      this.expr2 = expr2;
   }

   @Override
   public boolean interpret(String context) {		
      return expr1.interpret(context) && expr2.interpret(context);
   }
}

Step 3

InterpreterPatternDemo Use the Expression class to create rules and parse them.

InterpreterPatternDemo.java

public class InterpreterPatternDemo {

   //规则:Robert 和 John 是男性
   public static Expression getMaleExpression(){
      Expression robert = new TerminalExpression("Robert");
      Expression john = new TerminalExpression("John");
      return new OrExpression(robert, john);		
   }

   //规则:Julie 是一个已婚的女性
   public static Expression getMarriedWomanExpression(){
      Expression julie = new TerminalExpression("Julie");
      Expression married = new TerminalExpression("Married");
      return new AndExpression(julie, married);		
   }

   public static void main(String[] args) {
      Expression isMale = getMaleExpression();
      Expression isMarriedWoman = getMarriedWomanExpression();

      System.out.println("John is male? " + isMale.interpret("John"));
      System.out.println("Julie is a married women? " 
      + isMarriedWoman.interpret("Married Julie"));
   }
}

Step 4

Verify the output.

John is male? true
Julie is a married women? true