码迷,mamicode.com
首页 > 其他好文 > 详细

软件体系结构的第二次实验(解释器风格与管道过滤器风格

时间:2017-10-28 21:11:41      阅读:291      评论:0      收藏:0      [点我收藏+]

标签:运算   turn   private   目的   es2017   9.png   map   翻译   返回   

一、实验目的

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.*;

public class Test {

        public static void main(String[] args) {
            while(true){
                Scanner scanner = new Scanner(System.in);
                System.out.print("calc > ");
                String text = scanner.nextLine();
                if (analyzer(text))
                    System.out.println(calculate(toSuffix(text)));
                else
                    System.out.println("输入有误,请重新输入!!");
            }

        }

        //验证是否有空格
        static List<Object> toSuffix(String s) {
            Map<String, Integer> map = new HashMap<String, Integer>();
            map.put("+", 0);
            map.put("-", 0);
            map.put("*", 1);
            map.put("/", 1);
            List<Object> list = new ArrayList<Object>();
            s = s.replace(" ", "");
            String[] number = s.split("[^\\d]");
            String[] operator = s.split("\\d+");
            Stack<String> stack = new Stack<String>();
            for (int i = 0; i < number.length; i++) {
                if (operator[i].length() != 0) {
                    while (!stack.isEmpty()
                            && map.get(operator[i]) <= map.get(stack.peek())) {
                        list.add(stack.pop());
                    }
                    stack.push(operator[i]);
                }
                list.add(Double.parseDouble(number[i]));
            }
            while (!stack.isEmpty()) {
                list.add(stack.pop());
            }
            return list;
        }

        //计算
        static double calculate(List<Object> list) {
            Stack<Double> stack = new Stack<Double>();
            for (Object obj : list) {
                if (obj instanceof Double) {
                    stack.push((Double) obj);
                } else {
                    double b = stack.pop();
                    double a = stack.pop();
                    if (obj.equals("+"))
                        stack.push(a + b);
                    if (obj.equals("-"))
                        stack.push(a - b);
                    if (obj.equals("*"))
                        stack.push(a * b);
                    if (obj.equals("/"))
                        stack.push(a / b);
                }
            }
            return stack.pop();
        }

        private static boolean analyzer(String text) {

            String[] signs = {"+", "-", "*", "/"};
            boolean isRight = true;
            //语法分析
            boolean haveSign = false;
            for (String sign : signs) {
                //是否包含运算符
                if (text.contains(sign)) {
                    haveSign = true;
                }
                //是否有连续的运算符
                if (text.contains(sign + sign)) {
                    isRight = false;
                }
                //首尾是否为运算符
                if ( text.indexOf(sign) == 0 || text.lastIndexOf(sign) == text.length() - 1) {
                    isRight = false;
                }
            }
            isRight = isRight && haveSign;
            return isRight;
        }
}

 

实验结果 :

 

 

技术分享

 

结构图:

技术分享

软件体系结构的第二次实验(解释器风格与管道过滤器风格

标签:运算   turn   private   目的   es2017   9.png   map   翻译   返回   

原文地址:http://www.cnblogs.com/zhujingru/p/7747898.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!