Interpreter pattern -Interpreter Pattern

Interpreter pattern is a relatively low frequency difficult to learn, but the design pattern that is used to describe how to use the object-oriented language constitutes a simple language interpreter. In some cases, in order to better describe a certain type of problem, we can create a new language, the language has its own expression and structure, namely grammar rules, instances of these problems will correspond for the sentences in the language. At this point, you can use the Interpreter pattern to design this new language. Learning interpreter mode can deepen our understanding of object-oriented and procedural programming language to master the interpretation of Chinese law rules.

The definition and characteristics of the model

Defined interpreter (Interpreter) mode: to analyze a language object definition, and the definition of the language grammar, said re-design a parser to interpret the language of the sentence. In other words, a compiled language to analyze examples of applications. This expression grammar model implements the interface process, a specific explanation of the interface context.

The concept of grammar and sentence mentioned here in the same compiler theory to describe the same, "grammar" refers to the grammatical rules of the language, and "sentence" is the focus of language elements. For example, there are many Chinese sentence, "I am Chinese" is one sentence, you can use a syntax tree to visually describe the sentences in the language.

Interpreter pattern is a type of model classes, the following major advantages.

  1. Good scalability. The use of classes in the interpreter mode represented grammar rules of a language and the grammar may be changed or extended by inheritance mechanisms.
  2. easy to accomplish. Each class in the expression node in the syntax tree are similar, it is relatively easy to achieve its grammar.


The main drawback of mode explained below.

  1. The lower the efficiency. Interpreter pattern commonly used in a large number of cycles and recursive calls, when to explain more complex sentences, its speed is very slow, and the process of debugging the code too much trouble.
  2. Class will cause swelling. Each Rule Interpreter mode define at least a class, when the grammar rule contains many, the number of classes will increase sharply, resulting in system management and maintenance difficult.
  3. Applicable scene is relatively small. In software development, application examples need to define the language grammar is very small, so this mode is rarely used to.

Architecture and Implementation Model

Interpreter pattern commonly used in compiling or analyzing examples of simple language in order to master its structure and implementation, we must first understand the translation principle of "grammar, sentence syntax tree" and other related concepts.

1) grammar

Formal rules of grammar is used to describe the grammatical structure of the language. No rules no standards, for example, some people think the guidelines are perfect love "mutual attraction, emotional specificity, neither party experienced love", although the last one criterion more demanding, but anything else, there are rules, language, too, Whether it is a machine language or natural language with its own grammar rules. For example, the Chinese in the "sentence" grammar follows.

〈句子〉::=〈主语〉〈谓语〉〈宾语〉
〈主语〉::=〈代词〉|〈名词〉
〈谓语〉::=〈动词〉
〈宾语〉::=〈代词〉|〈名词〉
〈代词〉你|我|他
〈名词〉7大学生I筱霞I英语
〈动词〉::=是|学习


Note: the notation ":: =" means "is defined as" means, with the "<" and ">" non-terminal symbol enclose, surround is no terminator.

2) sentence

Sentence is the basic unit of language, the language is a set of elements, which consists of a terminator can be derived from "grammar." For example, the above grammar can be introduced, "I is a college student," so it is a sentence.

3) syntax trees

The syntax tree is a tree structure of a sentence, it represents the derivation result of the sentence, it is useful in understanding the level of grammatical structure of sentences. Figure 1 is "I am a university student," the syntax tree.
 

The sentence "I am a university student," the syntax tree
1 sentence "I am a university student," the syntax tree


With these basics, now to introduce the structure of the interpreter pattern is simple. Structure and mode of interpretation combination pattern similar, but it contains constituent elements than the combination pattern, and a combination of structural model is an object model, is interpreted mode class type of model.

1. Structure Model

Interpreter pattern consists of the following major role.

  1. Abstract expression (Abstract Expression) Roles: interpreter defined interface conventions explaining the operation of the interpreter, comprising a main interpretation interpret ().
  2. Terminator expression (Terminal Expression) Roles: subclasses of the abstract expression is used to implement operations associated with terminal symbols in the grammar, the grammar each terminal symbol has a particular expression end corresponding thereto.
  3. Nonterminals expression (Nonterminal Expression) Roles: subclasses of the abstract expression is used to implement the grammar nonterminals operation, the grammar associated with each rule corresponds to a nonterminal expression.
  4. Environment (Context) Roles: typically comprises data or functions of the respective common interpreter required, generally used to transmit all shared data interpreter, the interpreter can obtain the latter values ​​here.
  5. Client (Client): The main task of the sentence or expression is to be analyzed into using the interpreter object description of the abstract syntax tree, and then call the interpretation interpreter, of course, you can also be accessed indirectly through the environmental role of interpreter of interpretation .


Interpreter pattern configuration diagram shown in Figure 2.
 

Mode of the structure of FIG explained
FIG 2 is a configuration diagram interpretation mode

2. Mode of realization

Key interpretation mode is implemented grammar rules define the design classes and terminator nonterminal class, the structure shown in FIG constructed syntax tree if necessary, the code structure is as follows:

 
  1. // abstract expression class
  2. interface AbstractExpression
  3. {
  4. public Object interpret (String info); // interpretation
  5. }
  6. // terminator expression class
  7. class TerminalExpression implements AbstractExpression
  8. {
  9. public Object interpret(String info)
  10. {
  11. // handling of terminator expression
  12. }
  13. }
  14. // nonterminal expression class
  15. class NonterminalExpression implements AbstractExpression
  16. {
  17. private AbstractExpression exp1;
  18. private AbstractExpression exp2;
  19. public Object interpret(String info)
  20. {
  21. // handling of non-terminator expression
  22. }
  23. }
  24. // Environmental
  25. class Context
  26. {
  27. private AbstractExpression exp;
  28. public Context()
  29. {
  30. // initialize data
  31. }
  32. public void operation(String info)
  33. {
  34. // call the interpretation of the relevant class expressions
  35. }
  36. }

Mode of application examples

[Example 1] design a "Shao Unitoll" bus card with the card reader mode interpreter program.

Description: If "Shao Yue Tong" card reader can determine the identity of the bus passengers, if it is "Shaoguan" or "Canton" and "elderly" "Women," "child" can be a free ride, others ride a buckle 2 yuan.

Analysis: This example of "interpretation mode" is more suitable design, the first design which follows the grammar rules.

<expression> ::= <city>的<person>
<city> ::= 韶关|广州
<person> ::= 老人|妇女|儿童


Then, according to the rules of grammar class diagram design of bus card reader program, follow these steps.

  • Define an abstract expression (Expression) interface, which contains the interpretation interpret (String info).
  • Expression defines a terminator (Terminal Expression) class, with which set (the Set) or human class to hold the city to meet the conditions, and to achieve an abstract expression interpretation interface interpret (Stringinfo), the character is determined to be analyzed whether strings are set terminator.
  • Terminator expression object personnel terminator expression object and satisfy the conditions of the definition of a non-terminal expression (AndExpressicm) class, which is a subclass of abstract expression, which includes the condition of the city, and to achieve interpret (String info) method, used to determine whether the string is analyzed to meet the conditions of persons satisfying the condition in the city.
  • Finally, the definition of an environment (Context) class, which contains the data interpreter needed to complete initialization of the terminator of the expression, and defines a method of interpretation freeRide (String info) to call the character string expression object to be analyzed explained. The structure shown in Figure 3.

 

Structure map "Shao Yue Tong" Bus Reader program
Figure 3 structure map "Shao Yue Tong" Bus Reader program


Code is as follows:

 
  1. package interpreterPattern;
  2. import java.util. *;
  3. / * Grammar rules
  4. <expression> ::= <city>的<person>
  5. <City> :: = Shaoguan | Guangzhou
  6. <Person> :: = elderly | Women | Children
  7. */
  8. public class InterpreterPatternDemo
  9. {
  10. public static void main(String[] args)
  11. {
  12. Context bus=new Context();
  13. bus.freeRide("韶关的老人");
  14. bus.freeRide("韶关的年轻人");
  15. bus.freeRide("广州的妇女");
  16. bus.freeRide("广州的儿童");
  17. bus.freeRide("山东的儿童");
  18. }
  19. }
  20. //抽象表达式类
  21. interface Expression
  22. {
  23. public boolean interpret(String info);
  24. }
  25. //终结符表达式类
  26. class TerminalExpression implements Expression
  27. {
  28. private Set<String> set= new HashSet<String>();
  29. public TerminalExpression(String[] data)
  30. {
  31. for(int i=0;i<data.length;i++)set.add(data[i]);
  32. }
  33. public boolean interpret(String info)
  34. {
  35. if(set.contains(info))
  36. {
  37. return true;
  38. }
  39. return false;
  40. }
  41. }
  42. //非终结符表达式类
  43. class AndExpression implements Expression
  44. {
  45. private Expression city=null;
  46. private Expression person=null;
  47. public AndExpression(Expression city,Expression person)
  48. {
  49. this.city=city;
  50. this.person=person;
  51. }
  52. public boolean interpret(String info)
  53. {
  54. String s[]=info.split("的");
  55. return city.interpret(s[0])&&person.interpret(s[1]);
  56. }
  57. }
  58. //环境类
  59. class Context
  60. {
  61. private String[] citys={"韶关","广州"};
  62. private String[] persons={"老人","妇女","儿童"};
  63. private Expression cityPerson;
  64. public Context()
  65. {
  66. Expression city=new TerminalExpression(citys);
  67. Expression person=new TerminalExpression(persons);
  68. cityPerson=new AndExpression(city,person);
  69. }
  70. public void freeRide(String info)
  71. {
  72. boolean ok=cityPerson.interpret(info);
  73. if(ok) System.out.println("您是"+info+",您本次乘车免费!");
  74. else System.out.println(info+",您不是免费人员,本次乘车扣费2元!");
  75. }
  76. }


程序运行结果如下:

您是韶关的老人,您本次乘车免费!
韶关的年轻人,您不是免费人员,本次乘车扣费2元!
您是广州的妇女,您本次乘车免费!
您是广州的儿童,您本次乘车免费!
山东的儿童,您不是免费人员,本次乘车扣费2元!

模式的应用场景

前面介绍了解释器模式的结构与特点,下面分析它的应用场景。

  1. 当语言的文法较为简单,且执行效率不是关键问题时。
  2. 当问题重复出现,且可以用一种简单的语言来进行表达时。
  3. 当一个语言需要解释执行,并且语言中的句子可以表示为一个抽象语法树的时候,如 XML 文档解释。


注意:解释器模式在实际的软件开发中使用比较少,因为它会引起效率、性能以及维护等问题。如果碰到对表达式的解释,在 Java 中可以用 Expression4J 或 Jep 等来设计。

模式的扩展

在项目开发中,如果要对数据表达式进行分析与计算,无须再用解释器模式进行设计了,Java 提供了以下强大的数学公式解析器:Expression4J、MESP(Math Expression String Parser) 和 Jep 等,它们可以解释一些复杂的文法,功能强大,使用简单。

现在以 Jep 为例来介绍该工具包的使用方法。Jep 是 Java expression parser 的简称,即 Java 表达式分析器,它是一个用来转换和计算数学表达式的 Java 库。通过这个程序库,用户可以以字符串的形式输入一个任意的公式,然后快速地计算出其结果。而且 Jep 支持用户自定义变量、常量和函数,它包括许多常用的数学函数和常量。

使用前先下载 Jep 压缩包,解压后,将 jep-x.x.x.jar 文件移到选择的目录中,在 Eclipse 的“Java 构建路径”对话框的“库”选项卡中选择“添加外部 JAR(X)...”,将该 Jep 包添加项目中后即可使用其中的类库。

下面以计算存款利息为例来介绍。存款利息的计算公式是:本金x利率x时间=利息,其相关代码如下:

 
  1. package interpreterPattern;
  2. import com.singularsys.jep.*;
  3. public class JepDemo
  4. {
  5. public static void main(String[] args) throws JepException
  6. {
  7. Jep jep=new Jep();
  8. //定义要计算的数据表达式
  9. String 存款利息="本金*利率*时间";
  10. //给相关变量赋值
  11. jep.addVariable("本金",10000);
  12. jep.addVariable("利率",0.038);
  13. jep.addVariable("时间",2);
  14. jep.parse (deposit interest); // analytical expression
  15. Object accrual = jep.evaluate (); // calculate
  16. System.out.println ( "deposit interest:" + accrual);
  17. }
  18. }


Program results are as follows:

存款利息:760.0

Guess you like

Origin blog.csdn.net/yucaixiang/article/details/94628112