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

130242014076+陈旭+第2次实验

时间:2017-10-27 21:30:15      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:png   double   log   实验   string   author   符号   ges   create   

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

一、实验目的

  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++ 

    3、采用管道-过滤器(Pipes and Filters)风格实现解释器

技术分享

 

                        图2  管道-过滤器风格

 技术分享

 

                     图 3  编译器模型示意图

  本实验,实现的是词法分析和语法分析两个部分。

四、实验步骤:

 代码如下:

  1 package com.brainstrong.uamis.util;
  2 
  3 import java.io.InputStream;
  4 import java.util.ArrayList;
  5 import java.util.List;
  6 import java.util.Scanner;
  7 import java.util.StringTokenizer;
  8 
  9 /**
 10  * JAVA实现四则运算解释器
 11  *
 12  * @author 旭旭
 13  * @create 2017-10-27 19:43
 14  **/
 15 public class Calc {
 16 
 17     public static void main(String[] args) {
 18         Scanner scanner = new Scanner(System.in);
 19         String exp = scanner.nextLine();
 20         System.out.println(calc(exp));
 21     }
 22 
 23     /**
 24      *
 25      * @param exp 四则表达式
 26      * @return
 27      */
 28     public static double calc(String exp){
 29         //1.把表示负数的-号换成@号
 30         exp = negativeToAtChar(exp);
 31         //2.数字的分类
 32         List<Double> numbers = splitNumExp(exp);
 33         //3.运算符的分离
 34         List<Character> ops = splitOpfromExp(exp);
 35         //4.先乘除
 36         for (int i = 0; i < ops.size(); i++) {
 37             //判断,运算符是否是乘除
 38             char op = ops.get(i);
 39             //是,取出,运算
 40             if (op == ‘*‘ || op == ‘/‘) {
 41                 //取出来,运算
 42                 ops.remove(i);//后面的数据往前顺序移动
 43                 //运算
 44                 //从数字容器中取出对应运算符的两个数字
 45                 double d1 = numbers.remove(i);
 46                 double d2 = numbers.remove(i);
 47 
 48                 if (op == ‘*‘) {
 49                     d1 *= d2;
 50                 }else {
 51                     d1 /= d2;
 52                 }
 53 
 54                 //把运算结果放入数字容器中i的位置
 55                 numbers.add(i, d1);//原来i位置(包括)后面的数据依次往后顺移
 56                 i--;
 57             }
 58         }
 59         //5.后加减
 60         while (!ops.isEmpty() ) {
 61             char op = ops.remove(0);
 62             double d1 = numbers.remove(0);
 63             double d2 = numbers.remove(0);
 64             //运算
 65             if (op == ‘+‘) {
 66                 d1 += d2;
 67             } else {
 68                 d1 -= d2;
 69             }
 70             //把运算结果插入到数字容器中0的位置
 71             numbers.add(0, d1);
 72         }
 73         //6.容器中的第一个数据就是结果
 74         return numbers.get(0);
 75     }
 76 
 77     /**
 78      * 从表达式中分离表达式和运算符
 79      * @param exp
 80      * @return
 81      */
 82     private static List<Character> splitOpfromExp(String exp) {
 83         List<Character> ops = new ArrayList<Character>();
 84         StringTokenizer st = new StringTokenizer(exp, "1234567890.@");
 85         while (st.hasMoreTokens()) {
 86             char c = st.nextElement().toString().trim().charAt(0);
 87             ops.add(c);
 88         }
 89         return ops;
 90     }
 91 
 92     /**
 93      * 分离出数字
 94      * @param exp
 95      * @return
 96      */
 97     private static List<Double> splitNumExp(String exp) {
 98         List<Double> numbers = new ArrayList<Double>();
 99         StringTokenizer st = new StringTokenizer(exp, "+-*/");
100         while (st.hasMoreTokens()) {
101             String numStr = st.nextElement().toString().trim();
102             if (numStr.charAt(0) == ‘@‘) {
103                 numStr = "-" + numStr.substring(1);
104             }
105             numbers.add(Double.parseDouble(numStr));
106         }
107         return numbers;
108     }
109 
110     /**
111      * 把-号换成@号
112      * @param exp
113      * @return
114      */
115     private static String negativeToAtChar(String exp) {
116         for (int i = 0; i < exp.length(); i++) {
117             char c = exp.charAt(i);
118             if (c == ‘-‘) {
119                 //判断是否是负数
120                 if (i == 0) {
121                     //第一个位置肯定是负数
122                     exp = "@"+exp.substring(1);
123                 }else {
124                     //不是第一个位置
125                     //判断前一个位置是否是运算符
126                     char cprev = exp.charAt(i - 1);
127                     if (cprev == ‘+‘ || cprev == ‘-‘ || cprev == ‘*‘ || cprev == ‘/‘) {
128                         exp = exp.substring(0, i)+"@"+exp.substring(i+1);
129                     }
130                 }
131             }
132         }
133         return exp;
134     }
135 
136 }

技术分享

 

130242014076+陈旭+第2次实验

标签:png   double   log   实验   string   author   符号   ges   create   

原文地址:http://www.cnblogs.com/softcx/p/7745060.html

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