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

2025-05-29 0 28

本文实例讲述了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 该语言解释树结构

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

3 该语言解释器活动图

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

4 代码示例

4.1 创建上下文环境——context

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83
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<string, object> map = new hashmap<string, object>();

/**

* 构造方法设置解析内容

*

* @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<string>

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

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23
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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47
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)) {

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50
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<iexpressions> list = new arraylist<iexpressions>();

/**

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

while (iterator.hasnext()) {

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

}

}

}

4.5 命令表达式——commandexperssion

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39
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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87
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() {

// 建立命令表达式

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45
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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23
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程序设计有所帮助。

原文链接:https://blog.csdn.net/chengqiuming/article/details/70139382

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Java基于解释器模式实现定义一种简单的语言功能示例 https://www.kuaiidc.com/111577.html

相关文章

发表评论
暂无评论