首页 > 其他分享 >Interpreter Pattern

Interpreter Pattern

时间:2023-09-08 13:56:06浏览次数:35  
标签:解释器 终结符 Pattern 文法 Interpreter Expression 句子 表达式

It can explain what ?

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

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

How explain ?

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

  • 我是大学生
  • 张强学习编程
  • 小明是北京人
  • 部门领导下发一则通知

为了掌握好它的结构与实现,需要先了解编译原理中的文法句子语法树等相关概念。(其实不了解也行,可以直接看code,在回来看)

这里提到的文法和句子的概念同编译原理中的描述相同,

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

Grammar Concept

这个是分析的关键。

〈句子〉::=〈主语〉〈谓语〉〈宾语〉
〈主语〉::=〈代词〉|〈名词〉
〈谓语〉::=〈动词〉
〈宾语〉::=〈代词〉|〈名词〉
〈代词〉::= 你 | 我 | 他
〈名词〉::= 大学生 | 小明 | 英语 | 张强
〈动词〉::= 是 | 学习

注意:

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

Sentence

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

Syntax Tree

语法树是句子结构的一种树型表示,它代表了句子的推导结果,它有利于理解句子语法结构的层次。

“我是大学生”的语法树如图所示:

终结符和非终结符

终结符表达式(Terminal Expression):
就是一个最终的元素,不可在向下分割。

非终结符表达式(Nonterminal Expression):
非终结符需要依照文法规则去分割,文法中的每条规则都对应于一个非终结符表达式。

Key Elements

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

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

Example —— 公交车身份识别系统

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

  • "韶关的老人";
  • "韶关的年轻人";
  • "广州的妇女";
  • "广州的儿童";
  • "山东的儿童";

你需要写一个解释器去识别每个人的身份,如果是“韶关”或者“广州”的“老人” “妇女”“儿童”就可以免费乘车,其他人员乘车一次扣 2 元。

分析:本实例用“解释器模式”设计比较适合,首先设计其文法规则如下:

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

Client

public class Client {

    /*文法规则
        <expression> ::= <city>的<person>
            <city> ::=  韶关 | 广州
            <person> ::= 老人 | 妇女 | 儿童
    */

    public static void main(String[] args)
    {
        Context bus=new Context();
        bus.freeRide("韶关的老人");
        bus.freeRide("韶关的年轻人");
        bus.freeRide("广州的妇女");
        bus.freeRide("广州的儿童");
        bus.freeRide("山东的儿童");
    }
}

Context

class Context {
    private String[] citys = {"韶关", "广州"};
    private String[] persons = {"老人", "妇女", "儿童"};
    private Expression cityPerson;

    public Context() {
        Expression city = new TerminalExpression(citys);
        Expression person = new TerminalExpression(persons);
        cityPerson = new AndExpression(city, person);
    }

    public void freeRide(String info) {
        boolean ok = cityPerson.interpret(info);
        if (ok) System.out.println("您是" + info + ",您本次乘车免费!");
        else System.out.println(info + ",您不是免费人员,本次乘车扣费2元!");
    }
}
//抽象表达式类
interface Expression {
    public boolean interpret(String info);
}

//终结符表达式类
class TerminalExpression implements Expression {
    private Set<String> set = new HashSet<String>();

    public TerminalExpression(String[] data) {
        for (int i = 0; i < data.length; i++) set.add(data[i]);
    }

    public boolean interpret(String info) {
        if (set.contains(info))
            return true;
        return false;
    }
}

//非终结符表达式类
class AndExpression implements Expression {
    private Expression city = null;
    private Expression person = null;

    public AndExpression(Expression city, Expression person) {
        this.city = city;
        this.person = person;
    }

    public boolean interpret(String info) {
        String s[] = info.split("的");
        System.out.println(city.interpret(s[0]) && person.interpret(s[1]));
        return city.interpret(s[0]) && person.interpret(s[1]);
    }
}

out:

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

Reference

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

标签:解释器,终结符,Pattern,文法,Interpreter,Expression,句子,表达式
From: https://www.cnblogs.com/mysticbinary/p/17686606.html

相关文章

  • Mediator Pattern
    MediatorPattern就类似现实生活中的中介(中间人),房屋中介、媒婆中介、权利寻租中介...,现实中为什么需要中介,在现实中的原因主要是两个一为了保护双方当事人的安全,只要中介人不泄密,他们双方就可以秘密的把交易完成,并且双方都是安全的。二是买卖双方并不信任双方,但是他们都共同的......
  • Bridge Pattern
    WhatisBridgePattern桥接模式(BridgePattern),旨在将抽象部分和实现部分解耦,使它们可以独立地变化。该模式通过将抽象和实现分离,使它们可以独立地进行扩展和修改,同时通过桥接(Bridge)将它们连接起来。将一个事物原本耦合在一起的东西,通过定义成抽象和实现两个维度,做到解耦,解耦就......
  • Template Pattern —— Behavioral Class
    HookMethod钩子方法(HookMethod)之所以被称为“钩子”,是因为它在算法或流程中提供了一个“钩子”,允许子类在特定的点上“钩入”自己的实现逻辑,从而影响算法的行为或流程的执行。它类似于一个挂钩、锚点,所以叫Hookmethod,它允许子类插入自定义的代码来改变或扩展算法的功能。T......
  • Flyweight Pattern —— Creational Class
    享元模式在主流的标准里是放到结构大类下的,但是我感觉这个模式的最终作用也是为了获取一个类,所以我将其划分到创建大类下。WhatisFlyweightPatternFlyweight是指轻量级的。享元模式旨在支持大量细粒度的对象共享,以减少内存消耗。该模式通过共享相似对象的部分状态,来减少对......
  • Factory Pattern —— Creational Class
    core工厂模式(FactoryPattern)是一种创建型设计模式,用于创建对象而不暴露对象创建的逻辑。它将对象的实例化过程封装在一个工厂类中,客户端通过调用工厂类的方法来创建对象,从而实现了解耦和灵活性。工厂模式的核心思想是将对象的创建与使用分离。客户端不直接实例化对象,而是通过调......
  • 20230626 java.util.regex.Pattern
    介绍java.util.regex.PatternpublicfinalclassPatternimplementsjava.io.Serializable正则表达式的编译表示API常量flagUNIX_LINES启用UNIX行模式在多行模式中匹配^和$时,只有\n被识别成行终止符CASE_INSENSITIVE不区分大小写匹配字符时忽略字母的......
  • Visitor Pattern-访问者模式
    C#中的访问者模式(VisitorPattern)是一种行为型设计模式,它将数据结构和数据操作分离,使得可以在不修改数据结构的前提下定义新的操作。访问者模式的核心思想是将数据结构和数据操作解耦,将数据操作封装到独立的访问者类中。数据结构定义一组元素,每个元素接受访问者的访问并调用相应......
  • Strategy Pattern-策略模式
    C#中的策略模式(StrategyPattern)是一种行为型设计模式,它可以让你定义一族算法,并将每个算法封装起来,使它们可以相互替换,从而使得算法的变化独立于使用算法的客户端。策略模式的核心思想是将算法的定义和使用分离,将不同的算法封装到独立的策略类中。这样,客户端可以根据需求从不同的......
  • StatePattern-状态模式
    C#中的状态模式是一种行为型设计模式,它允许对象在其内部状态发生改变时改变其行为。状态模式的核心思想是将对象的行为封装在不同的状态类中,对象根据当前状态的不同而执行不同的行为。在C#中,实现状态模式通常需要以下几个参与者:状态接口(StateInterface):定义了表示不同状态的方法......
  • SAP ABAP 模式(Pattern)、模板的创建与调用
    1.代码模板2.模式(Pattern) 调用3.标准模式,一些内置固定格式代码的填充  ......