1. 程式人生 > >130242014030-陳文升-第二次實驗

130242014030-陳文升-第二次實驗

自增 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-陳文升-第二次實驗