130242014039-劉鑫-第2次實驗
一、實驗目的
1.熟悉體系結構的風格的概念
2.理解和應用管道過濾器型的風格。
3、理解解釋器的原理
4、理解編譯器模型
二、實驗環境
硬件:
軟件:Python或任何一種自己喜歡的語言
三、實驗內容
1、實現“四則運算”的簡易翻譯器。
結果要求:
1)實現加減乘除四則運算,允許同時又多個操作數,如:2+3*5-6 結果是11
2)被操作數為整數,整數可以有多位
3)處理空格
4)輸入錯誤顯示錯誤提示,並返回命令狀態“CALC”
加強練習:
1、有能力的同學,可以嘗試實現賦值語句,例如x=2+3*5-6,返回x=11。(註意:要實現解釋器的功能,而不是只是顯示)
2、嘗試實現自增和自減符號,例如
2、采用管道-過濾器(Pipes and Filters)風格實現解釋器
圖2 管道-過濾器風格
圖 3 編譯器模型示意圖
本實驗,實現的是詞法分析和語法分析兩個部分。
package fjnu.test;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
public class ExpressionToDouble {
private boolean isRightFormat = true;
public double getResult(String formula) {
double returnValue = 0;
try {
returnValue = doAnalysis(formula);
} catch (NumberFormatException nfe) {
System.out.println("公式格式有誤,請檢查:" + formula);
} catch (Exception e) {
e.printStackTrace();
}
if (!isRightFormat) {
System.out.println("公式格式有誤,請檢查:" + formula);
}
return returnValue;
}
private double doAnalysis(String formula) {
double returnValue = 0;
LinkedList<Integer> stack = new LinkedList<Integer>();
int curPos = 0;
String beforePart = "";
String afterPart = "";
String calculator = "";
isRightFormat = true;
while (isRightFormat
&& (formula.indexOf(‘(‘) >= 0 || formula.indexOf(‘)‘) >= 0)) {
curPos = 0;
for (char s : formula.toCharArray()) {
if (s == ‘(‘) {
stack.add(curPos);
} else if (s == ‘)‘) {
if (stack.size() > 0) {
beforePart = formula.substring(0, stack.getLast());
afterPart = formula.substring(curPos + 1);
calculator = formula.substring(stack.getLast() + 1,
curPos);
formula = beforePart + doCalculation(calculator)
+ afterPart;
stack.clear();
break;
} else {
System.out.println("有未關閉的右括號!");
isRightFormat = false;
}
}
curPos++;
}
if (stack.size() > 0) {
System.out.println("有未關閉的左括號!");
break;
}
}
if (isRightFormat) {
returnValue = doCalculation(formula);
}
return returnValue;
}
private double doCalculation(String formula) {
ArrayList<Double> values = new ArrayList<Double>();
ArrayList<String> operators = new ArrayList<String>();
int curPos = 0;
int prePos = 0;
for (char s : formula.toCharArray()) {
if (s == ‘+‘ || s == ‘-‘ || s == ‘*‘ || s == ‘/‘) {
values.add(Double.parseDouble(formula.substring(prePos, curPos)
.trim()));
operators.add("" + s);
prePos = curPos + 1;
}
curPos++;
}
values.add(Double.parseDouble(formula.substring(prePos).trim()));
char op;
for (curPos = operators.size() - 1; curPos >= 0; curPos--) {
op = operators.get(curPos).charAt(0);
switch (op) {
case ‘*‘:
values.add(curPos, values.get(curPos) * values.get(curPos + 1));
values.remove(curPos + 1);
values.remove(curPos + 1);
operators.remove(curPos);
break;
case ‘/‘:
values.add(curPos, values.get(curPos) / values.get(curPos + 1));
values.remove(curPos + 1);
values.remove(curPos + 1);
operators.remove(curPos);
break;
}
}
for (curPos = operators.size() - 1; curPos >= 0; curPos--) {
op = operators.get(curPos).charAt(0);
switch (op) {
case ‘+‘:
values.add(curPos, values.get(curPos) + values.get(curPos + 1));
values.remove(curPos + 1);
values.remove(curPos + 1);
operators.remove(curPos);
break;
case ‘-‘:
values.add(curPos, values.get(curPos) - values.get(curPos + 1));
values.remove(curPos + 1);
values.remove(curPos + 1);
operators.remove(curPos);
break;
}
}
return values.get(0).doubleValue();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str;
while (true) {
System.out.print("calc > ");
str = scanner.nextLine();
System.out.println(new ExpressionToDouble().getResult(str));
}
}
}
130242014039-劉鑫-第2次實驗