一、实验目的
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;
}
}
}