130242014030-陳文升-第二次實驗
阿新 • • 發佈:2017-10-29
自增 als ann 自己 1-1 註意 filters char else
一、實驗目的
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 編譯器模型示意圖
本實驗,實現的是詞法分析和語法分析兩個部分。
import java.util.ArrayList; import java.util.Scanner; import java.util.Stack; public class gg { public static void main(String[] args) { while(true){ System.out.print("calc>"); //輸入 Scanner in = new Scanner(System.in); String SR = in.nextLine(); //輸出 try { Double t = calculate(SR); System.out.println(t); } catch (Exception e) { System.out.println("您輸入的表達式有誤!"); } } } //計算 public static double calculate(String SR) { //轉換數組 String[] arr = convert(SR); //操作數棧 Stack<Double> S = new Stack<>(); //操作符棧 Stack<String> F = new Stack<>(); //遍歷表數組 for (int i = 0; i < arr.length; i++) { if (arr[i].equals("+") || arr[i].equals("-") || arr[i].equals("*") || arr[i].equals("/")) { while (!F.isEmpty() && opcompare(F.lastElement(), arr[i])) { switch (F.pop()) { case "+": S.push(S.pop() + S.pop()); continue; case "-": double c = S.pop(); double d = S.pop(); S.push(d - c); continue; case "*": S.push(S.pop() * S.pop()); continue; case "/": double a = S.pop(); double b = S.pop(); S.push(b / a); continue; default: break; } } F.push(arr[i]); } else S.push(Double.parseDouble(arr[i])); } while (!F.isEmpty()) { switch (F.pop()) { case "+": S.push(S.pop() + S.pop()); continue; case "-": double c = S.pop(); double d = S.pop(); S.push(d - c); continue; case "*": S.push(S.pop() * S.pop()); continue; case "/": double a = S.pop(); double b = S.pop(); S.push(b / a); continue; default: break; } } return S.pop(); } //轉換函數 public static String[] convert(String s) { ArrayList<String> arrayList = new ArrayList<>(); for (int i = 0; i < s.length(); i++) { if (!opjudge(s.charAt(i))) { int j = i; while ((i < s.length()) && !opjudge(s.charAt(i))) i++; arrayList.add(s.substring(j, i)); i--; } else arrayList.add(String.valueOf(s.charAt(i))); } return arrayList.toArray(new String[arrayList.size()]); } //操作判斷 public static boolean opjudge(char c) { if (c == ‘+‘ || c == ‘-‘ || c == ‘*‘ || c == ‘/‘) return true; else return false; } //操作符賦值 public static int opvalue(String s) { switch (s) { case "+": return 1; case "-": return 2; case "*": return 3; case "/": return 4; default: return -1; } } //操作優先級符比較 public static boolean opcompare(String s1, String s2) { if (opvalue(s1) >= opvalue(s2)) return true; else { return false; } } }
130242014030-陳文升-第二次實驗