introduce

  1. In the principle of compilation, an arithmetic expression forms a lexical unit through a lexical analyzer, which in turn builds a parsing tree through a syntax parser, and finally forms an abstract parsing tree. Both lexers and parsers can be used as parsers
  2. Interpreter Pattern: Defines a representation of one of the grammars of a given language (expression) and an Interpreter that is used to parse sentences (expressions) in the language.

  • Context: Is an environment role that contains global information outside of the interpreter.
  • AbstractExpression: an AbstractExpression that declares an abstract interpretation operation. This interface is shared by all nodes in the abstract syntax tree.
  • TerminalExression: Terminator expression that implements the interpretive operation associated with terminators ina grammar.
  • NonterminalExpression: is a non-terminal expression. It is the non-terminal expression in the grammar to implement the interpretation operation. Rn requires a concrete non-terminal expression class.

case

Four operational problems:

  1. Enter the form of the expression, such as a + b + C + d, to ensure that the expression value cannot be repeated
  2. Enter the values of a, B, C, and D respectively
  3. For the results

Create a Calculator class

public class Calculator {


    // Define an expression
    private Expression expression;

    // The constructor takes arguments and parses
    public Calculator(String expStr) {
        // Arrange the sequence of operations
        Stack<Expression> stack = new Stack<>();
        // The expression is split into character arrays
        char[] charArray = expStr.toCharArray();

        Expression left = null;
        Expression right = null;
        for (int i = 0; i < charArray.length; i++) {
            switch (charArray[i]) {
                case '+':
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new AddExpression(left, right));
                    break;
                case The '-':
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new SubExpression(left, right));
                    break;
                default:    // The variable in the formula
                    stack.push(new VarExpression(String.valueOf(charArray[i])));
                    break; }}this.expression = stack.pop();
    }

    / / calculate
    public int run(HashMap<String, Integer> var) {
        return this.expression.interpreter(var); }}Copy the code

Create the Expression class

public abstract class Expression {

    /** * parses formulas and values *@param var
     * @return* /
    public abstract int interpreter(HashMap<String, Integer> var); The VarExpression class inherits Expression Expression Javapublic class VarExpression extends Expression{

    private String key;

    public VarExpression(String key) {
        this.key = key;
    }

    @Override
    public int interpreter(HashMap<String, Integer> var) {
        return var.get(key); }}Copy the code

Create conditional expressions The SymbolExpression class inherits Expression expressions

public class SymbolExpression extends Expression{

    protected Expression left;
    protected Expression right;

    public SymbolExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpreter(HashMap<String, Integer> var) {
        return 0; }}Copy the code

The SubExpression class inherits SymbolExpression

public class SubExpression extends SymbolExpression{

    public SubExpression(Expression left, Expression right) {
        super(left, right);
    }


    @Override
    public int interpreter(HashMap<String, Integer> var) {
        return super.left.interpreter(var) - super.right.interpreter(var); }}Copy the code

The SubExpression class inherits SymbolExpression

public class AddExpression extends SymbolExpression{


    public AddExpression(Expression left, Expression right) {
        super(left, right);
    }


    @Override
    public int interpreter(HashMap<String, Integer> var) {
         return super.left.interpreter(var) + super.right.interpreter(var); }}Copy the code

The client

public class Client {

    public static void main(String[] args) throws IOException {
        String expStr = getExpStr();
        HashMap<String, Integer> var = getValue(expStr);
        Calculator calculator = new Calculator(expStr);
        System.out.println("Operation result:" + expStr + "=" + calculator.run(var));
    }

    // Get the expression
    public static String getExpStr(a) throws IOException {
        System.out.print("Please enter the expression:");
        return (new BufferedReader(new InputStreamReader(System.in))).readLine();
    }

    // Get the value mapping
    public static HashMap<String, Integer> getValue(String expStr) throws IOException {
        HashMap<String, Integer> map = new HashMap<>();

        for (char ch : expStr.toCharArray()) {
            if(ch ! ='+'&& ch ! =The '-') {
                if(! map.containsKey(String.valueOf(ch))) { System.out.print("Please enter" + String.valueOf(ch) + "Value:");
                    String in = (new BufferedReader(newInputStreamReader(System.in))).readLine(); map.put(String.valueOf(ch), Integer.valueOf(in)); }}}returnmap; }}Copy the code

Advantages and disadvantages

Advantages:

1) Good scalabilityCopy the code

Disadvantages:

1) Interpreter mode causes class bloat. 1) Interpreter mode uses recursive calling methods, which makes debugging very complicated. 1) It uses a lot of loops and recursion, and efficiency is a problem that cannot be ignoredCopy the code

Applicable scenarios:

1) Some recurring problems can be expressed in a simple language. 2) Sentences in a language that needs to be interpreted can be represented as an abstract syntax treeCopy the code



Github Demo address: ~ ~ ~ portal ~ ~ ~

Personal blog address: blog.yanxiaolu.cn /