Assume that a text box in the system allows the user to enter a string expression, such"5 Division 2 multiplication 3 modulo 4 multiplication 6", The system is required to be able to calculate the expression result according to the Java integer multiplication and division operation rules, such as 12.
Assume that the system allows the user to input a string expression in a text box, such as"List name age student ID sortby student IDThe system is required to extract student information from the database and sort the student information by student ID.
When an application frequently uses a sentence in the form of text (whether it is entered by the user or read from the file), we need to define the string expressionLanguageDesignInterpreter (Interpreter).
In actual application development, there is little chance to write an interpreter. In addition, you need to learn how to compile a complex interpreter. Therefore, yqj2065 considers interpreter pattern as the most difficult to learn in all design patterns. If you have a general understanding of compilation principles, the difficulty coefficient is reduced from 7 stars to 4 stars. Therefore, the content in the next section is four stars.
7.1.1 multiplication Interpreter
An example of the interpreter mode is used to explain a simple expression language, suchAddition/subtraction interpreter, multiplication/division interpreter, or boolean operator Interpreter. For example, if you enter the string "5, 2, 3, 4, and 6", the program can follow the integer int multiplication and division operation rule to calculate the expression result, for example, 12. Note: For simplicity, firstIgnore priority and parentheses. In addition, the program actually processes the "5/2*3% 4*6" string.
The interpretation of simple string expressions does not require much lexical analysis knowledge. In order to focus our attention, we have simplified the expression language to the level of mental disability.
- The multiplication and division expressions are composed of numbers and operators '*', '/', and '%.
- A number is an expression, and an operator is used to connect two numbers as expressions. recursively, an operator is used to connect two expressions as expressions. Therefore, 5/6, 2, 5, and 2 * are valid expressions.
- For simplicity, Expression Language requires at least one space between numbers and operators. Therefore, the codeString [] tokens = Statement. Split ("\ s + ");
You can easily split the string you entered into the smallest unit of the Expression Language-terminal ).
The core of the interpreter mode (Interpreter pattern) is the interpreted expression. The interface expr represents/encapsulates the expression. expr encapsulates an interpret () method to explain (calculate) the expression (expr instance) and return the calculation result.
The number digit is an expression, so digit is a subtype of expr. Two numbers connected by an operator are expressions, which are expressed by op, while mulop, modop, and divop represent multiplication, modulo, and Division expressions respectively.
Routine 7 3 encapsulation syntax package intent. interpreter. calculator; public interface expr {public int interpret ();} package intent. interpreter. calculator; public abstract class op implements expr {protected expr left, right; // Public op (expr left, expr right) {This. left = left; this. right = right ;}} package intent. interpreter. calculator; public class mulop extends op {public mulop (expr left, expr right) {super (left, right) ;}@ override public int interpret () {return Super. left. interpret () * super. right. interpret () ;}} package intent. interpreter. calculator; public class digit implements expr {private int value; Public digit (INT value) {This. value = value ;}@ override public int interpret () {return this. value ;}}
Look at the class diagrams of expr, digit, and OP, andCombination Mode and decoration ModeThe same structure. Differences and internal relationships will be discussed later.
Now all parts are available, but the entire "5/2*3% 4*6" string still needs to form an expression. A simple implementation is to useStackConstruct the syntax tree.
Example 7 4 construct the syntax tree package intent. interpreter. calculator; import Java. util. *; public class calculator {private expr; Public void build (string statement) {string [] tokens = Statement. split (""); expr left = NULL, Right = NULL; stack <expr> stack = new stack <> (); For (INT I = 0; I <tokens. length; I ++) {If (tokens [I]. equals ("*") {left = stack. pop (); Right = new digit (tokens [++ I]); stack. push (New mulop (left, right);} else if (tokens [I]. equals ("/") {left = stack. pop (); Right = new digit (tokens [++ I]); stack. push (New divop (left, right);} else if (tokens [I]. equals ("%") {left = stack. pop (); Right = new digit (tokens [++ I]); stack. push (New modop (left, right);} else {stack. push (New digit (tokens [I]);} This. expr = (expr) stack. pop ();} public int compute () {return expr. interpret () ;}} public class client {public static void main (string ARGs []) {string Statement = "6/2*3% 4*6"; Statement = "62/3 "; calculator calculator = new calculator (); calculator. build (statement); int result = calculator. compute (); system. out. println (statement + "=" + result);} public static void test () {expr E = new divop (New digit (62), new digit (3 )); int result = E. interpret (); system. out. println ("62/3 =" + result );}}
The interpreter mode in [design patterns] does not explain how to create an abstract syntax tree.
Calculator MethodBuild (string Statement)Parse the statement parameter and construct an expr instance.
You can also directly define the expr instance by the client, as shown in the test () code, and execute its interpret (). This way
ManualIt looks interesting and kind-it's silly.
Expr E =NewDivop (NewDigit (62 ),NewDigit (3 ));
Concise interpreter mode (5.3)