1. 程式人生 > >130242014039-劉鑫-第2次實驗

130242014039-劉鑫-第2次實驗

pre pri 提示 align part clas alt stat 自己

一、實驗目的

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、嘗試實現自增和自減符號,例如

x++

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次實驗