Interpreter Pattern

打印 上一主题 下一主题

主题 942|帖子 942|积分 2826

It can explain what ?

如下是解释器要解释的主体:

  • 加减乘除等运算,3+4/9+6*8
  • 摩尔斯电码
  • 正则表达式
  • El表达式
  • OGNL表达式
  • 小明是北京人
  • 小红是一名售货员
  • 部门领导下发一则通知
  • ...
How explain ?

解释器模式常用于对简单语言集的编译或分析,例如:

  • 我是大学生
  • 张强学习编程
  • 小明是北京人
  • 部门领导下发一则通知
为了掌握好它的结构与实现,需要先了解编译原理中的文法、句子、语法树等相关概念。(其实不了解也行,可以直接看code,在回来看)
这里提到的文法和句子的概念同编译原理中的描述相同,

  • 文法指语言的语法规则
    如何解释语言的规则
  • 句子是语言集中的元素
    例如,汉语中的句子有很多,“我是大学生”是其中的一个句子,可以用一棵语法树来直观地描述语言中的句子。
Grammar Concept

这个是分析的关键。
〈句子〉::=〈主语〉〈谓语〉〈宾语〉
〈主语〉::=〈代词〉|〈名词〉
〈谓语〉::=〈动词〉
〈宾语〉::=〈代词〉|〈名词〉
〈代词〉::= 你 | 我 | 他
〈名词〉::= 大学生 | 小明 | 英语 | 张强
〈动词〉::= 是 | 学习
注意:

  • ::= 表示“定义为”的意思;
  • 用〈和 〉括住的是非终结符, 没有括住的是终结符;
  • | 是 逻辑符号or.
Sentence

句子是语言的基本单位,是语言集中的一个元素,它由终结符构成,能由"文法"推导出
例如,上述文法可以推出“我是大学生”,所以它是句子。
Syntax Tree

语法树是句子结构的一种树型表示,它代表了句子的推导结果,它有利于理解句子语法结构的层次。
“我是大学生”的语法树如图所示:
  1. <expression> ::= <代词>是<名词>
  2. <代词> ::= 我 | 你 | 他 | 她
  3. <名词> ::= 大学生 | 程序员 | 牲口 | 懦夫
复制代码
终结符和非终结符

终结符表达式(Terminal Expression):
就是一个最终的元素,不可在向下分割。
非终结符表达式(Nonterminal Expression):
非终结符需要依照文法规则去分割,文法中的每条规则都对应于一个非终结符表达式。
Key Elements

解释器模式包含以下主要角色。

  • 抽象表达式(Abstract Expression)角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
  • 终结符表达式(Terminal    Expression)角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
  • 非终结符表达式(Nonterminal Expression)角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
  • 环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
  • 客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。
Example —— 公交车身份识别系统

需求描述:每个人坐车都需要缴费,每个人上车后需要刷自己的公交卡卡,每个人的卡里都有每个人的信息,信息如下:

  • "韶关的老人";
  • "韶关的年轻人";
  • "广州的妇女";
  • "广州的儿童";
  • "山东的儿童";
你需要写一个解释器去识别每个人的身份,如果是“韶关”或者“广州”的“老人” “妇女”“儿童”就可以免费乘车,其他人员乘车一次扣 2 元。
分析:本实例用“解释器模式”设计比较适合,首先设计其文法规则如下:
  1. <expression> ::= <city>的<person>
  2. <city> ::= 韶关 | 广州
  3. <person> ::= 老人 | 妇女 | 儿童
复制代码
Client
  1. public static void main(String[] args){
  2.       Context bus=new Context();
  3.       bus.freeRide("韶关的老人");
  4.       bus.freeRide("韶关的年轻人");
  5.       bus.freeRide("广州的妇女");
  6.       bus.freeRide("广州的儿童");
  7.       bus.freeRide("山东的儿童");
  8. }
复制代码
Context
  1. class Context {
  2.     private String[] citys = {"韶关", "广州"};
  3.     private String[] persons = {"老人", "妇女", "儿童"};
  4.     private Expression cityPerson;
  5.     public Context() {
  6.         Expression city = new TerminalExpression(citys);
  7.         Expression person = new TerminalExpression(persons);
  8.         cityPerson = new AndExpression(city, person);
  9.     }
  10.     public void freeRide(String info) {
  11.         boolean ok = cityPerson.interpret(info);
  12.         if (ok) System.out.println("您是" + info + ",您本次乘车免费!");
  13.         else System.out.println(info + ",您不是免费人员,本次乘车扣费2元!");
  14.     }
  15. }
复制代码
  1. //抽象表达式类
  2. interface Expression {
  3.     public boolean interpret(String info);
  4. }
  5. //终结符表达式类
  6. class TerminalExpression implements Expression {
  7.     private Set<String> set = new HashSet<String>();
  8.     public TerminalExpression(String[] data) {
  9.         for (int i = 0; i < data.length; i++) set.add(data[i]);
  10.     }
  11.     public boolean interpret(String info) {
  12.         if (set.contains(info))
  13.             return true;
  14.         return false;
  15.     }
  16. }
  17. //非终结符表达式类
  18. class AndExpression implements Expression {
  19.     private Expression city = null;
  20.     private Expression person = null;
  21.     public AndExpression(Expression city, Expression person) {
  22.         this.city = city;
  23.         this.person = person;
  24.     }
  25.     public boolean interpret(String info) {
  26.         String s[] = info.split("的");
  27.         System.out.println(city.interpret(s[0]) && person.interpret(s[1]));
  28.         return city.interpret(s[0]) && person.interpret(s[1]);
  29.     }
  30. }
复制代码
out:
  1. true
  2. 您是韶关的老人,您本次乘车免费!
  3. false
  4. 韶关的年轻人,您不是免费人员,本次乘车扣费2元!
  5. true
  6. 您是广州的妇女,您本次乘车免费!
  7. true
  8. 您是广州的儿童,您本次乘车免费!
  9. false
  10. 山东的儿童,您不是免费人员,本次乘车扣费2元!
复制代码
Reference

设计模式之解释器模式(Interpreter)详解及代码示例
https://www.cnblogs.com/jing99/p/12610089.html

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

金歌

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表