Interpreter Pattern

来源:https://www.cnblogs.com/mysticbinary/archive/2023/09/08/17686606.html
-Advertisement-
Play Games

# It can explain what ? 如下是解釋器要解釋的主體: - 加減乘除等運算,3+4/9+6*8 - 摩爾斯電碼 - 正則表達式 - El表達式 - OGNL表達式 - 小明是北京人 - 小紅是一名售貨員 - 部門領導下發一則通知 - ... # How explain ? 解釋器 ...


It can explain what ?

如下是解釋器要解釋的主體:

  • 加減乘除等運算,3+4/9+6*8
  • 摩爾斯電碼
  • 正則表達式
  • El表達式
  • OGNL表達式
  • 小明是北京人
  • 小紅是一名售貨員
  • 部門領導下發一則通知
  • ...

How explain ?

解釋器模式常用於對簡單語言集的編譯或分析,例如:

  • 我是大學生
  • 張強學習編程
  • 小明是北京人
  • 部門領導下發一則通知

為了掌握好它的結構與實現,需要先瞭解編譯原理中的文法句子語法樹等相關概念。(其實不瞭解也行,可以直接看code,在回來看)

這裡提到的文法和句子的概念同編譯原理中的描述相同,

  • 文法指語言的語法規則
    如何解釋語言的規則
  • 句子是語言集中的元素
    例如,漢語中的句子有很多,“我是大學生”是其中的一個句子,可以用一棵語法樹來直觀地描述語言中的句子。

Grammar Concept

這個是分析的關鍵。

〈句子〉::=〈主語〉〈謂語〉〈賓語〉
〈主語〉::=〈代詞〉|〈名詞〉
〈謂語〉::=〈動詞〉
〈賓語〉::=〈代詞〉|〈名詞〉
〈代詞〉::= 你 | 我 | 他
〈名詞〉::= 大學生 | 小明 | 英語 | 張強
〈動詞〉::= 是 | 學習

註意:

  • ::= 表示“定義為”的意思;
  • 括住的是非終結符沒有括住的是終結符;
  • | 是 邏輯符號or.

Sentence

句子是語言的基本單位,是語言集中的一個元素,它由終結符構成,能由"文法"推導出
例如,上述文法可以推出“我是大學生”,所以它是句子。

Syntax Tree

語法樹是句子結構的一種樹型表示,它代表了句子的推導結果,它有利於理解句子語法結構的層次。

“我是大學生”的語法樹如圖所示:

<expression> ::= <代詞>是<名詞>
<代詞> ::= 我 | 你 | 他 | 她
<名詞> ::= 大學生 | 程式員 | 牲口 | 懦夫

終結符和非終結符

終結符表達式(Terminal Expression):
就是一個最終的元素,不可在向下分割。

非終結符表達式(Nonterminal Expression):
非終結符需要依照文法規則去分割,文法中的每條規則都對應於一個非終結符表達式。

Key Elements

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

  • 抽象表達式(Abstract Expression)角色:定義解釋器的介面,約定解釋器的解釋操作,主要包含解釋方法 interpret()。
  • 終結符表達式(Terminal Expression)角色:是抽象表達式的子類,用來實現文法中與終結符相關的操作,文法中的每一個終結符都有一個具體終結表達式與之相對應。
  • 非終結符表達式(Nonterminal Expression)角色:也是抽象表達式的子類,用來實現文法中與非終結符相關的操作,文法中的每條規則都對應於一個非終結符表達式。
  • 環境(Context)角色:通常包含各個解釋器需要的數據或是公共的功能,一般用來傳遞被所有解釋器共用的數據,後面的解釋器可以從這裡獲取這些值。
  • 客戶端(Client):主要任務是將需要分析的句子或表達式轉換成使用解釋器對象描述的抽象語法樹,然後調用解釋器的解釋方法,當然也可以通過環境角色間接訪問解釋器的解釋方法。

Example —— 公交車身份識別系統

需求描述:每個人坐車都需要繳費,每個人上車後需要刷自己的公交卡卡,每個人的卡裡都有每個人的信息,信息如下:

  • "韶關的老人";
  • "韶關的年輕人";
  • "廣州的婦女";
  • "廣州的兒童";
  • "山東的兒童";

你需要寫一個解釋器去識別每個人的身份,如果是“韶關”或者“廣州”的“老人” “婦女”“兒童”就可以免費乘車,其他人員乘車一次扣 2 元。

分析:本實例用“解釋器模式”設計比較適合,首先設計其文法規則如下:

<expression> ::= <city>的<person>
<city> ::= 韶關 | 廣州
<person> ::= 老人 | 婦女 | 兒童

Client

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ### 前言 上篇文章 [13分鐘聊聊併發包中常用同步組件並手寫一個自定義同步組件](https://juejin.cn/post/7274475842998042665) 聊到併發包中常用的同步組件,並且還手把手實現了自定義的同步組件 本篇文章來聊聊併發包下的另一個核心-線程池 閱讀本文大概12分 ...
  • # Python初步瞭解裝飾器 - 裝飾器的概念 - 裝飾器的簡單使用 - 裝飾器的進階 - 裝飾器的練習 - 裝飾器的固定模塊 - 裝飾器的語法糖 ## 裝飾器的概念 ```python 裝飾器它不是一個新的知識點,它是有之前我們學習的名稱空間、函數嵌套、閉包函數等知識點彙總而來 器:工具 裝飾: ...
  • 在軟體開發中,我們經常會遇到這樣的情況:我們需要使用一個現有的類或者介面,但它與我們系統的目標介面不相容,而我們又不能修改它。這時候,我們該怎麼辦呢?大多數情況下我們都可以使用適配器模式來解決這個問題,**本文將從以下四個方面講解適配器模式**。 - 簡介 - 優缺點 - 應用場景 - Java 代 ...
  • ## 1. 什麼是Http2.0 HTTP/2.0,通常簡稱為HTTP/2,是一種用於傳輸超文本(例如網頁和資源文件)的網路協議。它是HTTP/1.1的繼任者,旨在提高性能和效率,以適應現代Web應用的需求。HTTP/2的主要特點包括以下幾點: 1. **多路復用(Multiplexing)**:H ...
  • 光看訪客這個名字,猜測這個訪客模式應該非常好理解,只要玩過Linux的人,都能深刻明白Root和非Root和訪客賬號登錄的巨大差別性。 # What is Visitor? 如果你沒玩過Linux,那麼假設公共的圖書館有一臺電腦,有兩個賬戶: - 其中一個是**管理員(Admin)**的賬戶,擁有這 ...
  • 作者:是奉壹呀 \ 來源:juejin.cn/post/7262274383287500860 看到一個評論,裡面提到了list.sort()和list.strem().sorted()排序的差異。 說到list sort()排序比stream().sorted()排序性能更好,但沒說到為什麼。 ! ...
  • Sermant是基於Java位元組碼增強技術的無代理服務網格,其利用Java位元組碼增強技術為宿主應用程式提供服務治理功能。 ...
  • 京東茅臺搶購腳本可以分為以下幾部分,具體實現步驟如下: 登錄京東賬號 首先需要登錄京東賬號。一個簡單的方式是使用Python的 selenium 庫。在使用 selenium 庫前,需要安裝 selenium 庫和對應的瀏覽器驅動。 示例代碼如下所示: from selenium import we ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...