1、實驗目的java
1.熟悉體系結構的風格的概念express
2.理解和應用管道過濾器型的風格。ide
三、理解解釋器的原理翻譯
四、理解編譯器模型3d
2、實驗環境blog
硬件: ip
軟件:Python或任何一種本身喜歡的語言ci
3、實驗內容input
一、實現「四則運算」的簡易翻譯器。編譯器
結果要求:
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、實驗步驟:
代碼以下:
package fjnu.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Arithmetic {
public static void main(String args[]){
//System.out.println(arithmetic("2.2+((3+4)*2-22)/2*3.2"));
//System.out.println(arithmetic("2+333 *5-6"));
/* try {
System.out.println(arithmetic("1+"));
}catch(Error e){
System.out.println("輸入的格式有問題請從新輸入");
}*/
Scanner input=new Scanner(System.in);
while(true){
String entry = null;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
try {
System.out.print("calc > ");
entry = reader.readLine();
if(entry==null ||entry.length()==0)
{
System.out.println("沒有輸入就回車!");
continue;
}
System.out.println(arithmetic(entry));
} catch (Error e) {
System.out.println("輸入的格式和形式是有誤的有問題,從新輸入正確的格式!");
}catch (Exception e) {
System.out.println("輸入的格式和形式是有誤的有問題,從新輸入正確的格式!");
}
}
}
}
public static double arithmetic(String exp){
String result = parseExp(exp).replaceAll("[\\[\\]]", "");
return Double.parseDouble(result);
}
/**
* 解析計算四則運算表達式,例:2+((3+4)*2-22)/2*3
* @param expression
* @return
*/
public static String parseExp(String expression){
//String numberReg="^((?!0)\\d+(\\.\\d+(?<!0))?)|(0\\.\\d+(?<!0))$";
expression=expression.replaceAll("\\s+", "").replaceAll("^\\((.+)\\)$", "$1");
String checkExp="\\d";
String minExp="^((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))[\\+\\-\\*\\/]((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))$";
//最小表達式計算
if(expression.matches(minExp)){
String result=calculate(expression);
return Double.parseDouble(result)>=0?result:"["+result+"]";
}
//計算不帶括號的四則運算
String noParentheses="^[^\\(\\)]+$";
String priorOperatorExp="(((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))[\\*\\/]((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\])))";
String operatorExp="(((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))[\\+\\-]((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\])))";
if(expression.matches(noParentheses)){
Pattern patt=Pattern.compile(priorOperatorExp);
Matcher mat=patt.matcher(expression);
if(mat.find()){
String tempMinExp=mat.group();
expression=expression.replaceFirst(priorOperatorExp, parseExp(tempMinExp));
}else{
patt=Pattern.compile(operatorExp);
mat=patt.matcher(expression);
if(mat.find()){
String tempMinExp=mat.group();
expression=expression.replaceFirst(operatorExp, parseExp(tempMinExp));
}
}
return parseExp(expression);
}
//計算帶括號的四則運算
String minParentheses="\\([^\\(\\)]+\\)";
Pattern patt=Pattern.compile(minParentheses);
Matcher mat=patt.matcher(expression);
if(mat.find()){
String tempMinExp=mat.group();
expression=expression.replaceFirst(minParentheses, parseExp(tempMinExp));
}
return parseExp(expression);
}
/**
* 計算最小單位四則運算表達式(兩個數字)
* @param exp
* @return
*/
public static String calculate(String exp){
exp=exp.replaceAll("[\\[\\]]", "");
String number[]=exp.replaceFirst("(\\d)[\\+\\-\\*\\/]", "$1,").split(",");
BigDecimal number1=new BigDecimal(number[0]);
BigDecimal number2=new BigDecimal(number[1]);
BigDecimal result=null;
String operator=exp.replaceFirst("^.*\\d([\\+\\-\\*\\/]).+$", "$1");
if("+".equals(operator)){
result=number1.add(number2);
}else if("-".equals(operator)){
result=number1.subtract(number2);
}else if("*".equals(operator)){
result=number1.multiply(number2);
}else if("/".equals(operator)){
result=number1.divide(number2);
}
return result!=null?result.toString():null;
}
}