Interpreter mode (interpreter) definition
Given a language, define a representation of its grammar and define an interpreter that interprets the sentences in the language using that representation.
UML Class Diagram
Role
Abstract expression role : declares an abstract interface that all specific expression roles need to implement. This interface is primarily a interpret () method, which is called an interpretation operation.
Terminator Expressions (Terminalexpression) role : implements the interface required by the abstract expression role, mainly a interpret () method; each terminator in the grammar has a specific end expression corresponding to it. For example, there is a simple formula R=R1+R2, in which R1 and R2 are terminator, corresponding parsing R1 and R2 of the interpreter is the Terminator expression.
Non-terminator expressions (nonterminalexpression) role : Each rule in the grammar requires a specific non-terminator expression, and a non-terminator expression is generally an operator or other keyword in the grammar, such as a formula r=r1+ R2, "+" is a non-terminator, parsing "+" is an interpreter is a non-terminator expression.
Environment (context) role : The task of this role is generally used to store the grammar of each terminator corresponding to the specific values, such as R=R1+R2, we give R1 value 100, to R2 assignment value 200. This information needs to be stored in the environment role, and in many cases it is sufficient for us to use map to act as an environment role.
Example
Abstract expressions (expression)
PackageCom.csdhsm.pattemdesign.interpreter;/*** @Title: Expression.java * @Description: Abstract expression *@author: Han * @date: July 2, 2016 morning 9:57:58*/ Public Abstract classExpression {//Interpreter explanation Public Abstract Booleaninterpret (Context CTX); Public Abstract Booleanequals (Object object); Public Abstract inthashcode (); Public AbstractString toString ();}
PackageCom.csdhsm.pattemdesign.interpreter;/*** @Title: Constant.java * @Description: BOOL constant, END *@author: Han * @date: July 2, 2016 morning 9:48:15*/ Public classConstantextendsExpression {Private Booleanvalue; PublicConstant (Booleanvalue) { This. Value =value; } @Override Public Booleanequals (Object obj) {if(obj! =NULL&& objinstanceofConstant) { return This. Value = =((Constant) obj). value; } return false; } @Override Public inthashcode () {return This. ToString (). Hashcode (); } @Override PublicString toString () {return NewBoolean (value). toString (); } @Override Public Booleaninterpret (Context ctx) {returnvalue; }}
PackageCom.csdhsm.pattemdesign.interpreter;/*** @Title: Variable.java * @Description: Famous variable, end *@author: Han * @date: July 2, 2016 morning 9:48:33*/ Public classVariableextendsExpression {PrivateString name; PublicVariable (String name) { This. Name =name; } @Override Public Booleanequals (Object object) {if(Object! =NULL&& ObjectinstanceofVariable) { return This. Name.equals (((Variable) object). Name); } return false; } @Override Public inthashcode () {return This. ToString (). Hashcode (); } @Override PublicString toString () {returnname; } @Override Public Booleaninterpret (Context ctx) {returnCtx.lookup ( This); }}
PackageCom.csdhsm.pattemdesign.interpreter;/*** @Title: And.java * @Description: and expression, non-terminating *@author: Han * @date: July 2, 2016 morning 9:48:52*/ Public classandextendsExpression {PrivateExpression left,right; Publicand (expression left, expression right) { This. left =Left ; This. right =Right ; } @Override Public Booleanequals (Object object) {if(Object! =NULL&& Objectinstanceofand ) { return This. Left.equals (((and) object). Left) && This. Right.equals (((and) object). right); } return false; } @Override Public inthashcode () {return This. ToString (). Hashcode (); } @Override PublicString toString () {return"(" + left.tostring () + "and" + right.tostring () + ")"; } @Override Public Booleaninterpret (Context ctx) {returnLeft.interpret (CTX) &&Right.interpret (CTX); }}
PackageCom.csdhsm.pattemdesign.interpreter;/*** @Title: Not.java * @Description: not expression *@author: Han * @date: July 2, 2016 morning 9:49:24*/ Public classNotextendsExpression {PrivateExpression exp; PublicNot (Expression exp) { This. Exp =exp; } @Override Public Booleanequals (Object obj) {if(obj! =NULL&& objinstanceofNot ) { returnExp.equals ((not) obj). exp); } return false; } @Override Public inthashcode () {return This. ToString (). Hashcode (); } @Override PublicString toString () {return"(not" + exp.tostring () + ")"; } @Override Public Booleaninterpret (Context ctx) {return!Exp.interpret (CTX); }}
PackageCom.csdhsm.pattemdesign.interpreter;/*** @Title: Or.java * @Description: an Or expression *@author: Han * @date: July 2, 2016 morning 9:49:34*/ Public classOrextendsExpression {PrivateExpression left,right; PublicOr (expression left, expression right) { This. left =Left ; This. right =Right ; } @Override Public Booleanequals (Object obj) {if(obj! =NULL&& objinstanceofOr) { return This. Left.equals ((or) obj). left) && This. Right.equals (((Or) obj). right); } return false; } @Override Public inthashcode () {return This. ToString (). Hashcode (); } @Override Public Booleaninterpret (Context ctx) {returnLeft.interpret (CTX) | |Right.interpret (CTX); } @Override PublicString toString () {return"(" + left.tostring () + "OR" + right.tostring () + ")"; }}
Context Environment Class
PackageCom.csdhsm.pattemdesign.interpreter;ImportJava.util.HashMap;ImportJava.util.Map;/*** @Title: Context.java * @Description: Environment (context) class defines a mapping from a variable to a Boolean value *@author: Han * @date: July 2, 2016 morning 9:49:02*/ Public classContext {Privatemap<variable,boolean> map =NewHashmap<variable,boolean>(); Public voidAssign (Variable var,Booleanvalue) {Map.put (Var,NewBoolean (value)); } Public BooleanLookup (Variable var)throwsillegalargumentexception{Boolean Value=Map.get (VAR); if(Value = =NULL){ Throw Newillegalargumentexception (); } returnValue.booleanvalue (); }}
Client
PackageCom.csdhsm.pattemdesign.interpreter; Public classSolution { Public Static voidMain (string[] args) {Context ctx=NewContext (); //declare a variable xVariable x =NewVariable ("X"); //declare a variable yVariable y =NewVariable ("Y"); Constant C=NewConstant (true); //the value of the variable x is false and stored in the environmentCtx.assign (x,false); Ctx.assign (Y,true); Expression Exp=NewOr (Newand (C,x),Newand (Y,NewNot (x))); System.out.println ("X=" +X.interpret (CTX)); System.out.println ("Y=" +Y.interpret (CTX)); System.out.println (exp.tostring ()+ "=" +Exp.interpret (CTX)); }}
Results
OK, success.
Summarize
The interpreter pattern provides an easy way to execute the syntax, and it is easy to modify or extend the syntax. Many classes in a general system use similar syntax, and an interpreter can be used instead of implementing an interpreter for each rule. and the different rules in the interpreter are implemented by different classes, which makes it easier to add a new syntax rule.
But the interpreter pattern is difficult to maintain for complex grammars. As you can imagine, each rule has to correspond to a processing class, and these classes have to recursively invoke abstract expression roles, such as the mess of the class intertwined together is what a horrible thing ah!
Design mode (-----interpreter mode)