一、实验目的

1.熟悉体系结构的风格的概念

2.理解和应用管道过滤器型的风格。

3、理解解释器的原理

4、理解编译器模型

二、实验环境

硬件: 

软件:Python或任何一种自己喜欢的语言

三、实验内容

1、实现“四则运算”的简易翻译器。

结果要求:

1)实现加减乘除四则运算,允许同时又多个操作数,如:2+3*5-6 结果是11

2)被操作数为整数,整数可以有多位

3)处理空格

4)输入错误显示错误提示,并返回命令状态“CALC”

四、实验步骤:

     要求写具体实现代码,并根据实际程序,画出程序的总体体系结构图和算法结构图。

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("输入字符串");
        String b = sc.next();
        System.out.println(caculate2(b));

    }

    // 对运算符优先级进一步排序 减法大于加法 除法大于乘法
    public static double caculate2(String formula) {
        String[] arr = convert(formula);
        Stack<Double> val = new Stack<>();
        Stack<String> op = new Stack<>();

        for (int i = 0; i < arr.length; i++) {
            if (arr[i].equals("(")) {
                val.push(caculate2(bracketGet(formula, i)));//递归计算括号内部的值,并将该值入栈
                i = i + bracketGet(formula, i).length() + 1;
            } else if (arr[i].equals("+") || arr[i].equals("-")
                    || arr[i].equals("*") || arr[i].equals("/")) {
                while (!op.isEmpty() && opcompare2(op.lastElement(), arr[i])) {
                    switch (op.pop()) {
                    case "+":
                        val.push(val.pop() + val.pop());
                        continue;
                    case "-":
                        double c = val.pop();
                        double d = val.pop();
                        val.push(d - c);
                        continue;
                    case "*":
                        val.push(val.pop() * val.pop());
                        continue;
                    case "/":
                        double a = val.pop();
                        double b = val.pop();
                        val.push(b / a);
                        continue;
                    default:
                        break;
                    }
                }
                op.push(arr[i]);
            } else
                val.push(Double.parseDouble(arr[i]));

        }
        while (!op.isEmpty()) {
            switch (op.pop()) {
            case "+":
                val.push(val.pop() + val.pop());
                break;
            case "-":
                double c = val.pop();
                double d = val.pop();
                val.push(d - c);
                break;
            case "*":
                val.push(val.pop() * val.pop());
                break;
            case "/":
                double a = val.pop();
                double b = val.pop();
                val.push(b / a);
                break;
            default:
                break;
            }
        }

        return val.pop();
    }
    /**
     * 获取括号内的字符串
     * @param s
     * @param k  从k位置开始获取第一个带完整的括号的子字符串
     * @return
     */
    public static String bracketGet(String s, int k) {
        int m = 0;
        int i;
        String[] arr = convert(s);
        for (i = k; i < arr.length; i++) {
            if (arr[i].equals("(")) {
                m++;
                continue;
            }
            if (arr[i].equals(")")) {
                m--;
                if (m == 0)
                    break;
                else
                    continue;
            }

        }
        StringBuilder sb = new StringBuilder();
        for (int j = k + 1; j < i; j++) {
            sb.append(arr[j]);
        }
        return sb.toString();
    }
    /**
     * 实现字符串表达式转化为字符串数组,要求输入的字符串中间没有空格。
     * @param s
     * @return
     */
    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()]);

    }
    /**
     * 判断是否为运算符
     * @param c
     * @return
     */
    public static boolean opjudge(char c) {
        if (c == '+' || c == '-' || c == '*' || c == '/' || c == '('
                || c == ')')
            return true;
        else
            return false;
    }
    /**
     * 字符串的优先级,依次是除法 乘法 减法 加法 依次降低,遍历到运算符时,优先级高才入栈
     * @param s
     * @return
     */
    public static int opvalue2(String s) {
        switch (s) {
        case "+":
            return 1;
        case "-":
            return 2;
        case "*":
            return 3;
        case "/":
            return 4;
        default:
            return -1;
        }

    }
    /**
     * 运算符优先级比较
     * @param s1
     * @param s2
     * @return
     */
    public static boolean opcompare2(String s1, String s2) {
        if (opvalue2(s1) >= opvalue2(s2))
            return true;
        else {
            return false;
        }

    }
}

五、实验总结

  逐步的,渐渐地更加清晰的懂得了体系结构的作用,能使得一个程序更加严谨,有条理。

posted on 2017-10-25 19:50  以为你还好  阅读(197)  评论(1编辑  收藏  举报