130242014056 王钰鹏 第2次实验

一、实验目的

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

/**
 * Created by hasee on 2017/10/28.
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while(true){
            System.out.print("calc > ");
            String text = scanner.nextLine();
            if (interpreter(text))
                System.out.println(calculate(lexer(text)));
            else
                System.out.println("输入有误,请重新输入!!");
        }

    }

    /*
    去除空字符串并将插入到队列中
     */
    public static List<Object> lexer(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;
    }

    /**
     * 計算
     * @param list
     * @return
     */
    public 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();
    }

    /**
     * 语法分析
     * @param text
     * @return
     */
    private static boolean interpreter(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;
    }
}

 

 

转载于:https://www.cnblogs.com/wsat/p/7747937.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值