130242014023+李甘露美+第2次实验

Posted lglmlg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了130242014023+李甘露美+第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  编译器模型示意图

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

四、实验步骤:

  1 #预先定义类型(整型,加,减,乘,除,左右括号,还有结束标记
  2 INTEGER,PLUS,MINUS,MUL,DIV,LPAREN,RPAREN,EOF=(
  3 \'INTEGER\',\'PLUS\',\'MINUS\',\'MUL\',\'DIV\',\'LPAREN\',\'RPAREN\',\'EOF\')
  4 
  5 #给字符打标记(标出它的类型与值)
  6 class Token(object):
  7     def  __init__(self,type,value):
  8         self.type=type
  9         self.value=value
 10     def __str__(self):
 11         return \'Token({type},{value})\'.format(
 12             type=self.type,
 13             value=repr(self.value)
 14             )
 15 
 16 #词法分析器(让输入的字符一个一个地打标记,即“认出”这些词)
 17 class Lexer(object):
 18 
 19 #给每个词打标记
 20     def __init__(self,text):
 21         self.text=text
 22         self.pos=0
 23         self.current_char=self.text[self.pos]
 24 
 25      #错误的处理
 26     def error(self):
 27         raise Exception(\'Invalid Char\')
 28      
 29      #往下走
 30     def advance(self):
 31         self.pos+=1
 32         if self.pos>len(self.text)-1:
 33             self.current_char=None
 34         else:
 35             self.current_char=self.text[self.pos]
 36     
 37     #处理多位整数
 38     def integer(self):
 39         
 40         result=\'\'
 41         while self.current_char is not None and self.current_char.isdigit():
 42             result=result+self.current_char
 43             self.advance()
 44         return int(result)
 45 
 46     #对空格的处理
 47     def deal_space(self):
 48         while self.current_char is not None and self.current_char.isspace():
 49             self.advance()
 50 
 51      #处理下一个词
 52     def get_next_token(self):
 53         #打标记:1)pos+1,2)返回Token(类型,数值)
 54         while self.current_char is not None:
 55             #如果处理的是空格
 56             if self.current_char.isspace():
 57                 self.deal_space()
 58             #如果处理的是数字
 59             if self.current_char.isdigit():
 60                 return Token(INTEGER,self.integer())
 61             #如果处理的是加号
 62             if self.current_char==\'+\':
 63                 self.advance()
 64                 return Token(PLUS,\'+\')
 65             #如果处理的减号
 66             if self.current_char==\'-\':
 67                 self.advance()
 68                 return Token(MINUS,\'-\')
 69             #如果处理的是乘号
 70             if self.current_char==\'*\':
 71                 self.advance()
 72                 return Token(MUL,\'*\')
 73             #如果处理的是除号
 74             if self.current_char==\'/\':
 75                 self.advance()
 76                 return Token(DIV,\'/\')
 77             #如果处理的是左括号
 78             if self.current_char==\'(\':
 79                 self.advance()
 80                 return Token(LPAREN,\'(\')
 81             #如果处理的是右括号
 82             if self.current_char==\')\':
 83                 self.advance()
 84                 return Token(RPAREN,\')\')
 85             #如果都不是
 86             self.error()
 87         return Token(EOF,None)
 88 
 89 #句法分析
 90 class Interpreter(object):
 91 
 92     def __init__(self,lexer):
 93         self.lexer=lexer
 94         self.current_token=self.lexer.get_next_token()
 95 
 96     def error(self):
 97         raise Exception(\'Invalid Syntax\')
 98     #判断这个位置的字符是否符合类型的要求,符合则去找下一个字符
 99     def eat(self,token_type):
100         if self.current_token.type==token_type:
101             self.current_token=self.lexer.get_next_token()
102         else:
103             self.error()
104         #下面处理计算,根据括号最优先,先乘除后加减,factor比term优先,term比expr优先
105      #这里处理的是factor(即算式中的用于进行乘除运算的元素,如整数和括号表达式)
106     def factor(self):
107         token=self.current_token
108         #如果这个factor是整数
109         if token.type==INTEGER:
110             self.eat(INTEGER)
111             return token.value
112         #如果这个factor是括号表达式
113         elif token.type==LPAREN:
114             self.eat(LPAREN)
115             result=self.expr()
116             self.eat(RPAREN)
117             return result
118     #这里处理的是term(即应该优先运算的乘除操作)
119     def term(self):
120         result=self.factor()
121         while self.current_token.type in (MUL, DIV):
122             token=self.current_token
123             #进行乘运算
124             if token.type==MUL:
125                 self.eat(MUL)
126                 result=result*self.factor()
127             #进行除运算
128             if token.type==DIV:
129                 self.eat(DIV)
130                 result=result/self.factor()
131         return result
132     #这里处理的是expr(即处理加减操作)
133     def expr(self):
134         result=self.term()
135         while self.current_token.type in (PLUS, MINUS):
136             token=self.current_token
137             if token.type==PLUS:
138                 self.eat(PLUS)
139                 result=result+self.term()
140             if token.type==MINUS:
141                 self.eat(MINUS)
142                 result=result-self.term()
143         return result
144             
145 
146 def main():
147     #先接受输入的算式
148     while True:
149         try:
150             text=input(\'calc_> \')
151         except EOFError:
152             break
153         if not text:
154             continue
155         #词法分析
156         lexer=Lexer(text)
157         #句法分析
158         interpreter = Interpreter(lexer)
159         #根据句法分析进行计算
160         result=interpreter.expr()
161         print(result)
162 
163 if  __name__==\'__main__\':
164     main()

在该代码的执行过程中涉及到的结构图如下:

五、实验总结

       首先要感谢这次的实验,有幸能接触到Python语言,算是一种新的了解和尝试吧。Python是一种比较通俗易懂,语法也比较特别的脚本语言,比较适合这次的管道——过滤器风格的层层递进的结构,这次的例子也是浅显易懂的,“麻雀虽小,五脏俱全”,步骤和顺序是很清晰的:接收字符集,对每个字符进行词法分析,判断整个算式的语法,一层一层的计算,返回最后的结果。

       通过这次的实验,我对管道——过滤器风格有了更深刻更具体的了解。

 

以上是关于130242014023+李甘露美+第2次实验的主要内容,如果未能解决你的问题,请参考以下文章

130242014023-李甘露美-实验一

“电商系统某功能模块”需求分析与设计实验课小结

130242014032 ++“电商系统搜索功能模块”需求分析与设计实验课小结

130242014023“电商系统搜索模块”需求分析与设计实验课小结

操作系统第2次实验报告:创建进程

操作系统第4次实验报告:文件系统