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、尝试实现自增和自减符号,例如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));

}

}

}

 

posted @ 2017-10-28 22:47  Nathan刘鑫  阅读(245)  评论(0编辑  收藏  举报