130242014074+林泽民+第2次实验
软件体系结构的第二次实验(解释器风格与管道过滤器风格)
一、实验目的
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++
3、采用管道-过滤器(Pipes and Filters)风格实现解释器
 
图2 管道-过滤器风格
 
图 3 编译器模型示意图
本实验,实现的是词法分析和语法分析两个部分。
四、实验步骤:
代码如下:
- import java.util.ArrayList;
 - import java.util.LinkedList;
 - import java.util.Scanner;
 - /**
 - * @author 林泽民
 - * 实现“四则运算”的简易翻译器。
 - */
 - public class Calculator {
 - private static boolean rightFormat = true;
 - public static double getResult(String formula){
 - //处理空格
 - formula=formula.replaceAll(" ", "");
 - double returnValue = 0;
 - returnValue = doAnalysis(formula);
 - if(!rightFormat){
 - throw new NumberFormatException();
 - }
 - return returnValue;
 - }
 - //解析字符串函数
 - private static double doAnalysis(String formula){
 - double returnValue = 0;
 - LinkedList<Integer> stack = new LinkedList<Integer>();
 - int curPos = 0;
 - String beforePart = "";
 - String afterPart = "";
 - String calculator = "";
 - rightFormat = true;
 - //取得括号
 - while(rightFormat&&(formula.indexOf('(') >= 0||formula.indexOf(')') >= 0)){
 - curPos = 0;
 - for(char s : formula.toCharArray()){
 - if(s == '('){
 - stack.add(curPos);
 - }else if(s == ')'){
 - if(stack.size() > 0){
 - beforePart = formula.substring(0, stack.getLast());
 - afterPart = formula.substring(curPos + 1);
 - calculator = formula.substring(stack.getLast() + 1, curPos);
 - formula = beforePart + doCalculation(calculator) + afterPart;
 - stack.clear();
 - break;
 - }else{
 - System.out.println("有未关闭的右括号!");
 - rightFormat = false;
 - }
 - }
 - curPos++;
 - }
 - if(stack.size() > 0){
 - System.out.println("有未关闭的左括号!");
 - break;
 - }
 - }
 - if(rightFormat){
 - returnValue = doCalculation(formula);
 - }
 - return returnValue;
 - }
 - //四则运算函数
 - private static double doCalculation(String formula) {
 - ArrayList<Double> values = new ArrayList<Double>();
 - ArrayList<String> operators = new ArrayList<String>();
 - int curPos = 0;
 - int prePos = 0;
 - int minus = 0;
 - for (char s : formula.toCharArray()) {
 - if ((s == '+' || s == '-' || s == '*' || s == '/') && minus !=0 && minus !=2) {
 - //将数字分离出来放在double类型里面
 - values.add(Double.parseDouble(formula.substring(prePos, curPos).trim()));
 - operators.add("" + s);
 - prePos = curPos + 1;
 - minus = minus +1;
 - }else{
 - minus =1;
 - }
 - curPos++;
 - }
 - //去掉前后空格
 - values.add(Double.parseDouble(formula.substring(prePos).trim()));
 - char op;
 - //下面是从容器中取出数字进行运算
 - for (curPos = 0; curPos <= operators.size() - 1; curPos++) {
 - op = operators.get(curPos).charAt(0);
 - switch (op) {
 - case '*':
 - values.add(curPos, values.get(curPos) * values.get(curPos + 1));
 - values.remove(curPos + 1);
 - values.remove(curPos + 1);
 - operators.remove(curPos);
 - curPos = -1;
 - break;
 - case '/':
 - values.add(curPos, values.get(curPos) / values.get(curPos + 1));
 - values.remove(curPos + 1);
 - values.remove(curPos + 1);
 - operators.remove(curPos);
 - curPos = -1;
 - break;
 - }
 - }
 - for (curPos = 0; curPos <= operators.size() - 1; curPos++) {
 - op = operators.get(curPos).charAt(0);
 - switch (op) {
 - case '+':
 - values.add(curPos, values.get(curPos) + values.get(curPos + 1));
 - values.remove(curPos + 1);
 - values.remove(curPos + 1);
 - operators.remove(curPos);
 - curPos = -1;
 - break;
 - case '-':
 - values.add(curPos, values.get(curPos) - values.get(curPos + 1));
 - values.remove(curPos + 1);
 - values.remove(curPos + 1);
 - operators.remove(curPos);
 - curPos = -1;
 - break;
 - }
 - }
 - return values.get(0).doubleValue();
 - }
 - //主函数
 - public static void main(String[] args) {
 - String str;
 - Scanner scan = new Scanner(System.in);
 - while (true){
 - System.out.print("calc > ");
 - str=scan.nextLine();
 - try{
 - System.out.println(getResult(str));
 - }catch(NumberFormatException exc){
 - System.out.println("格式输入有误,请重新输入!");
 - }
 - }
 - }
 - }
 
结果如下:
 
对应结构图:

                    
                
                
            
        
浙公网安备 33010602011771号