1、實驗目的java
1.熟悉體系結構的風格的概念ui
2.理解和應用管道過濾器型的風格。翻譯
三、理解解釋器的原理blog
四、理解編譯器模型ip
2、實驗環境編譯器
硬件: string
軟件:Python或任何一種本身喜歡的語言it
3、實驗內容編譯
一、實現「四則運算」的簡易翻譯器。ast
結果要求:
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、實驗步驟:
代碼以下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class calc {
private static String[] SIGNS = {"+", "-", "*", "/"};
private static Character[] STANDARD_CHAT = {'+', '-', '*', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' '};
private static List<Character> STANDARD_LIST = new ArrayList<Character>(Arrays.asList(STANDARD_CHAT));
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String expr = scanner.nextLine();
while (!expr.contains("quit")) {
//詞法+語法分析
if (analyzer(expr)) {
System.out.println(calculator(expr));
} else {
System.out.println("表達式輸入錯誤");
}
expr = scanner.nextLine();
}
}
private static Double calculator(String expr) {
//去空格
expr = expr.replace(" ","");
for (String sign : SIGNS) {
Integer index;
if ("-".equals(sign)) {
index = expr.lastIndexOf(sign);
} else {
index = expr.indexOf(sign);
}
if (index == -1) {
continue;
}
String firstHalf = expr.substring(0, index);
String secondHalf = expr.substring(index + 1, expr.length());
switch (sign) {
case "+":
return calculator(firstHalf) + calculator(secondHalf);
case "-":
return calculator(firstHalf) - calculator(secondHalf);
case "*":
return calculator(firstHalf) * calculator(secondHalf);
case "/":
return calculator(firstHalf) / calculator(secondHalf);
}
}
return Double.valueOf(expr);
}
private static boolean analyzer(String expr) {
boolean isRight = true;
for (int i = 0; i < expr.length(); i++) {
if (!STANDARD_LIST.contains(expr.charAt(i))) {
isRight = false;
break;
}
}
//語法分析
boolean haveSign = false;
for (String sign : SIGNS) {
if (expr.contains(sign)) {
haveSign = true;
}
if (expr.contains(sign + sign)) {
isRight = false;
}
if ( expr.indexOf(sign) == 0 || expr.lastIndexOf(sign) == expr.length() - 1) {
isRight = false;
}
}
isRight = isRight && haveSign;
return isRight;
}
}