130242014074+林澤民+第2次實驗

軟件體系結構的第二次實驗(解釋器風格與管道過濾器風格)java

1、實驗目的函數

  1.熟悉體系結構的風格的概念翻譯

  2.理解和應用管道過濾器型的風格。3d

  三、理解解釋器的原理orm

  四、理解編譯器模型blog

2、實驗環境ip

  硬件: rem

  軟件:Python或任何一種本身喜歡的語言字符串

3、實驗內容get

  一、實現「四則運算」的簡易翻譯器。

  結果要求:

    1)實現加減乘除四則運算,容許同時又多個操做數,如:2+3*5-6 結果是11

    2)被操做數爲整數,整數能夠有多位

    3)處理空格

    4)輸入錯誤顯示錯誤提示,並返回命令狀態「CALC」

     

 

      圖1    實驗結果示例

  增強練習:

    一、有能力的同窗,能夠嘗試實現賦值語句,例如x=2+3*5-6,返回x=11。(注意:要實現解釋器的功能,而不是隻是顯示)

    二、嘗試實現自增和自減符號,例如x++ 

    三、採用管道-過濾器(Pipes and Filters)風格實現解釋器

 

 

 

 

                        圖2  管道-過濾器風格

 

 

 

                       圖 3  編譯器模型示意圖

  本實驗,實現的是詞法分析和語法分析兩個部分。

4、實驗步驟:

 代碼以下:

  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. }    

 

結果以下:

 

 

對應結構圖:

相關文章
相關標籤/搜索