Java基于解释器模式实现定义一种简单的语言功能示例

网友投稿 242 2023-08-05

Java基于解释器模式实现定义一种简单的语言功能示例

本文实例讲述了java基于解释器模式实现定义一种简单的语言功能。分享给大家供大家参考,具体如下:

一 模式定义

解释器模式:就是给定一个语言的文法表示,并且定义一个解释器,用来解释语言中的句子。解释器模式描述了怎样在有了一个简单的文法后,使用模式设计解释这些语句。

二 模式举例

1 模式分析

我们自己设计一种语言来说明这一模式

(1)该语言区分大小写

(2)该语言以PROGRAM开头,END结尾

(3)PRINTLN表示打印一行并换行

(4)使用FOR…FROM…TO…END表示循环

示例语言内容如下:

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

该句表示的意思是:首先打印“start…”换行,然后循环打印“90”换行、“91”换行、……“100”换行,最后打印“end…”换行。

2 该语言解释树结构

3 该语言解释器活动图

4 代码示例

4.1 创建上下文环境——Context

package com.demo.interpreter.context;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.StringTokenizer;

/**

* 上下文环境

*

* @author

*

*/

public class Context {

// 待解析的文本内容

private final StringTokenizer stringTokenizer;

// 当前命令

private String currentToken;

// 用来存储动态变化信息内容

private final Map map = new HashMap();

/**

* 构造方法设置解析内容

*

* @param text

*/

public Context(String text) {

// 使用空格分隔待解析文本内容

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;

}

/**

* 获得当前命令内容

*

* @return

*/

public String getCurrentToken() {

return this.currentToken;

}

/**

* 获得节点的内容

*

* @return

*/

public String getTokenContent(String text) {

String str = text;

if (str != null) { // 替换map中的动态变化内容后返回 Iterator

// 替换map中的动态变化内容后返回

Iterator 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 表达式接口——IExpressions

package com.demo.interpreter.express;

import com.demo.interpreter.context.Context;

/**

*

* 表达式接口

*

* @author

*

*/

public interface IExpressions {

/**

* 解析

*

* @param context

*/

public void parse(Context context);

/**

* 执行方法

*

* @param context

*/

public void interpret();

}

4.3 主表达式——ProgramExpression

package com.demo.interpreter.express;

import com.demo.interpreter.context.Context;

/**

* program 表达式

*

* @author

*

*/

public class ProgramExpression implements IExpressions {

// 上下文环境

private final Context context;

// 当前命令

private final static String COMMAND = "PROGRAM";

// 存储下一个表达式引用

private IExpressions expressions;

/**

* 构造方法将待解析的内容传入

*

* @param text

*/

public ProgramExpression(String text) {

this.context = new Context(text);

this.parse(this.context);

}

@Override

public void parse(Context context) {

// 获取第一个命令节点

this.context.next();

}

/**

* 实现解释方法

*/

@Override

public void interpret() {

// 判断是否是以PROGRAM 开始

if (!this.context.equalsWithCommand(COMMAND)) {

http:// System.out.println("The '" + COMMAND + "' is Excepted For Start!");

} else {

// 是以PROGRAM 开始

this.context.next();

this.expressions = new ListExpression();

this.expressions.parse(this.context);

// ListExpression表达式开始解析

this.expressions.interpret();

}

}

}

4.4 列表表达式——ListExpression

package com.demo.interpreter.express;

import java.util.ArrayList;

import java.util.Iterator;

import com.demo.interpreter.context.Context;

/**

* 列表表达式

*

* @author

*

*/

public class ListExpression implements IExpressions {

private Context context;

private final ArrayList list = new ArrayList();

/**

* 构造方法将待解析的context传入

*

* @param context

*/

public void parse(Context context) {

this.context = context;

// 在ListExpression解析表达式中,循环解释语句中的每一个单词,直到终结符表达式或者异常情况退出

while (true) {

if (this.context.getCurrentToken() == null) {

// 获取当前节点如果为 null 则表示缺少END表达式

System.out.println("Error: The Experssion Missing 'END'! ");

break;

} else if (this.context.equalsWithCommand("END")) {

this.context.next();

// 解析正常结束

break;

} else {

// 建立Command 表达式

IExpressions expressions = new CommandExperssion(this.context);

// 添加到列表中

list.add(expressions);

}

}

}

/**

* 实现解释方法

*/

@Override

public void interpret() {

// 循环list列表中每一个表达式 解释执行

Iterator iterator = list.iterator();

while (iterator.hasNext()) {

(iterator.next()).interpret();

}

}

}

4.5 命令表达式——CommandExperssion

package com.demo.interpreter.express;

import com.demo.interpreter.context.Context;

/**

* 命令表达式

*

* @author

*

*/

public class CommandExperssion implements IExpressions {

private final Context context;

private IExpressions expressions;

/**

* 构造方法将待解析的context传入

*

* @param context

*/

public CommandExperssion(Context context) {

this.context = context;

this.parse(this.context);

}

public void parse(Context context) {

// 判断当前命令类别 在此只对For和最原始命令进行区分

if (this.context.equalsWithCommand("FOR")) {

// 创建For表达式进行解析

expressions = new ForExpression(this.context);

} else {

// 创建原始命令表达式进行内容解析

expressions = new PrimitiveExpression(this.context);

}

}

/**

* 解析内容

*/

@Override

public void interpret() {

// 解析内容

this.expressions.interpret();

}

}

4.6 循环表达式——ForExpression

package com.demo.interpreter.express;

import com.demo.interpreter.context.Context;

/**

* For表达式

*

* @author

*

*/

public class ForExpression implements IExpressions {

private final Context context;

// 存储当前索引key值

private String variable;

// 存储循环起始位置

private int start_index;

// 存储循环结束位置

private int end_index;

private IExpressions expressions;

/**

* 构造方法将待解析的context传入

*

* @param context

*/

public ForExpression(Context context) {

this.context = context;

this.parse(this.context);

}

/**

* 解析表达式

*/

@Override

public void parse(Context context) {

// 首先获取当前节点

this.context.next();

while (true) {

// 判断节点

if (this.context.equalsWithCommand("FROM")) {

// 设置开始索引内容

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;

}

// 获取下一个节点

this.context.next();

} else if (this.context.equalsWithCommand("TO")) {

// 设置结束索引内容

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 {

// 设置当前索引变量内容

if (this.variable == null) {

this.variable = this.context.getCurrentToken();

}

// 获取下一个节点

this.context.next();

}

}

// 建立列表表达式

this.expressions = new ListExpression();

this.expressions.parse(this.context);

}

/**

* 实现解释方法

*/

@Override

public void interpret() {

// 建立命令表达式

ahUGWaLQzh for (int x = this.start_index; x <= this.end_index; x++) {

// 设置变量内容

this.context.put("" + this.variable, x);

// 执行解释方法

this.expressions.interpret();

}

// 移除使用的临时变量内容

this.context.clear("" + this.variable);

}

}

4.7 基础表达式——PrimitiveExpression

package com.demo.interpreter.express;

import com.demo.interpreter.context.Context;

/**

* 最基础的表达式

*

* @author

*

*/

public class PrimitiveExpression implements IExpressions {

private Context context;

// 节点名称

private String tokenName;

// 文本内容

private String text;

/**

* 构造方法将待解析的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();

}

}

/**

* 实现解释方法

*/

@Override

public void interpret() {

// 首先获取当前节点内容

if ("PRINTLN".equals(tokenName)) {

// 获得内容信息

// 打印内容

System.out.println(this.context.getTokenContent(this.text));

}

}

}

4.8 让语言解释器开始工作——Client

package com.demo.interpreter;

import com.demo.interpreter.express.IExpressions;

import com.demo.interpreter.express.ProgramExpression;

/**

* 主应用程序

*

* @author

*

*/

public class Client {

/**

* @param args

*/

public static void main(String[] args) {

// myida语言语句

String str = "PROGRAM PRINTLN start... FOR i FROM 90 TO 100 PRINTLN i END PRINTLN end... END";

System.out.println("str:" + str);

// 创建PROGRAM表达式

IExpressions expressions = new ProgramExpression(str);

// 解释执行

expressions.interpret();

}

}

5 运行结果

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...

三 设计原则

1 “开-闭”原则

2 封闭变化原则

四 使用场合

(1)一种特定类型的问题发生的频率足够高,并且业务规则频繁变化,不断重复出现类似情况。

(2)业务规则不是过于复杂烦琐,比较容易抽象出语法规则。

(3)效率不是软件系统中主要考虑的因素。

五 解释器模式静态类图

更多java相关内容感兴趣的读者可查看本站专题:《Java面向对象程序设计入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:深入浅析ZooKeeper的工作原理
下一篇:node使用promise替代回调函数
相关文章

 发表评论

暂时没有评论,来抢沙发吧~