一、实验目的
1.熟悉体系结构的风格的概念
2.理解和应用管道过滤器型的风格。
3、理解解释器的原理
4、理解编译器模型
二、实验环境
硬件:
软件:Python或任何一种自己喜欢的语言
三、实验内容
1、实现“四则运算”的简易翻译器。
结果要求:
1)实现加减乘除四则运算,允许同时又多个操作数,如:2+3*5-6 结果是11
2)被操作数为整数,整数可以有多位
3)处理空格
4)输入错误显示错误提示,并返回命令状态“CALC”
图1 实验结果示例
加强练习:
1、有能力的同学,可以尝试实现赋值语句,例如x=2+3*5-6,返回x=11。(注意:要实现解释器的功能,而不是只是显示)
2、尝试实现自增和自减符号,例如x++
2、采用管道-过滤器(Pipes and Filters)风格实现解释器
图2 管道-过滤器风格
图 3 编译器模型示意图
本实验,实现的是词法分析和语法分析两个部分。
四、实验步骤:
要求写具体实现代码,并根据实际程序,画出程序的总体体系结构图和算法结构图。
1 public class Operate { 2 private StackpriStack = new Stack ();// 操作符栈 3 private Stack numStack = new Stack ();// 操作数栈 4 5 public int caculate(String str) { 6 String temp; 7 StringBuffer tempNum = new StringBuffer(); 8 // 处理空格 9 StringBuffer string = new StringBuffer().append(str.replace(" ", "")); 10 11 while (string.length() != 0) { 12 temp = string.substring(0, 1); 13 string.delete(0, 1); 14 if (!isNum(temp)) { 15 if (!"".equals(tempNum.toString())) { 16 int num = Integer.parseInt(tempNum.toString()); 17 numStack.push(num); 18 tempNum.delete(0, tempNum.length()); 19 } 20 while (!compare(temp.charAt(0)) && (!priStack.empty())) { 21 int a = (int) numStack.pop();// 第二个运算数 22 int b = (int) numStack.pop();// 第一个运算数 23 char ope = priStack.pop(); 24 int result = 0;// 运算结果 25 switch (ope) { 26 // 如果是加号或者减号,则 27 case '+': 28 result = b + a; 29 // 将操作结果放入操作数栈 30 numStack.push(result); 31 break; 32 case '-': 33 result = b - a; 34 // 将操作结果放入操作数栈 35 numStack.push(result); 36 break; 37 case '*': 38 result = b * a; 39 // 将操作结果放入操作数栈 40 numStack.push(result); 41 break; 42 case '/': 43 result = b / a;// 将操作结果放入操作数栈 44 numStack.push(result); 45 break; 46 } 47 48 } 49 // 判断当前运算符与栈顶元素优先级 50 if (temp.charAt(0) != '#') { 51 priStack.push(new Character(temp.charAt(0))); 52 if (temp.charAt(0) == ')') { 53 priStack.pop(); 54 priStack.pop(); 55 } 56 } 57 } else 58 // 当为数字 59 tempNum = tempNum.append(temp); 60 } 61 return numStack.pop(); 62 } 63 64 private boolean isNum(String temp) { 65 return temp.matches("[0-9]"); 66 } 67 68 private boolean compare(char str) { 69 if (priStack.empty()) { 70 // 当为空时,显然 当前优先级最低,返回高 71 return true; 72 } 73 char last = (char) priStack.lastElement(); 74 // 如果栈顶为'('显然,优先级最低,')'不可能为栈顶。 75 if (last == '(') { 76 return true; 77 } 78 switch (str) { 79 case '#': 80 return false;// 结束符 81 case '(': 82 // '('优先级最高,显然返回true 83 return true; 84 case ')': 85 // ')'优先级最低, 86 return false; 87 case '*': { 88 // '*/'优先级只比'+-'高 89 if (last == '+' || last == '-') 90 return true; 91 else 92 return false; 93 } 94 case '/': { 95 if (last == '+' || last == '-') 96 return true; 97 else 98 return false; 99 }100 // '+-'为最低,一直返回false101 case '+':102 return false;103 case '-':104 return false;105 }106 return true;107 }108 109 public static void main(String args[]) {110 Operate operate = new Operate();111 Scanner scanner = new Scanner(System.in);112 String calstr;113 while (true) {114 System.out.print("calc > ");115 calstr = scanner.nextLine();116 try {117 int t = operate.caculate(calstr + "#");118 System.out.println(t);119 } catch (Exception e) {120 System.out.println("Error!");121 }122 }123 }124 }