linux io测试陈旭,130242014076+陈旭+第2次实验(示例代码)

该博客介绍了如何使用Java实现一个四则运算的简易解释器,包括处理加减乘除、整数操作、错误处理等功能。此外,还探讨了管道过滤器风格的软件体系结构,通过示例展示了词法分析和语法分析的过程。实验旨在帮助读者理解解释器工作原理和编译器模型。
摘要由CSDN通过智能技术生成

软件体系结构的第二次实验(解释器风格与管道过滤器风格)

一、实验目的

1.熟悉体系结构的风格的概念

2.理解和应用管道过滤器型的风格。

3、理解解释器的原理

4、理解编译器模型

二、实验环境

硬件:

软件:Python或任何一种自己喜欢的语言

三、实验内容

1、实现“四则运算”的简易翻译器。

结果要求:

1)实现加减乘除四则运算,允许同时又多个操作数,如:2+3*5-6 结果是11

2)被操作数为整数,整数可以有多位

3)处理空格

4)输入错误显示错误提示,并返回命令状态“CALC”

20180111005536979044.png

图1    实验结果示例

加强练习:

1、有能力的同学,可以尝试实现赋值语句,例如x=2+3*5-6,返回x=11。(注意:要实现解释器的功能,而不是只是显示)

2、尝试实现自增和自减符号,例如x++

3、采用管道-过滤器(Pipes and Filters)风格实现解释器

20180111005536980021.png

图2  管道-过滤器风格

20180111005536981974.png

图 3  编译器模型示意图

本实验,实现的是词法分析和语法分析两个部分。

四、实验步骤:

代码如下:

1 packagecom.brainstrong.uamis.util;2

3 importjava.io.InputStream;4 importjava.util.ArrayList;5 importjava.util.List;6 importjava.util.Scanner;7 importjava.util.StringTokenizer;8

9 /**

10 * JAVA实现四则运算解释器11 *12 *@author旭旭13 * @create 2017-10-27 19:4314 **/

15 public classCalc {16

17 public static voidmain(String[] args) {18 Scanner scanner = newScanner(System.in);19 String exp =scanner.nextLine();20 System.out.println(calc(exp));21 }22

23 /**

24 *25 *@paramexp 四则表达式26 *@return

27 */

28 public static doublecalc(String exp){29 //1.把表示负数的-号换成@号

30 exp =negativeToAtChar(exp);31 //2.数字的分类

32 List numbers =splitNumExp(exp);33 //3.运算符的分离

34 List ops =splitOpfromExp(exp);35 //4.先乘除

36 for (int i = 0; i < ops.size(); i++) {37 //判断,运算符是否是乘除

38 char op =ops.get(i);39 //是,取出,运算

40 if (op == ‘*‘ || op == ‘/‘) {41 //取出来,运算

42 ops.remove(i);//后面的数据往前顺序移动43 //运算44 //从数字容器中取出对应运算符的两个数字

45 double d1 =numbers.remove(i);46 double d2 =numbers.remove(i);47

48 if (op == ‘*‘) {49 d1 *=d2;50 }else{51 d1 /=d2;52 }53

54 //把运算结果放入数字容器中i的位置

55 numbers.add(i, d1);//原来i位置(包括)后面的数据依次往后顺移

56 i--;57 }58 }59 //5.后加减

60 while (!ops.isEmpty() ) {61 char op = ops.remove(0);62 double d1 = numbers.remove(0);63 double d2 = numbers.remove(0);64 //运算

65 if (op == ‘+‘) {66 d1 +=d2;67 } else{68 d1 -=d2;69 }70 //把运算结果插入到数字容器中0的位置

71 numbers.add(0, d1);72 }73 //6.容器中的第一个数据就是结果

74 return numbers.get(0);75 }76

77 /**

78 * 从表达式中分离表达式和运算符79 *@paramexp80 *@return

81 */

82 private static ListsplitOpfromExp(String exp) {83 List ops = new ArrayList();84 StringTokenizer st = new StringTokenizer(exp, "[email protected]");85 while(st.hasMoreTokens()) {86 char c = st.nextElement().toString().trim().charAt(0);87 ops.add(c);88 }89 returnops;90 }91

92 /**

93 * 分离出数字94 *@paramexp95 *@return

96 */

97 private static ListsplitNumExp(String exp) {98 List numbers = new ArrayList();99 StringTokenizer st = new StringTokenizer(exp, "+-*/");100 while(st.hasMoreTokens()) {101 String numStr =st.nextElement().toString().trim();102 if (numStr.charAt(0) == ‘@‘) {103 numStr = "-" + numStr.substring(1);104 }105 numbers.add(Double.parseDouble(numStr));106 }107 returnnumbers;108 }109

110 /**

111 * 把-号换成@号112 *@paramexp113 *@return

114 */

115 private staticString negativeToAtChar(String exp) {116 for (int i = 0; i < exp.length(); i++) {117 char c =exp.charAt(i);118 if (c == ‘-‘) {119 //判断是否是负数

120 if (i == 0) {121 //第一个位置肯定是负数

122 exp = "@"+exp.substring(1);123 }else{124 //不是第一个位置125 //判断前一个位置是否是运算符

126 char cprev = exp.charAt(i - 1);127 if (cprev == ‘+‘ || cprev == ‘-‘ || cprev == ‘*‘ || cprev == ‘/‘) {128 exp = exp.substring(0, i)+"@"+exp.substring(i+1);129 }130 }131 }132 }133 returnexp;134 }135

136 }

20180111005536988810.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值