130242014074+林泽民+第2次实验

Posted smirk小泽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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  编译器模型示意图

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

四、实验步骤:

 代码如下:

  1. import java.util.ArrayList;    
  2. import java.util.LinkedList;  
  3. import java.util.Scanner;    
  4.     
  5. /**   
  6.  * @author 林泽民   
  7.  * 实现“四则运算”的简易翻译器。 
  8.  */    
  9. public class Calculator {    
  10.          
  11.      private static boolean rightFormat = true;    
  12.       
  13.      public static double getResult(String formula){      
  14.            
  15.         //处理空格  
  16.          formula=formula.replaceAll(" ", "");  
  17.            
  18.         double returnValue = 0;      
  19.          returnValue = doAnalysis(formula);      
  20.        
  21.          if(!rightFormat){      
  22.             throw new NumberFormatException();  
  23.          }     
  24.          return returnValue;     
  25.      }    
  26.       
  27.      //解析字符串函数  
  28.      private static double doAnalysis(String formula){    
  29.          double returnValue = 0;      
  30.          LinkedList<Integer> stack = new LinkedList<Integer>();      
  31.         int curPos = 0;      
  32.         String beforePart = "";     
  33.         String afterPart = "";      
  34.          String calculator = "";     
  35.          rightFormat = true;    
  36.         //取得括号  
  37.         while(rightFormat&&(formula.indexOf(\'(\') >= 0||formula.indexOf(\')\') >= 0)){             
  38.              curPos = 0;      
  39.             for(char s : formula.toCharArray()){       
  40.                  if(s == \'(\'){         
  41.                     stack.add(curPos);       
  42.                  }else if(s == \')\'){         
  43.                     if(stack.size() > 0){         
  44.                          beforePart = formula.substring(0, stack.getLast());         
  45.                          afterPart = formula.substring(curPos + 1);         
  46.                         calculator = formula.substring(stack.getLast() + 1, curPos);          
  47.                          formula = beforePart + doCalculation(calculator) + afterPart;         
  48.                         stack.clear();         
  49.                         break;         
  50.                      }else{          
  51.                          System.out.println("有未关闭的右括号!");         
  52.                          rightFormat = false;         
  53.                      }       
  54.                 }        
  55.                  curPos++;       
  56.              }       
  57.              if(stack.size() > 0){        
  58.                  System.out.println("有未关闭的左括号!");       
  59.                  break;       
  60.              }     
  61.          }      
  62.         if(rightFormat){      
  63.              returnValue = doCalculation(formula);     
  64.         }      
  65.          return returnValue;     
  66.     }    
  67.          
  68.      //四则运算函数  
  69.      private static double doCalculation(String formula) {      
  70.          ArrayList<Double> values = new ArrayList<Double>();      
  71.          ArrayList<String> operators = new ArrayList<String>();     
  72.          int curPos = 0;     
  73.          int prePos = 0;    
  74.          int minus = 0;          
  75.          for (char s : formula.toCharArray()) {     
  76.               if ((s == \'+\' || s == \'-\' || s == \'*\' || s == \'/\') && minus !=0 && minus !=2) {         
  77.                  //将数字分离出来放在double类型里面  
  78.                  values.add(Double.parseDouble(formula.substring(prePos, curPos).trim()));                      
  79.                   operators.add("" + s);                     
  80.                   prePos = curPos + 1;                    
  81.                   minus = minus +1;    
  82.               }else{                  
  83.                   minus =1;                  
  84.               }    
  85.               curPos++;          
  86.         }      
  87.          //去掉前后空格  
  88.          values.add(Double.parseDouble(formula.substring(prePos).trim()));     
  89.          char op;      
  90.          //下面是从容器中取出数字进行运算  
  91.         for (curPos = 0; curPos <= operators.size() - 1; curPos++) {                             
  92.              op = operators.get(curPos).charAt(0);       
  93.             switch (op) {      
  94.              case \'*\':        
  95.                  values.add(curPos, values.get(curPos) * values.get(curPos + 1));       
  96.                  values.remove(curPos + 1);        
  97.                  values.remove(curPos + 1);       
  98.                 operators.remove(curPos);      
  99.                  curPos = -1;    
  100.                 break;       
  101.             case \'/\':       
  102.                 values.add(curPos, values.get(curPos) / values.get(curPos + 1));        
  103.                 values.remove(curPos + 1);        
  104.                 values.remove(curPos + 1);        
  105.                 operators.remove(curPos);      
  106.                 curPos = -1;    
  107.                 break;       
  108.             }      
  109.         }      
  110.         for (curPos = 0; curPos <= operators.size() - 1; curPos++) {       
  111.             op = operators.get(curPos).charAt(0);      
  112.             switch (op) {      
  113.             case \'+\':        
  114.                 values.add(curPos, values.get(curPos) + values.get(curPos + 1));        
  115.                 values.remove(curPos + 1);        
  116.                 values.remove(curPos + 1);       
  117.                 operators.remove(curPos);      
  118.                 curPos = -1;    
  119.                 break;     
  120.             case \'-\':        
  121.                 values.add(curPos, values.get(curPos) - values.get(curPos + 1));       
  122.                 values.remove(curPos + 1);     
  123.                 values.remove(curPos + 1);       
  124.                 operators.remove(curPos);      
  125.                 curPos = -1;    
  126.                 break;      
  127.             }     
  128.         }      
  129.         return values.get(0).doubleValue();    
  130.     }    
  131.       
  132.     //主函数  
  133.     public static void main(String[] args) {         
  134.           
  135.         String str;  
  136.         Scanner scan = new Scanner(System.in);  
  137.             
  138.         while (true){  
  139.               
  140.             System.out.print("calc > ");    
  141.             str=scan.nextLine();  
  142.             try{      
  143.                 System.out.println(getResult(str));      
  144.             }catch(NumberFormatException exc){      
  145.                 System.out.println("格式输入有误,请重新输入!");    
  146.             }  
  147.               
  148.         }  
  149.           
  150.     }    
  151.         
  152. }    

 

结果如下:

 

 

对应结构图:

 

 

以上是关于130242014074+林泽民+第2次实验的主要内容,如果未能解决你的问题,请参考以下文章

130242014074 林泽民 实验一

130242014074 林泽民 《电商系统某功能模块》的需求分析与设计

155242012068+林汉民+第2次试验

155242012068-林汉民-实验一

第四次实验报告:使用Packet Tracer理解RIP路由协议

05林信任快捷方式