Design PHP
Interpreter mode definition(It is rarely encountered in real projects, so the theory goes first ...)
The interpreter mode is a solution for parsing according to the prescribed syntax, which is rarely used in current projects. It is defined as a representation of the method that defines a language, define an interpreter that uses this representation to explain sentences in a language. The structure is as follows:
1. abstractexpression -- Abstract Interpreter
The specific interpretation task is completed by each implementation class. The specific interpreter is completed by terminalexpression and nonterminalexpression, respectively.
2. terminalexpression-terminator expression
Implement the interpreted operation associated with the elements in the method. There is only one Terminator expression in the interpreter mode, but there are multiple instances that correspond to different terminologies.
3. nonterminalexpression -- Non-terminator expression
Each rule in the grammar corresponds to a non-terminator expression. Non-terminator expressions are added based on complicated logic procedures. In principle, each grammar rule corresponds to a non-terminator expression.
4. Context -- Environment role
Now we use the interpreter mode to explain the four arithmetic operations (addition, subtraction, multiplication, division). The class diagram is as follows:
In the figure, mathexpression is the abstract interpreter, literal and variable are the terminator expressions, and sum and multiply are non-terminator expressions. The structure is clear. The implementation code is as follows:
<? Phpinterface mathexpression {public function evaluate (array $ values);}/*** a terminal expression which is a literal value. */class literal implements mathexpression {private $ _ value; public function _ construct ($ value) {$ this-> _ value = $ value ;} public Function evaluate (array $ values) {return $ this-> _ value ;}}/*** a terminal expression which represents a variable. */class variable implements mathexpression {private $ _ letter; public function _ construct ($ letter) {$ this-> _ letter = $ letter ;} public Function evaluate (array $ values) {return $ values [$ this-> _ Letter] ;}}/*** nonterminal expression. */class sum implements mathexpression {private $ _ A; private $ _ B; public function _ construct (mathexpression $ A, mathexpression $ B) {$ this-> _ A = $ A; $ this-> _ B = $ B;} public function evaluate (array $ values) {return $ this-> _ A-> evaluate ($ values) + $ this-> _ B-> evaluate ($ values) ;}}/*** nonterminal expression. */class multiply implements mathexpression {private $ _ A; private $ _ B; public function _ construct (mathexpression $ A, mathexpression $ B) {$ this-> _ A = $ A; $ this-> _ B = $ B;} public function evaluate (array $ values) {return $ this-> _ A-> evaluate ($ values) * $ this-> _ B-> evaluate ($ values); }}// 10 (a + 3) $ expression = new multiply (New literal (10), new sum (new variable ('A'), new literal (3 ))); echo $ expression-> evaluate (Array ('A' => 111), "\ n"; running result: 1140 [finished in 0.1 s]
Let's take a look at the advantages and disadvantages of this writing.
Advantages of interpreter Mode
The interpreter mode is a simple syntax analysis tool. Its most significant advantage is scalability. to modify a syntax rule, you only need to modify the corresponding non-terminator expression. if you extend the syntax, you only need to add a non-terminator class.
Disadvantages of interpreter Mode
1. The Interpreter mode will cause class expansion (I think many models have this problem)
Each syntax generates a non-terminator expression. When syntax rules are complex, a large number of class files can be generated, which brings a lot of trouble to maintenance.
2. The Interpreter mode uses recursive call methods.
Each Terminator expression only cares about its own expressions. Each expression needs to know the final result and must be stripped layer by layer, whether it is a process-oriented language or an object-oriented language, recursion is used when necessary, which leads to complicated debugging.
3. efficiency issues
Recursion will naturally lead to efficiency problems, especially when it is used to explain complex and lengthy syntaxes.
Use Cases of interpreter Mode
1. The Interpreter mode can be used for repeated issues.
For example, for server log analysis and processing, because the log modes of each server are different, but the data elements are the same, according to the interpreter mode, the terminator expressions are the same, but the non-terminator expression needs to be formulated.
2. a scenario where simple syntax needs to be explained
For example, SQL syntax analysis
Notes about interpreter Mode
Try not to use the interpreter mode in important modules; otherwise, maintenance will be a big problem. In the project, you can use shell, jruby, groovy, and other script languages to replace the interpreter mode, to make up for the PHP efficiency.
It can be found in large and medium-sized framework projects, such as data analysis tools, report design tools, and scientific computing tools, if you encounter a situation where "a specific type of problem occurs frequently enough", consider expression4j, MESP, open-source parsing toolkit, such as Jep, has extremely powerful functions and does not need to write interpreters from the beginning.
Original interpreter mode (Interpreter pattern)