130242014022 蓝宏铮 第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 编译器模型示意图
本实验,实现的是词法分析和语法分析两个部分。
四、实验步骤:
INTEGER, PLUS, MINUS, MUL, DIV, LPAREN, RPAREN, EOF,VARIABLE,EQUALITY,INCREMENT,REDUCE = ('INTEGER', 'PLUS', 'MINUS', 'MUL', 'DIV', 'LPAREN', 'RPAREN', 'EOF','VARIABLE','EQUALITY','INCREMENT','REDUCE')
class Token(object): def __init__(self,type,value): self.type = type self.value = value # toString def __str__(self): return 'Token({type},{value})'.format( type=self.type, value = self.value ) class Lexer(object): # 词法分析器 # 给每个词打标记 # text为输入的表达式 def __init__(self, text): self.text = text # pos为当前位置 self.pos = 0 # current_char为当前字符 self.current_char = self.text[self.pos] # 取字符错误时调用的方法 def error(self): # raise 抛出异常 raise Exception('Invalid Char') #前进的方法,即取下一个字符 def advance(self): # 往下走,取值 self.pos += 1 if self.pos > len(self.text) - 1: self.current_char = None else: self.current_char = self.text[self.pos] def variable(self): # 变量处理 variable = '' while self.current_char is not None and self.current_char.isalpha(): variable = variable + self.current_char # 往下走,取值 self.advance() # 取值完毕后,将该变量存入字典中 if variable not in variables: variables[variable] = None return variable def integer(self): # 多位整数处理 result = '' while self.current_char is not None and self.current_char.isdigit(): result = result + self.current_char # 往下走,取值 self.advance() return int(result) # 处理输入时的非法空格 def deal_space(self): # 循环遍历,遇到空格则跳过,取下一个字符 while self.current_char is not None and self.current_char.isspace(): self.advance() def get_next_token(self): # 打标记:1)pos+1,2)返回Token(类型,数值) while self.current_char is not None: # 空格处理 if self.current_char.isspace(): self.deal_space() # 数字处理(判断是否为多位整数) if self.current_char.isdigit(): return Token(INTEGER, self.integer()) # 加号处理Plus if self.current_char == '+': # # 判断是自增还是加号 # if self.get_next_token() '+': # self.advance() # return Token(PLUS, '+') self.advance() return Token(PLUS, '+') # 减号处理Minus if self.current_char == '-': self.advance() return Token(MINUS, '-') # 左括号 if self.current_char == '(': self.advance() return Token(LPAREN,'(') # 右括号 if self.current_char == ')': self.advance() return Token(RPAREN,')') # 乘号 if self.current_char == '*': self.advance() return Token(MUL,'*') # 除号 if self.current_char == '/': self.advance() return Token(DIV,'/') # 若是判断出字符则进入变量获取的方法 if self.current_char.isalpha(): return Token(VARIABLE,self.variable()) # 等号 if self.current_char == '=': self.advance() return Token(EQUALITY,'EQUALITY') # # 自增 # if self.current_char == '++': # self.advance() # return Token(EQUALITY,'EQUALITY') # 其余均为非法字符 self.error() # 取到None字符 返回一个空的Token 表示循环结束 return Token(EOF, None) class Interpreter(object): # 句法分析 # 语法树 # 语法树中的一个参数为词法分析器Lexer def __init__(self, lexer): self.lexer = lexer self.current_token = self.lexer.get_next_token() def error(self): raise Exception('Invalid Syntax') # 当当前Token取值完毕 # 删除当前的Token,取下一个Token的值 def eat(self, token_type): # 跳过与当前相同的Token,取下一个Token if self.current_token.type == token_type: self.current_token = self.lexer.get_next_token() else: # 若在删除的过程中出错,会引起整体的错误,故抛错 self.error() # 工厂方法 def factor(self): token = self.current_token # 判断当前要删除的Token类型 if token.type == INTEGER: self.eat(INTEGER) return token.value # 将类型为Variable的变量返回 if token.type == VARIABLE: self.eat(VARIABLE) return variables[token.value] # 左括号 elif token.type == LPAREN: self.eat(LPAREN) result = self.expr() self.eat(RPAREN) return result def term(self): result = self.factor() while self.current_token.type in (MUL, DIV): token = self.current_token if token.type == MUL: self.eat(MUL) result = result * self.factor() if token.type == DIV: self.eat(DIV) result = result / self.factor() return result def expr(self): result = self.term() while self.current_token.type in (PLUS, MINUS): token = self.current_token if token.type == PLUS: self.eat(PLUS) result = result + self.term() if token.type == MINUS: self.eat(MINUS) result = result - self.term() return result def assignment(self): if self.current_token.type == VARIABLE: var = self.current_token.value self.eat(VARIABLE) if self.current_token.type == EQUALITY: self.eat(EQUALITY) variables[var] = self.expr() return vardef printResult(text): lexer = Lexer(text) variableKey = Interpreter(lexer).assignment() print(variableKey,"=",variables[variableKey]) def main(): while True: try: text = input('calc_> ') except EOFError: break if not text: continue # try: printResult(text) # except Exception: # print('Invalid Syntax') if __name__ == '__main__': main()
转载于:https://www.cnblogs.com/RealKing/p/7780189.html
130242014022 蓝宏铮 第2次实验相关推荐
- 20145231熊梓宏 《网络对抗》 实验四 恶意代码分析
20145231熊梓宏 <网络对抗> 实验四 恶意代码分析 基础问题回答 1.如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操 ...
- c语言实验报告函数和宏定义,第六章 实验报告(函数与宏定义)
##C程序设计实验报告 ###一.实验项目: 1.编写由三角形三边求面积的函数 2.编写求N阶乘的函数 3.求两个整数的最大公约数 4.打印输出三角形 5.求500以内的所有亲密数对 ##姓名:戴求 ...
- 计算机组成原理秒表设计实验,计算机组成原理实验2.4计数器赖晓铮剖析.ppt
计算机组成原理实验2.4计数器赖晓铮剖析 计算机组成原理 实验系列 一.总线与寄存器 二.进位加法器 三.比较器(仲裁器) 四.计数器 五.运算器 六.存储器 七.时序发生器 八.微程序控制器 九.硬 ...
- 计算机组成原理字发生器,计算机组成原理实验2.7时序发生器赖晓铮剖析.ppt
计算机组成原理实验2.7时序发生器赖晓铮剖析 计算机组成原理 实验系列 一.总线与寄存器 二.进位加法器 三.比较器(仲裁器) 四.计数器 五.运算器 六.存储器 七.时序发生器 八.微程序控制器 九 ...
- 子程序调用与宏定义的异同_微机原理 宏指令及子程序设计实验:宏指令和子程序的区别...
西安邮电学院 微机原理实验报告 题 目: 宏指令及子程序设计实验 院系名称: 班 级: 学生姓名: 学号(8位): 指导教师: 2.5 宏令及子程序设计实验 2.5.1 实验目的 1.熟悉宏指令.宏定 ...
- JoVE微生物组专刊征稿,写方法拍视频教程发SCI(宏基因组公众号专属福利)
JoVE 视频实验杂志 官网:https://www.jove.com/ 包括上万个实验和分析方法视频,还有几十个领域的数百个专业视频教程资源. 这个杂志被SCI收录了吗?必须的.杂志在Web of ...
- python面向对象实验报告_20192310 实验三《Python程序设计》实验报告
学号 2020-2021-1 <数据结构与面向对象程序设计>实验三报告 课程:<程序设计与数据结构> 班级: 1923 姓名: 严嘉钰 学号:20192310 实验教师:王志强 ...
- 利用DOCX文档远程模板注入执行宏代码
利用DOCX文档远程模板注入执行宏代码 简介 本地文件中在没有宏代码的情况下,攻击者可以尝试执行远程文件中宏代码.其中来自APT28的最新样本将此技术展现的淋漓尽致.该样本是docx文件,文件内没有任 ...
- 数电实验一-初识Multisim和Basys3
特别说明:该系列内容均是本人实验记录,无盗取侵权之嫌,仅供参考,请多动手实践! 一.实验目的 详见报告 二.实验仪器设备 详见报告 三.实验设计过程 使用Multisim为Basys3板卡创建一个PL ...
最新文章
- catia三维轴承_浅谈基于CATIA二次开发的单排四点接触球轴承三维设计论文
- 解决CSV文件中长数字以科学记数格式保存问题
- cocos2d-x jsbinding 在线更新策略设计
- 上如何刻字_校园石阶上被人刻了1700多个字?!这次网友却说好
- 基于docker安装tensorflow
- PAT乙级题目答案汇总PAT (Basic Level) Practice (中文)
- 第22天学习Java的笔记-继承
- 针对C++和Delphi的LiveBindings一瞥
- json.stringfy()和json.parse()
- linux服务器系统_利用Zabbix监控系统监测Linux服务器系统时间是否准确完美实现...
- mysql优化之 EXPLAIN(一)
- Vue之webpack之vue
- Zookeeper C API 指南三(回调函数)
- 老毛子Padavan网段LAN修改
- win7如何添加终端服务器,Win7怎么添加windows超级终端?
- 【目标检测适用】Pascal Voc(07+12)联合训练并在07上测试
- 微信公众平台的设计与开发之道
- 输入法半角和全角的快捷转换_搜狗输入法经常用到的冷门小技巧,复制文章空白行取消方法...
- Canvas3——绘制渐变图形与绘制变形图形
- com.googlecode.genericdao