代码改变世界

130242014036+高忠杰+第二次实验

2017-10-28 15:54  零凌临  阅读(301)  评论(0编辑  收藏  举报

 

一、实验目的

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  编译器模型示意图

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

四、实验步骤:

代码:

 

 

  1 <template>
  2   <div class="hello">
  3     <p class="text">请输入运算式,按运算开始运算(不用输入等于号,请输入英文字符的括号!)</p>
  4     <div class="question">
  5       <input type="text" v-model="input" placeholder="在此输入表达式">
  6       <input type="button" value="开始运算" @click="run">
  7       <input type="button" value="清空" @click="clear">
  8     </div>
  9     <div v-if="input==''" class="answer">在此显示答案</div>
 10     <div v-else class="answer">{{input}}{{result}}</div>
 11   </div>
 12 </template>
 13 
 14 <script>
 15 export default {
 16   name: 'HelloWorld',
 17   data () {
 18     return {
 19       msg: '',
 20       input:'',
 21       result:''
 22     }
 23   },
 24   methods:{
 25     run(input){
 26       function isOperator(value){    //判断是否为运算符
 27         var operatorString = "+-*/()";
 28         return operatorString.indexOf(value) > -1
 29       }
 30       function getPrioraty(value){   //判断运算符类型:1 为加减,2 为乘除,3 为其他(包括括号)
 31         switch(value){
 32           case '+':
 33           case '-':
 34             return 1;
 35           case '*':
 36           case '/':
 37             return 2;
 38           default:
 39             return 0;
 40         }
 41       }
 42       function getResult (fir, sec, cur) {   //进行基础运算 fir、sec为操作数,cur为操作符
 43         switch(cur){
 44           case '+':return parseFloat(fir)+parseFloat(sec);
 45           case '-':return parseFloat(fir)-parseFloat(sec);
 46           case '*':return parseFloat(fir)*parseFloat(sec);
 47           case '/':return parseFloat(fir)/parseFloat(sec);
 48         }
 49       }
 50       function prioraty(o1, o2){
 51         return getPrioraty(o1) <= getPrioraty(o2);
 52       }
 53       function operator1(exp){    //进行第一次运算,按运算优先级用后缀的形式储存运算表达式,去除括号
 54         var inputStack = [];
 55         var outputStack = [];
 56         var outputQueue = [];
 57 
 58         for(var i = 0, len = exp.length; i < len; i++){     //将表达式存入inputStack中
 59           var cur = exp[i];
 60           if(cur != ' ' ){
 61             inputStack.push(cur);
 62           }
 63         }
 64         while(inputStack.length > 0){       //如果有括号,将括号中的值存入outputStack
 65           var cur = inputStack.shift();
 66           if(isOperator(cur)){
 67             if(cur == '('){
 68               outputStack.push(cur);
 69             }else if(cur == ')'){
 70               var po = outputStack.pop();
 71               while(po != '(' && outputStack.length > 0){
 72                 outputQueue.push(po);
 73                 po = outputStack.pop();
 74               }
 75               if(po != '('){
 76                 alert("运算符不匹配,请重新输入");
 77                 throw "error: unmatched ()";
 78 
 79               }
 80             }else{
 81               while(prioraty(cur, outputStack[outputStack.length - 1]) && outputStack.length > 0){
 82                 outputQueue.push(outputStack.pop());
 83               }
 84               outputStack.push(cur);
 85             }
 86           }else{
 87             outputQueue.push(new Number(cur));
 88           }
 89         }
 90         if(outputStack.length > 0){     //按优先级进行排序
 91           if(outputStack[outputStack.length - 1] == ')' || outputStack[outputStack.length - 1] == '('){
 92             alert("运算符不匹配,请重新输入");
 93             throw "error: unmatched ()";
 94 
 95           }
 96           while(outputStack.length > 0){
 97             outputQueue.push(outputStack.pop());
 98           }
 99         }
100         return outputQueue;
101       }
102       function operator2(rpnQueue){     //将排好序的outputStack按后缀结构进行运算
103         var outputStack = [];
104         while(rpnQueue.length > 0){
105           var cur = rpnQueue.shift();
106 
107           if(!isOperator(cur)){
108             outputStack.push(cur);
109           }else{
110             if(outputStack.length < 2){
111               alert("运算符不匹配,请重新输入");
112               throw "unvalid stack length";
113             }
114             var sec = outputStack.pop();
115             var fir = outputStack.pop();
116 
117             outputStack.push(getResult(fir, sec, cur));
118           }
119         }
120 
121         if(outputStack.length != 1){
122           alert("运算符不匹配,请重新输入");
123           throw "unvalid expression";
124         }else{
125           console.log(outputStack[0]);
126           return outputStack[0];
127         }
128       }
129       this.result='='+operator2(operator1(this.input))
130 
131     },
132     clear(){
133       this.input='';
134       this.result='';
135     }
136   }
137 }
138 </script>
139 
140 <!-- Add "scoped" attribute to limit CSS to this component only -->
141 <style scoped>
142 .hello{
143   text-align: center;
144   margin: 100px;
145 }
146   .text{
147     text-align: left;
148   }
149   .question{
150     text-align: left;
151   }
152   .answer{
153     margin-top: 20px;
154     text-align: left;
155   }
156 
157 </style>

界面:

运算过程:

结果:

更多:

 

 对应结果图: