欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java基于解釋器模式實(shí)現(xiàn)定義一種簡(jiǎn)單的語(yǔ)言功能示例

 更新時(shí)間:2018年05月07日 10:07:13   作者:chengqiuming  
這篇文章主要介紹了Java基于解釋器模式實(shí)現(xiàn)定義一種簡(jiǎn)單的語(yǔ)言功能,簡(jiǎn)單描述了解釋器模式的概念、功能及Java使用解釋器模式定義一種簡(jiǎn)單語(yǔ)言的相關(guān)實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下

本文實(shí)例講述了Java基于解釋器模式實(shí)現(xiàn)定義一種簡(jiǎn)單的語(yǔ)言功能。分享給大家供大家參考,具體如下:

一 模式定義

解釋器模式:就是給定一個(gè)語(yǔ)言的文法表示,并且定義一個(gè)解釋器,用來解釋語(yǔ)言中的句子。解釋器模式描述了怎樣在有了一個(gè)簡(jiǎn)單的文法后,使用模式設(shè)計(jì)解釋這些語(yǔ)句。

二 模式舉例

1 模式分析

我們自己設(shè)計(jì)一種語(yǔ)言來說明這一模式

(1)該語(yǔ)言區(qū)分大小寫
(2)該語(yǔ)言以PROGRAM開頭,END結(jié)尾
(3)PRINTLN表示打印一行并換行
(4)使用FOR…FROM…TO…END表示循環(huán)

示例語(yǔ)言內(nèi)容如下:

PROGRAM PRINTLN start... FOR i FROM 90 TO 100 PRINTLN i END PRINTLN end...END

該句表示的意思是:首先打印“start…”換行,然后循環(huán)打印“90”換行、“91”換行、……“100”換行,最后打印“end…”換行。

2 該語(yǔ)言解釋樹結(jié)構(gòu)

3 該語(yǔ)言解釋器活動(dòng)圖

4 代碼示例

4.1 創(chuàng)建上下文環(huán)境——Context

package com.demo.interpreter.context;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
/**
 * 上下文環(huán)境
 *
 * @author
 *
 */
public class Context {
  // 待解析的文本內(nèi)容
  private final StringTokenizer stringTokenizer;
  // 當(dāng)前命令
  private String currentToken;
  // 用來存儲(chǔ)動(dòng)態(tài)變化信息內(nèi)容
  private final Map<String, Object> map = new HashMap<String, Object>();
  /**
   * 構(gòu)造方法設(shè)置解析內(nèi)容
   *
   * @param text
   */
  public Context(String text) {
    // 使用空格分隔待解析文本內(nèi)容
    this.stringTokenizer = new StringTokenizer(text);
  }
  /**
   * 解析文本
   */
  public String next() {
    if (this.stringTokenizer.hasMoreTokens()) {
      currentToken = this.stringTokenizer.nextToken();
    } else {
      currentToken = null;
    }
    return currentToken;
  }
  /**
   * 判斷命令是否正確
   *
   * @param command
   * @return
   */
  public boolean equalsWithCommand(String command) {
    if (command == null || !command.equals(this.currentToken)) {
      return false;
    }
    return true;
  }
  /**
   * 獲得當(dāng)前命令內(nèi)容
   *
   * @return
   */
  public String getCurrentToken() {
    return this.currentToken;
  }
  /**
   * 獲得節(jié)點(diǎn)的內(nèi)容
   *
   * @return
   */
  public String getTokenContent(String text) {
    String str = text;
    if (str != null) { // 替換map中的動(dòng)態(tài)變化內(nèi)容后返回 Iterator<String>
      // 替換map中的動(dòng)態(tài)變化內(nèi)容后返回
      Iterator<String> iterator = this.map.keySet().iterator();
      while (iterator.hasNext()) {
        String key = iterator.next();
        Object obj = map.get(key);
        str = str.replaceAll(key, obj.toString());
      }
    }
    return str;
  }
  public void put(String key, Object value) {
    this.map.put(key, value);
  }
  public void clear(String key) {
    this.map.remove(key);
  }
}

4.2 表達(dá)式接口——IExpressions

package com.demo.interpreter.express;
import com.demo.interpreter.context.Context;
/**
 *
 * 表達(dá)式接口
 *
 * @author
 *
 */
public interface IExpressions {
  /**
   * 解析
   *
   * @param context
   */
  public void parse(Context context);
  /**
   * 執(zhí)行方法
   *
   * @param context
   */
  public void interpret();
}

4.3 主表達(dá)式——ProgramExpression

package com.demo.interpreter.express;
import com.demo.interpreter.context.Context;
/**
 * program 表達(dá)式
 *
 * @author
 *
 */
public class ProgramExpression implements IExpressions {
  // 上下文環(huán)境
  private final Context context;
  // 當(dāng)前命令
  private final static String COMMAND = "PROGRAM";
  // 存儲(chǔ)下一個(gè)表達(dá)式引用
  private IExpressions expressions;
  /**
   * 構(gòu)造方法將待解析的內(nèi)容傳入
   *
   * @param text
   */
  public ProgramExpression(String text) {
    this.context = new Context(text);
    this.parse(this.context);
  }
  @Override
  public void parse(Context context) {
    // 獲取第一個(gè)命令節(jié)點(diǎn)
    this.context.next();
  }
  /**
   * 實(shí)現(xiàn)解釋方法
   */
  @Override
  public void interpret() {
    // 判斷是否是以PROGRAM 開始
    if (!this.context.equalsWithCommand(COMMAND)) {
      System.out.println("The '" + COMMAND + "' is Excepted For Start!");
    } else {
      // 是以PROGRAM 開始
      this.context.next();
      this.expressions = new ListExpression();
      this.expressions.parse(this.context);
      // ListExpression表達(dá)式開始解析
      this.expressions.interpret();
    }
  }
}

4.4 列表表達(dá)式——ListExpression

package com.demo.interpreter.express;
import java.util.ArrayList;
import java.util.Iterator;
import com.demo.interpreter.context.Context;
/**
 * 列表表達(dá)式
 *
 * @author
 *
 */
public class ListExpression implements IExpressions {
  private Context context;
  private final ArrayList<IExpressions> list = new ArrayList<IExpressions>();
  /**
   * 構(gòu)造方法將待解析的context傳入
   *
   * @param context
   */
  public void parse(Context context) {
    this.context = context;
    // 在ListExpression解析表達(dá)式中,循環(huán)解釋語(yǔ)句中的每一個(gè)單詞,直到終結(jié)符表達(dá)式或者異常情況退出
    while (true) {
      if (this.context.getCurrentToken() == null) {
        // 獲取當(dāng)前節(jié)點(diǎn)如果為 null 則表示缺少END表達(dá)式
        System.out.println("Error: The Experssion Missing 'END'! ");
        break;
      } else if (this.context.equalsWithCommand("END")) {
        this.context.next();
        // 解析正常結(jié)束
        break;
      } else {
        // 建立Command 表達(dá)式
        IExpressions expressions = new CommandExperssion(this.context);
        // 添加到列表中
        list.add(expressions);
      }
    }
  }
  /**
   * 實(shí)現(xiàn)解釋方法
   */
  @Override
  public void interpret() {
    // 循環(huán)list列表中每一個(gè)表達(dá)式 解釋執(zhí)行
    Iterator<IExpressions> iterator = list.iterator();
    while (iterator.hasNext()) {
      (iterator.next()).interpret();
    }
  }
}

4.5 命令表達(dá)式——CommandExperssion

package com.demo.interpreter.express;
import com.demo.interpreter.context.Context;
/**
 * 命令表達(dá)式
 *
 * @author
 *
 */
public class CommandExperssion implements IExpressions {
  private final Context context;
  private IExpressions expressions;
  /**
   * 構(gòu)造方法將待解析的context傳入
   *
   * @param context
   */
  public CommandExperssion(Context context) {
    this.context = context;
    this.parse(this.context);
  }
  public void parse(Context context) {
    // 判斷當(dāng)前命令類別 在此只對(duì)For和最原始命令進(jìn)行區(qū)分
    if (this.context.equalsWithCommand("FOR")) {
      // 創(chuàng)建For表達(dá)式進(jìn)行解析
      expressions = new ForExpression(this.context);
    } else {
      // 創(chuàng)建原始命令表達(dá)式進(jìn)行內(nèi)容解析
      expressions = new PrimitiveExpression(this.context);
    }
  }
  /**
   * 解析內(nèi)容
   */
  @Override
  public void interpret() {
    // 解析內(nèi)容
    this.expressions.interpret();
  }
}

4.6 循環(huán)表達(dá)式——ForExpression

package com.demo.interpreter.express;
import com.demo.interpreter.context.Context;
/**
 * For表達(dá)式
 *
 * @author
 *
 */
public class ForExpression implements IExpressions {
  private final Context context;
  // 存儲(chǔ)當(dāng)前索引key值
  private String variable;
  // 存儲(chǔ)循環(huán)起始位置
  private int start_index;
  // 存儲(chǔ)循環(huán)結(jié)束位置
  private int end_index;
  private IExpressions expressions;
  /**
   * 構(gòu)造方法將待解析的context傳入
   *
   * @param context
   */
  public ForExpression(Context context) {
    this.context = context;
    this.parse(this.context);
  }
  /**
   * 解析表達(dá)式
   */
  @Override
  public void parse(Context context) {
    // 首先獲取當(dāng)前節(jié)點(diǎn)
    this.context.next();
    while (true) {
      // 判斷節(jié)點(diǎn)
      if (this.context.equalsWithCommand("FROM")) {
        // 設(shè)置開始索引內(nèi)容
        String nextStr = this.context.next();
        try {
          this.start_index = Integer.parseInt(nextStr);
        } catch (Exception e) {
          System.out
              .println("Error: After 'FROM' Expression Exist Error!Please Check the Format Of Expression is Correct!");
          break;
        }
        // 獲取下一個(gè)節(jié)點(diǎn)
        this.context.next();
      } else if (this.context.equalsWithCommand("TO")) {
        // 設(shè)置結(jié)束索引內(nèi)容
        String nextStr = this.context.next();
        try {
          this.end_index = Integer.parseInt(nextStr);
        } catch (Exception e) {
          System.out
              .println("Error: After 'TO' Expression Exist Error!Please Check the Format Of Expression is Correct!");
        }
        this.context.next();
        break;
      } else {
        // 設(shè)置當(dāng)前索引變量?jī)?nèi)容
        if (this.variable == null) {
          this.variable = this.context.getCurrentToken();
        }
        // 獲取下一個(gè)節(jié)點(diǎn)
        this.context.next();
      }
    }
    // 建立列表表達(dá)式
    this.expressions = new ListExpression();
    this.expressions.parse(this.context);
  }
  /**
   * 實(shí)現(xiàn)解釋方法
   */
  @Override
  public void interpret() {
    // 建立命令表達(dá)式
    for (int x = this.start_index; x <= this.end_index; x++) {
      // 設(shè)置變量?jī)?nèi)容
      this.context.put("" + this.variable, x);
      // 執(zhí)行解釋方法
      this.expressions.interpret();
    }
    // 移除使用的臨時(shí)變量?jī)?nèi)容
    this.context.clear("" + this.variable);
  }
}

4.7 基礎(chǔ)表達(dá)式——PrimitiveExpression

package com.demo.interpreter.express;
import com.demo.interpreter.context.Context;
/**
 * 最基礎(chǔ)的表達(dá)式
 *
 * @author
 *
 */
public class PrimitiveExpression implements IExpressions {
  private Context context;
  // 節(jié)點(diǎn)名稱
  private String tokenName;
  // 文本內(nèi)容
  private String text;
  /**
   * 構(gòu)造方法將待解析的context傳入
   *
   * @param context
   */
  public PrimitiveExpression(Context context) {
    this.parse(context);
  }
  @Override
  public void parse(Context context) {
    this.context = context;
    this.tokenName = this.context.getCurrentToken();
    this.context.next();
    if ("PRINTLN".equals(this.tokenName)) {
      this.text = this.context.getCurrentToken();
      this.context.next();
    }
  }
  /**
   * 實(shí)現(xiàn)解釋方法
   */
  @Override
  public void interpret() {
    // 首先獲取當(dāng)前節(jié)點(diǎn)內(nèi)容
    if ("PRINTLN".equals(tokenName)) {
      // 獲得內(nèi)容信息
      // 打印內(nèi)容
      System.out.println(this.context.getTokenContent(this.text));
    }
  }
}

4.8 讓語(yǔ)言解釋器開始工作——Client

package com.demo.interpreter;
import com.demo.interpreter.express.IExpressions;
import com.demo.interpreter.express.ProgramExpression;
/**
 * 主應(yīng)用程序
 *
 * @author
 *
 */
public class Client {
  /**
   * @param args
   */
  public static void main(String[] args) {
    // myida語(yǔ)言語(yǔ)句
    String str = "PROGRAM PRINTLN start... FOR i FROM 90 TO 100 PRINTLN i END PRINTLN end... END";
    System.out.println("str:" + str);
    // 創(chuàng)建PROGRAM表達(dá)式
    IExpressions expressions = new ProgramExpression(str);
    // 解釋執(zhí)行
    expressions.interpret();
  }
}

5 運(yùn)行結(jié)果

str:PROGRAM PRINTLN start... FOR i FROM 90 TO 100 PRINTLN i END PRINTLN end... END
start...
90
91
92
93
94
95
96
97
98
99
100
end...

三 設(shè)計(jì)原則

1 “開-閉”原則

2 封閉變化原則

四 使用場(chǎng)合

(1)一種特定類型的問題發(fā)生的頻率足夠高,并且業(yè)務(wù)規(guī)則頻繁變化,不斷重復(fù)出現(xiàn)類似情況。

(2)業(yè)務(wù)規(guī)則不是過于復(fù)雜煩瑣,比較容易抽象出語(yǔ)法規(guī)則。

(3)效率不是軟件系統(tǒng)中主要考慮的因素。

五 解釋器模式靜態(tài)類圖

更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O(shè)計(jì)入門與進(jìn)階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • SpringBoot集成Redis及SpringCache緩存管理示例詳解

    SpringBoot集成Redis及SpringCache緩存管理示例詳解

    本文介紹了如何在SpringBoot中集成Redis并使用SpringCache進(jìn)行緩存管理,詳解了Redis的配置、使用以及SpringCache的注解,還闡述了SpringCache的工作原理,包括其AOP實(shí)現(xiàn)和與各種緩存框架的集成,使得開發(fā)者可以輕松實(shí)現(xiàn)緩存功能,以提高應(yīng)用性能
    2024-09-09
  • Java實(shí)現(xiàn)深度搜索DFS算法詳解

    Java實(shí)現(xiàn)深度搜索DFS算法詳解

    深度優(yōu)先搜索是一種在開發(fā)爬蟲早期使用較多的方法。它的目的是要達(dá)到被搜索結(jié)構(gòu)的葉結(jié)點(diǎn)。這篇文章主要介紹了基于Java實(shí)現(xiàn)深度優(yōu)先搜索(DFS)算法,需要的朋友可以參考一下
    2021-12-12
  • java synchronized關(guān)鍵字的用法

    java synchronized關(guān)鍵字的用法

    synchronized關(guān)鍵字我們大家都知道是線程同步關(guān)鍵字.總結(jié)一下日常的使用方法,還有一個(gè)坑.
    2016-05-05
  • Java springboot Mongodb增刪改查代碼實(shí)例

    Java springboot Mongodb增刪改查代碼實(shí)例

    這篇文章主要介紹了Java springboot Mongodb增刪改查代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java8實(shí)現(xiàn)Stream流的合并的方法展示

    Java8實(shí)現(xiàn)Stream流的合并的方法展示

    本文介紹了Java8中Stream流的合并方法,包括concat()、flatMap()和reduce()三種方法。其中,concat()方法可以將兩個(gè)Stream流合并成一個(gè),flatMap()方法可以將一個(gè)Stream流中的元素映射成多個(gè)Stream流并合并成一個(gè),reduce()方法可以將Stream流中的元素逐個(gè)合并成一個(gè)結(jié)果
    2023-05-05
  • 老生常談spring的事務(wù)傳播機(jī)制

    老生常談spring的事務(wù)傳播機(jī)制

    這篇文章主要介紹了spring的事務(wù)傳播機(jī)制,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 解決使用json-lib包實(shí)現(xiàn)xml轉(zhuǎn)json時(shí)空值被轉(zhuǎn)為空中括號(hào)的問題

    解決使用json-lib包實(shí)現(xiàn)xml轉(zhuǎn)json時(shí)空值被轉(zhuǎn)為空中括號(hào)的問題

    網(wǎng)上能查到的xml轉(zhuǎn)json的jar包大部分是net.sf.json-lib,但是JSON json =xmlSerializer.read(xml); 方法會(huì)出現(xiàn)將空值轉(zhuǎn)化為[]的問題,下面為大家提供兩種解決方法
    2018-03-03
  • java連接mongoDB并進(jìn)行增刪改查操作實(shí)例詳解

    java連接mongoDB并進(jìn)行增刪改查操作實(shí)例詳解

    這篇文章主要介紹了java連接mongoDB并進(jìn)行增刪改查操作,結(jié)合實(shí)例形式詳細(xì)分析了java環(huán)境下MongoDB擴(kuò)展包的下載、安裝及操作MongoDB連接、增刪改查等相關(guān)操作技巧,需要的朋友可以參考下
    2019-04-04
  • Java如何發(fā)起http請(qǐng)求的實(shí)現(xiàn)(GET/POST)

    Java如何發(fā)起http請(qǐng)求的實(shí)現(xiàn)(GET/POST)

    這篇文章主要介紹了Java如何發(fā)起http請(qǐng)求的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • SpringBoot整合Lombok插件與使用詳解

    SpringBoot整合Lombok插件與使用詳解

    Lombok是Java開發(fā)的插件,通過注解自動(dòng)生成常用代碼,如getter/setter,節(jié)省開發(fā)時(shí)間,提高效率,它在編譯期生成方法,不影響性能,安裝Lombok需要添加Maven依賴和IDEA插件,使用注解如@Data、@Getter等簡(jiǎn)化代碼編寫,官網(wǎng)提供詳細(xì)文檔
    2024-09-09

最新評(píng)論